From 6ad6de2ca085971b5dc07f709e4f94d6b6d8daa4 Mon Sep 17 00:00:00 2001 From: Brett Heap Date: Tue, 13 Oct 2026 18:25:56 +0000 Subject: [PATCH 1/5] Drive lane-start's row stamp at three checkout lengths, so #180's cut is a measured design and not a run root's accident The stamp's tail (Amendment 11(c)'s dir and window) is what cut_to_line takes first under ratified decision O1's cap; its length is the checkout path's, not the run root's. A real lane-start, started twice --no-launch under a $HOME at least as long as tests/run.sh's, with the checkout at a short fixed path (tail intact), at 100 characters (window lost, #180's shape) and at 160 (the path dropped whole, never truncated); the head, the 240 cap and the log's full facts are asserted in all three. Co-Authored-By: Claude Opus 5.5 --- tests/test_lane_start_row_stamp.py | 266 +++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 tests/test_lane_start_row_stamp.py diff --git a/tests/test_lane_start_row_stamp.py b/tests/test_lane_start_row_stamp.py new file mode 100644 index 00000000..74af5d87 --- /dev/null +++ b/tests/test_lane_start_row_stamp.py @@ -0,0 +1,266 @@ +# SPDX-License-Identifier: Apache-2.0 +"""`lane-start`'s row stamp under a long checkout path (opensoft/openRepoTools#180). + +THE STAMP'S TAIL IS THE PART A CUT TAKES, AND THAT IS THE DESIGN. Amendment +11(c) puts the lane's `dir` and `window` in the tail of the stamp a resume +writes; Amendment 13(a) makes the cell ONE line under ratified decision O1's +240 characters; and `lane-start` orders that line so `cut_to_line` takes `dir` +and `window` first, because both are this same act's sub-fields in the lane's +own log and columns of Amendment 11's listing — a cut loses what a reader can +look up, never the head `row_stamp_is_unknown` reads. + +So the tail's length is the CHECKOUT PATH's length, and #180 was a shell-suite +case that put its checkout under `$HOME/projects` inside the run root: green +under plain pytest's short `/tmp`, red under `tests/run.sh`'s per-run root +(`TMPDIR` about 71 characters, so a `$HOME` about 91). These cases drive a real +`lane-start` twice, `--no-launch`, in that shape — a `$HOME` at least as long +as `run.sh`'s — with the checkout at three EXACT lengths, so the answer does not +depend on where pytest itself was run: + + * a short, fixed checkout keeps the whole tail, however long `$HOME` is — + which is what `tests/test_lane_helpers.sh`'s clause (c) TAIL case now uses; + * a checkout as long as `run.sh` gave that case loses the `window` (#180); + * a longer one loses the path WHOLE, never a truncated path that reads as + a real one; + +and in every one the head is intact, the line is inside the cap, and the +lane's log carries both facts in full. +""" + +from __future__ import annotations + +import os +import shutil +import subprocess +import tempfile +from pathlib import Path + +import pytest + +from conftest import REPO, WINDOWS_SKIP, rmtree + +pytestmark = [pytest.mark.skipif(shutil.which("bash") is None, + reason="lane-start is a bash script"), + pytest.mark.skipif(shutil.which("git") is None, + reason="the register is a git repository"), + WINDOWS_SKIP] + +LANE = "repoZ-1" +WINDOW = "testsess:0 @1" + +#: `tests/run.sh`'s `$HOME` for the shell suite, as #180 measured it: a run +#: root `TMPDIR` of about 71 characters, the suite's `mktemp -d` beneath it +#: (`/tmp.XXXXXXXXXX`, 15) and `/home` (5). +RUN_SH_HOME = 91 + +SCRUBBED_PREFIXES = ("LANES_", "LANE_START_", "CLAUDE_", "OPENREPOTOOLS_", + "FAKE_", "GIT_", "TMUX") +SCRUBBED = {"AGENT_PROTOCOL_ROOT", "PROJECTS_ROOT", "XDG_CONFIG_HOME", + "XDG_CACHE_HOME"} + +#: The lane suite's fake tmux, cut down to one window, `testsess:0 @1`, whose +#: name is `$FAKE_TMUX_WINDOW_NAME` — `claude` on a first start and the lane +#: on the second, as a window lane-start renamed would answer. +FAKE_TMUX = r"""#!/usr/bin/env bash +case "${1-}" in + display-message) + shift + t=""; f="" + while [ $# -gt 0 ]; do + case "$1" in + -p) shift ;; + -t) t="${2-}"; shift 2 ;; + *) f="$1"; shift ;; + esac + done + if [ -n "$t" ]; then + case "$t" in + testsess:0|testsess:@1|@1) : ;; + *) exit 1 ;; + esac + case "$f" in + '#{window_id}') echo '@1' ;; + '#{window_name}') echo "${FAKE_TMUX_WINDOW_NAME:-claude}" ;; + '#{session_name}') echo 'testsess' ;; + '#{pane_current_command}') echo 'claude' ;; + *) echo ;; + esac + exit 0 + fi + case "$f" in + '#{session_name}:#{window_id}') echo 'testsess:@1' ;; + '#{session_name}:#{window_index}') echo 'testsess:0' ;; + '#S:#I') echo 'testsess:0' ;; + '#{window_id}') echo '@1' ;; + '#W'|'#{window_name}') echo "${FAKE_TMUX_WINDOW_NAME:-claude}" ;; + *) echo ;; + esac ;; + rename-window) + printf 'rename-window %s\n' "${2-}" >> "$FAKE_TMUX_LOG" ;; + *) : ;; +esac +""" + +FAKE_GH = """#!/usr/bin/env bash +printf 'FAKE gh REFUSED: %s -- this suite reaches no GitHub surface\\n' "$*" >&2 +exit 90 +""" + + +def _write(path: Path, text: str) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(text, encoding="utf-8") + path.chmod(0o755) + + +class Sandbox: + """One workstation, one register, and a `$HOME` at least `run.sh`'s length.""" + + def __init__(self, tmp_path: Path) -> None: + pad = max(0, RUN_SH_HOME - len(str(tmp_path / "r" / "home"))) + self.root = tmp_path / ("r" * (pad + 1)) + self.home = self.root / "home" + assert len(str(self.home)) >= RUN_SH_HOME + self.bin = self.root / "bin" + fakebin = self.root / "fakebin" + origin = self.root / "origin.git" + self.wip = self.home / "projects" / "wip" + for d in (self.home / "projects", self.root / "tmp", fakebin, self.bin, + self.home / ".claude" / "sessions", self.home / ".agents"): + d.mkdir(parents=True, exist_ok=True) + + env = {k: v for k, v in os.environ.items() + if k not in SCRUBBED and not k.startswith(SCRUBBED_PREFIXES)} + env.update({ + "HOME": str(self.home), + "TMPDIR": str(self.root / "tmp"), + "XDG_CONFIG_HOME": str(self.home / ".config"), + "XDG_CACHE_HOME": str(self.home / ".cache"), + "PATH": f"{fakebin}{os.pathsep}{self.bin}{os.pathsep}{env.get('PATH', '')}", + "TMUX": f"{self.root}/fake-tmux-socket,0,0", + "AGENT_PROTOCOL_ROOT": str(self.home / ".agents"), + "OPENREPOTOOLS_BIN_DIR": str(self.bin), + "CLAUDE_CONFIG_DIR": str(self.home / ".claude"), + "LANES_WORKSTATION": "Eagle", + "LANES_NO_GITHUB": "1", + "LANES_INDEX": "off", + "FAKE_TMUX_LOG": str(self.root / "tmux.log"), + "GIT_AUTHOR_NAME": "lane-start row stamp tests", + "GIT_AUTHOR_EMAIL": "test@example.invalid", + "GIT_COMMITTER_NAME": "lane-start row stamp tests", + "GIT_COMMITTER_EMAIL": "test@example.invalid", + }) + self.env = env + + for name in ("lane-start", "lanes-edit.sh", "repos.tsv"): + shutil.copy2(REPO / name, self.bin / name) + (self.bin / name).chmod(0o755) + _write(fakebin / "tmux", FAKE_TMUX) + _write(fakebin / "gh", FAKE_GH) + _write(fakebin / "claude", "#!/usr/bin/env bash\nexit 0\n") + + self.git("init", "-q", "--bare", "-b", "main", str(origin)) + self.git("clone", "-q", str(origin), str(self.wip)) + (self.wip / "lanes").mkdir() + (self.wip / "handoffs").mkdir() + (self.wip / "handoffs" / "README.md").write_text( + "# handoffs\n", encoding="utf-8") + (self.wip / "lanes" / "LANES.md").write_text( + "# LANES.md -- the sandbox register\n\n" + "| lane | session id | workstation / env / user | started (UTC) " + "| objects owned | handoff path | state |\n" + "|---|---|---|---|---|---|---|\n", encoding="utf-8") + self.git("-C", str(self.wip), "add", "--", "lanes/LANES.md", + "handoffs/README.md") + self.git("-C", str(self.wip), "commit", "-q", "-m", "seed") + self.git("-C", str(self.wip), "push", "-q", "origin", "main") + (self.home / ".agents" / "workspace.yaml").write_text( + f"repository: {origin}\npath: {self.wip}\n", encoding="utf-8") + + def git(self, *args: str) -> str: + return subprocess.run(["git", *args], env=self.env, check=True, + capture_output=True, text=True).stdout + + def checkout(self, path: Path) -> None: + self.git("init", "-q", "-b", "main", str(path)) + self.git("-C", str(path), "remote", "add", "origin", + "https://github.com/opensoft/repoZ.git") + + def start(self, *args: str, window_name: str) -> subprocess.CompletedProcess: + return subprocess.run([str(self.bin / "lane-start"), "repoZ", "1", + "--no-launch", *args], + env=dict(self.env, FAKE_TMUX_WINDOW_NAME=window_name), + capture_output=True, text=True, timeout=120, + check=False) + + def stamp_line(self) -> str: + """The `` of the row's ` · · ` cell.""" + rows = [r for r in (self.wip / "lanes" / "LANES.md") + .read_text(encoding="utf-8").splitlines() + if r.startswith(f"| `{LANE}`")] + assert len(rows) == 1, rows + cell = rows[0].rstrip().rstrip("|").rstrip().rsplit(" | ", 1)[1] + state, _utc, line = cell.split(" · ", 2) + assert state == "LIVE", cell + return line + + def last_log_line(self) -> str: + return (self.wip / "lanes" / "log" / f"{LANE}.md").read_text( + encoding="utf-8").splitlines()[-1] + + +@pytest.fixture +def short_root(): + """A short, FIXED-length directory outside the run root: `/tmp/` and + `mkdtemp`'s name, whatever `TMPDIR` or pytest's basetemp say.""" + root = Path(tempfile.mkdtemp(prefix="ort-tail.", dir="/tmp")) + try: + yield root + finally: + rmtree(root) + + +def _checkout_of_length(root: Path, length: int | None) -> Path: + """`/repoZ`, padded between the two to exactly `length` characters.""" + if length is None: + return root / "repoZ" + pad = length - len(str(root)) - len("/repoZ") - 1 + assert pad > 0, (root, length) + path = root / ("p" * pad) / "repoZ" + assert len(str(path)) == length + return path + + +@pytest.mark.parametrize("length, keeps", [ + pytest.param(None, "dir and window", id="short-fixed-checkout"), + pytest.param(100, "dir", id="as-long-as-run-sh-gave-180"), + pytest.param(160, "nothing", id="longer-still"), +]) +def test_the_stamp_tail_is_cut_by_the_checkout_path_and_never_the_head( + tmp_path, short_root, length, keeps): + box = Sandbox(tmp_path) + lane_dir = _checkout_of_length(short_root, length) + box.checkout(lane_dir) + + first = box.start("--dir", str(lane_dir), window_name="claude") + assert first.returncode == 0, first.stderr + # THE SECOND START STAMPS (Amendment 6(c)), and it finds the checkout in + # the lane's own log, exactly as the shell suite's case does. + second = box.start(window_name=LANE) + assert second.returncode == 0, second.stderr + line = box.stamp_line() + + assert len(line) <= 240, line + assert (f"(lane {LANE}) — lane-start on Eagle: window renamed, " + f"no launch; dir ") in line, line + if keeps == "dir and window": + assert line.endswith(f"; dir {lane_dir}; window {WINDOW}"), line + elif keeps == "dir": + assert f"; dir {lane_dir};" in line and line.endswith(" ..."), line + assert WINDOW not in line, line + else: + assert line.endswith("no launch; dir ..."), line + assert str(short_root) not in line, line + + # NOTHING IS LOST: what the cut took is this act's own log line. + assert f"; dir {lane_dir}; window {WINDOW}; " in box.last_log_line() From 085a2341a6f052df170e365088b1c4e5292c229a Mon Sep 17 00:00:00 2001 From: Brett Heap Date: Tue, 13 Oct 2026 18:25:56 +0000 Subject: [PATCH 2/5] Read the clause (c) TAIL case on a checkout at a short fixed path, so its answer no longer depends on the run root (#180) Under $HOME/projects the stamp's line outgrew the 230 the cut keeps once the run root was tests/run.sh's, and the window ref was cut: red locally, green under CI's plain pytest. The tail is now read on a lane whose checkout is /tmp/ort-a11t.XXXXXX/repoA11t (29 characters anywhere); repoA11b-1's second start keeps its exit, no-launch and head assertions, and cleanup removes the one fixture outside $SANDBOX. Co-Authored-By: Claude Opus 5.5 --- tests/test_lane_helpers.sh | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/tests/test_lane_helpers.sh b/tests/test_lane_helpers.sh index 53e5d3c1..0910a22c 100755 --- a/tests/test_lane_helpers.sh +++ b/tests/test_lane_helpers.sh @@ -96,6 +96,9 @@ cleanup() { [ -n "${RACE_PARENT:-}" ] && kill "$RACE_PARENT" 2>/dev/null [ -n "${RACE_CHILD:-}" ] && kill "$RACE_CHILD" 2>/dev/null [ -n "${GD_DUP:-}" ] && kill "$GD_DUP" 2>/dev/null + # #180's short, fixed checkout root for the clause (c) TAIL case: the one + # fixture this suite makes outside `$SANDBOX`. + [ -n "${A11T_ROOT:-}" ] && [ -d "$A11T_ROOT" ] && rm -rf -- "$A11T_ROOT" [ -n "${SANDBOX:-}" ] && [ -d "$SANDBOX" ] && rm -rf -- "$SANDBOX" return 0 } @@ -5348,12 +5351,35 @@ has "…keeping the home and estate the line already carried" "$A11B_LOG" "home FAKE_TMUX_WINDOW="a11start:@42" FAKE_TMUX_WINDOW_INDEX=3 FAKE_TMUX_WINDOW_NAME=repoA11b-1 \ CLAUDE_PROFILE_NAME=team-05a run "$START" repoA11b 1 --no-launch is "lane-start exits 0 on a second start of the same lane" "$rc" 0 -has "the row's stamp states clause (c)'s two facts for a person, in its TAIL" \ - "$(grep '^| `repoA11b-1`' "$LANES")" "dir $HOME/projects/repoA11b; window a11start:3 @42" -has "…and that tail still says what actually happened, so --no-launch never claims a launch" \ +has "…and its stamp says what actually happened, so --no-launch never claims a launch" \ "$(grep '^| `repoA11b-1`' "$LANES")" ", no launch" has "…while its HEAD is Amendment 8(d)'s and is untouched" \ "$(grep '^| `repoA11b-1`' "$LANES")" "(lane repoA11b-1) — lane-start on Eagle: window renamed, no launch; dir " +# THE TAIL IS READ ON A CHECKOUT AT A SHORT, FIXED PATH (opensoft/openRepoTools +# #180). The stamp is ONE line under ratified decision O1's cap (Amendment +# 13(a)), and `cut_to_line` takes `dir` and `window` first by design — both are +# this same act's log sub-fields, asserted in full above — so the tail fits only +# when the CHECKOUT PATH does. Read on `$HOME/projects/repoA11b`, this case's +# answer was the run root's length: green under plain pytest's `/tmp`, red under +# `tests/run.sh`'s per-run root, at the edge on macOS. `/tmp/ort-a11t.XXXXXX/ +# repoA11t` is 29 characters wherever the suite runs, which puts the line at +# about 170, well inside the 230 the cut keeps. It is the one fixture outside +# `$SANDBOX`, and `cleanup` removes it. `tests/test_lane_start_row_stamp.py` +# drives the same stamp at three checkout lengths, the two that are cut included. +A11T_ROOT="$(mktemp -d /tmp/ort-a11t.XXXXXX 2>/dev/null || :)" +is "the TAIL case has its short, fixed checkout root under /tmp" \ + "$( [ -n "$A11T_ROOT" ] && [ -d "$A11T_ROOT" ] && echo yes || echo no )" "yes" +A11T_DIR="${A11T_ROOT:-$SANDBOX/a11t-no-short-root}/repoA11t" +git init -q -b main "$A11T_DIR" +git -C "$A11T_DIR" remote add origin "https://github.com/opensoft/repoA11t.git" +FAKE_TMUX_WINDOW="a11tail:@43" FAKE_TMUX_WINDOW_INDEX=5 FAKE_TMUX_WINDOW_NAME=claude \ + run "$START" --dir "$A11T_DIR" repoA11t 1 --no-launch +is "lane-start exits 0 for a lane whose checkout is at that short path" "$rc" 0 +FAKE_TMUX_WINDOW="a11tail:@43" FAKE_TMUX_WINDOW_INDEX=5 FAKE_TMUX_WINDOW_NAME=repoA11t-1 \ + run "$START" repoA11t 1 --no-launch +is "…and on its second start, which reads the checkout back from the lane's log" "$rc" 0 +has "the row's stamp states clause (c)'s two facts for a person, in its TAIL" \ + "$(grep '^| `repoA11t-1`' "$LANES")" "dir $A11T_DIR; window a11tail:5 @43" # NO PROFILE IS NO SUB-FIELD, never a guessed one (Amendment 7(i)). mkdir -p "$HOME/projects/repoA11c" git init -q -b main "$HOME/projects/repoA11c" From 929c31e05df0a7433cf14ab458d1e536fbbc2c2b Mon Sep 17 00:00:00 2001 From: Brett Heap Date: Tue, 13 Oct 2026 20:42:18 +0000 Subject: [PATCH 3/5] Seed the row-stamp test's workspace from a data table, and name its cases by what the cut takes SonarCloud counted the register seed as a 14-line copy of test_lane_start_claude_current.py's (4.7% new-code duplication against a 3% gate); it is now one table written in a loop, the register text byte-identical. The 100-character case was labelled #180's shape, but #180's row read `... no launch; dir ...`, the path dropped whole: the ids are now window-cut-dir-kept and path-dropped-whole-as-in-180, and the docstring says which is which. Co-Authored-By: Claude Opus 5.5 --- tests/test_lane_start_row_stamp.py | 42 +++++++++++++++++------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/tests/test_lane_start_row_stamp.py b/tests/test_lane_start_row_stamp.py index 74af5d87..cbb48aed 100644 --- a/tests/test_lane_start_row_stamp.py +++ b/tests/test_lane_start_row_stamp.py @@ -19,9 +19,11 @@ * a short, fixed checkout keeps the whole tail, however long `$HOME` is — which is what `tests/test_lane_helpers.sh`'s clause (c) TAIL case now uses; - * a checkout as long as `run.sh` gave that case loses the `window` (#180); - * a longer one loses the path WHOLE, never a truncated path that reads as - a real one; + * a checkout whose path still fits loses only the `window` ref; + * a longer one loses the path WHOLE, never a truncated path that reads as a + real one. That is what #180's case read under `run.sh`'s root: + `… window renamed, no launch; dir ...`, its cut landing on the `;` that + follows the path, so the path went with it; and in every one the head is intact, the line is inside the cap, and the lane's log carries both facts in full. @@ -101,6 +103,17 @@ esac """ +#: The workspace repository's first commit: a register with its header and no +#: rows, and the handoffs directory a row's handoff path points into. +WORKSPACE_SEED = { + "lanes/LANES.md": "\n".join(( + "# LANES.md -- the sandbox register", "", + "| lane | session id | workstation / env / user | started (UTC) | " + "objects owned | handoff path | state |", + "|---|---|---|---|---|---|---|", "")), + "handoffs/README.md": "# handoffs\n", +} + FAKE_GH = """#!/usr/bin/env bash printf 'FAKE gh REFUSED: %s -- this suite reaches no GitHub surface\\n' "$*" >&2 exit 90 @@ -161,19 +174,12 @@ def __init__(self, tmp_path: Path) -> None: self.git("init", "-q", "--bare", "-b", "main", str(origin)) self.git("clone", "-q", str(origin), str(self.wip)) - (self.wip / "lanes").mkdir() - (self.wip / "handoffs").mkdir() - (self.wip / "handoffs" / "README.md").write_text( - "# handoffs\n", encoding="utf-8") - (self.wip / "lanes" / "LANES.md").write_text( - "# LANES.md -- the sandbox register\n\n" - "| lane | session id | workstation / env / user | started (UTC) " - "| objects owned | handoff path | state |\n" - "|---|---|---|---|---|---|---|\n", encoding="utf-8") - self.git("-C", str(self.wip), "add", "--", "lanes/LANES.md", - "handoffs/README.md") - self.git("-C", str(self.wip), "commit", "-q", "-m", "seed") - self.git("-C", str(self.wip), "push", "-q", "origin", "main") + for rel, text in WORKSPACE_SEED.items(): + (self.wip / rel).parent.mkdir(parents=True, exist_ok=True) + (self.wip / rel).write_text(text, encoding="utf-8") + for step in (("add", "--", *WORKSPACE_SEED), ("commit", "-q", "-m", "seed"), + ("push", "-q", "origin", "main")): + self.git("-C", str(self.wip), *step) (self.home / ".agents" / "workspace.yaml").write_text( f"repository: {origin}\npath: {self.wip}\n", encoding="utf-8") @@ -233,8 +239,8 @@ def _checkout_of_length(root: Path, length: int | None) -> Path: @pytest.mark.parametrize("length, keeps", [ pytest.param(None, "dir and window", id="short-fixed-checkout"), - pytest.param(100, "dir", id="as-long-as-run-sh-gave-180"), - pytest.param(160, "nothing", id="longer-still"), + pytest.param(100, "dir", id="window-cut-dir-kept"), + pytest.param(160, "nothing", id="path-dropped-whole-as-in-180"), ]) def test_the_stamp_tail_is_cut_by_the_checkout_path_and_never_the_head( tmp_path, short_root, length, keeps): From c19150fe705f5f42e1a85a3e7881bca3cd44a383 Mon Sep 17 00:00:00 2001 From: Brett Heap Date: Tue, 13 Oct 2026 20:42:18 +0000 Subject: [PATCH 4/5] Set A11T_ROOT before the suite's traps, and keep the TAIL case's checkout in the sandbox wherever its TMPDIR is short An inherited A11T_ROOT would have been removed by cleanup had the suite died before the clause (c) case. The checkout now goes under the sandbox's own $TMPDIR when that is at most 40 characters, and under /tmp only when it is not, with an assertion that it is at most 65 characters, so the line stays under about 210 wherever the root is. Co-Authored-By: Claude Opus 5.5 --- tests/test_lane_helpers.sh | 39 ++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/tests/test_lane_helpers.sh b/tests/test_lane_helpers.sh index 0910a22c..4c353785 100755 --- a/tests/test_lane_helpers.sh +++ b/tests/test_lane_helpers.sh @@ -63,6 +63,8 @@ done [ -f "$SRC_DIR/repos.tsv" ] || { echo "missing: $SRC_DIR/repos.tsv" >&2; exit 1; } SANDBOX="$(mktemp -d)" +# Set before the traps below, so `cleanup` never reads an inherited value. +A11T_ROOT="" REAL_HOME="$HOME" # THE GUARDS AT THE FOOT OF THIS FILE, re-pointed (Amendment 9, act 3 @@ -96,8 +98,8 @@ cleanup() { [ -n "${RACE_PARENT:-}" ] && kill "$RACE_PARENT" 2>/dev/null [ -n "${RACE_CHILD:-}" ] && kill "$RACE_CHILD" 2>/dev/null [ -n "${GD_DUP:-}" ] && kill "$GD_DUP" 2>/dev/null - # #180's short, fixed checkout root for the clause (c) TAIL case: the one - # fixture this suite makes outside `$SANDBOX`. + # #180's short checkout root for the clause (c) TAIL case, which is outside + # `$SANDBOX` wherever the run root is long. [ -n "${A11T_ROOT:-}" ] && [ -d "$A11T_ROOT" ] && rm -rf -- "$A11T_ROOT" [ -n "${SANDBOX:-}" ] && [ -d "$SANDBOX" ] && rm -rf -- "$SANDBOX" return 0 @@ -5355,21 +5357,26 @@ has "…and its stamp says what actually happened, so --no-launch never claims "$(grep '^| `repoA11b-1`' "$LANES")" ", no launch" has "…while its HEAD is Amendment 8(d)'s and is untouched" \ "$(grep '^| `repoA11b-1`' "$LANES")" "(lane repoA11b-1) — lane-start on Eagle: window renamed, no launch; dir " -# THE TAIL IS READ ON A CHECKOUT AT A SHORT, FIXED PATH (opensoft/openRepoTools -# #180). The stamp is ONE line under ratified decision O1's cap (Amendment -# 13(a)), and `cut_to_line` takes `dir` and `window` first by design — both are -# this same act's log sub-fields, asserted in full above — so the tail fits only -# when the CHECKOUT PATH does. Read on `$HOME/projects/repoA11b`, this case's -# answer was the run root's length: green under plain pytest's `/tmp`, red under -# `tests/run.sh`'s per-run root, at the edge on macOS. `/tmp/ort-a11t.XXXXXX/ -# repoA11t` is 29 characters wherever the suite runs, which puts the line at -# about 170, well inside the 230 the cut keeps. It is the one fixture outside -# `$SANDBOX`, and `cleanup` removes it. `tests/test_lane_start_row_stamp.py` -# drives the same stamp at three checkout lengths, the two that are cut included. -A11T_ROOT="$(mktemp -d /tmp/ort-a11t.XXXXXX 2>/dev/null || :)" -is "the TAIL case has its short, fixed checkout root under /tmp" \ - "$( [ -n "$A11T_ROOT" ] && [ -d "$A11T_ROOT" ] && echo yes || echo no )" "yes" +# THE TAIL IS READ ON A CHECKOUT AT A SHORT PATH (opensoft/openRepoTools#180). +# The stamp is ONE line under ratified decision O1's cap (Amendment 13(a)), and +# `cut_to_line` takes `dir` and `window` first by design — both are this same +# act's log sub-fields, asserted in full above — so the tail fits only when the +# CHECKOUT PATH does. Read on `$HOME/projects/repoA11b`, this case's answer was +# the run root's length: green under plain pytest's `/tmp`, red under +# `tests/run.sh`'s per-run root (`… no launch; dir ...`, the path cut whole), at +# the edge on macOS. The checkout goes in this sandbox's own `$TMPDIR` where +# that is at most 40 characters, as under plain pytest on Linux, and in `/tmp` +# where it is not, so `$A11T_DIR` is never over 65 characters and the line never +# over about 210, inside the 230 the cut keeps wherever the root is. `cleanup` +# removes it; only a SIGKILLed run under a long root leaves one in `/tmp`. +# `tests/test_lane_start_row_stamp.py` drives the same stamp at three checkout +# lengths, the two that are cut included. +a11t_base="$TMPDIR" +[ "${#a11t_base}" -le 40 ] || a11t_base=/tmp +A11T_ROOT="$(mktemp -d "$a11t_base/ort-a11t.XXXXXX" 2>/dev/null || :)" A11T_DIR="${A11T_ROOT:-$SANDBOX/a11t-no-short-root}/repoA11t" +is "the TAIL case has a checkout of at most 65 characters, wherever the run root is" \ + "$( [ -n "$A11T_ROOT" ] && [ -d "$A11T_ROOT" ] && [ "${#A11T_DIR}" -le 65 ] && echo yes || echo no )" "yes" git init -q -b main "$A11T_DIR" git -C "$A11T_DIR" remote add origin "https://github.com/opensoft/repoA11t.git" FAKE_TMUX_WINDOW="a11tail:@43" FAKE_TMUX_WINDOW_INDEX=5 FAKE_TMUX_WINDOW_NAME=claude \ From 703c90b819b9452d0d27f845f63efb9f908a337d Mon Sep 17 00:00:00 2001 From: Brett Heap Date: Sat, 17 Oct 2026 21:54:04 +0000 Subject: [PATCH 5/5] Say the shell suite's TAIL checkout is short, not fixed, in the row-stamp test's docstring Since c19150f the clause (c) case's checkout goes under the sandbox's own TMPDIR when that is short and under /tmp when it is not, so its length is bounded at 65 characters rather than fixed. Co-Authored-By: Claude Opus 5.5 --- tests/test_lane_start_row_stamp.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_lane_start_row_stamp.py b/tests/test_lane_start_row_stamp.py index cbb48aed..ee451e9e 100644 --- a/tests/test_lane_start_row_stamp.py +++ b/tests/test_lane_start_row_stamp.py @@ -17,8 +17,9 @@ as `run.sh`'s — with the checkout at three EXACT lengths, so the answer does not depend on where pytest itself was run: - * a short, fixed checkout keeps the whole tail, however long `$HOME` is — - which is what `tests/test_lane_helpers.sh`'s clause (c) TAIL case now uses; + * a short checkout keeps the whole tail, however long `$HOME` is — which is + what `tests/test_lane_helpers.sh`'s clause (c) TAIL case now uses, on a + checkout of at most 65 characters; * a checkout whose path still fits loses only the `window` ref; * a longer one loses the path WHOLE, never a truncated path that reads as a real one. That is what #180's case read under `run.sh`'s root: