Repository navigation
Amendment 23 act 2, slice 2b: lane-start and lane-handoff write the Rule 3 stamp and the PAUSED block with one write-handoff through the lane's checkout, W moves only by fast-forward, and a launch refuses only at a restart's fences - #20
brettheap wants to merge 22 commits into
Conversation
…hrough the lane's checkout, fast-forwards W before and after its writes, and is refused after its first write only by a restart's own fences (#198, slice 2b) Amendment 23, act 2's slice 2b, its `lane-start` half (lane openRepoTools-3's finding 282 on #307, its first writer): - 5c is one `LANES_LANE=<lane> lanes-edit.sh write-handoff <lane> --stamp <line> --subject <subject> [--restart ... --expected-digest <sha>]`, with no LANES_NO_FETCH. `hs_git_net` and `hs_carry_note` are deleted, and with them the publish under W's lock and the add/commit/pull/push in W outside any lock. Its exit is a note; under a supervised restart a 7, or a bound file no longer at the bound digest, still dies. - `refresh-workspace` runs before the first read and again before section 6, under the opt-in with the default resolution and never in a dry run; every exit is a note. The row is read from W after the first refresh, or from W's origin/main where it did not fast-forward; slice 1a's `lane_register_follow` is gone from lane-start. - The lane's checkout is made at "5. the row" (`lane-checkout --create`, a note on refusal), and the writable handoff path `handoff-path` names is printed beside the row's spelling. - The restart binding and 5d read the file `handoff-path` names; an ordinary launch whose own copy is missing falls back to `hs_resolve`, said. - The stale-checkout recoveries name `refresh-workspace` (or fetch and `merge --ff-only` for a caller's checkout) and the publish act, never a pull or a bare push. `request-handoff` gains LANES_LANE. Tests: new tests/test_a23_lane_start.py (eight cases, red at e2037b9); tests/test_a23_lane_start_read.py's lane-start cases follow the new read; the shell suite's RV-B2/RV-B3 (CN-1..3) and the :3189 recovery text; hygiene's no-pull rule covers lane-start. Refs #198 Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit f1b19e96637eb3f67f76d645ac6c8fb5b40869a6)
…so a launch no longer dies with 141 when an early-exiting awk closes the pipe under printf (#198, slice 2b)
CI run 39806108007 at f1b19e9: test_restart_missing_checksum_is_not_launch_authority
exited 141 (SIGPIPE) in `tests` and passed in `tests-no-submodule`. Its
stderr ends at "its record refs are", just before the restart-intent read
`eri_state`/`eri_op`, read by `printf ... | awk '... { print $2; exit }'`
under `set -o pipefail`. bash's printf writes that answer a line at a time,
so an awk that has found its line and exited can close the pipe under a
writer that is not done; the writer's SIGPIPE is the pipeline's status and
`set -e` ends the launch with no word said (openRepoTools#281's class).
`intent_field <answer> <field>` reads to the end and keeps the FIRST value,
as the early exit did. It now reads `eri_state`, `eri_op` and the twelve
`ri_*` fields of the restart reads. The other early-stopping pipes of #281's
class (`lane-start` :426, :1336, :2254, :3783, :3789 and lane-handoff's
restart reads) are left for #281.
New test_restart_intent_answer_larger_than_a_pipe_is_read_to_its_end
[missing-checksum|owned-launch]: a lanes-edit.sh wrapper pads restart-intent's
answer to about 4.6 MB, so an early-stopping reader is certain to close the
pipe before its writer is done. It is red at f1b19e9 (both rc 141, with
stderr ending where CI's did), red again with only the `ri_*` reads
reverted (141 after "binding: unchanged"), and green with this change.
Refs #198
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 84633dfa60e8318ffa2c06627b85db2ad7b809b0)
…epend` through the file `handoff-path` names, so its handoff is committed and pushed under the checkout's lock and never by its own pull and push in W (#198, slice 2b) Amendment 23, act 2's slice 2b, its `lane-handoff` half (lane openRepoTools-3's finding 282 on #307, its second writer): - The handoff file is `lanes-edit.sh handoff-path <lane> --create`: the row's cell translated into the checkout this lane's writes go through (its own `<W>-lanes/<lane>/` under the opt-in, made here where it is not there yet; an explicit LANES_REPO; W where the opt-in is off). 8 is "no handoff named" as before; any other exit is a note in the helper's words. - The publish and the commit block are one `LANES_LANE=<lane> write-handoff <lane> --prepend <block> --subject "handoff(<lane>@<ws>): PAUSED, <why>" [--restart <op> <gen> 0 preparing none]`, with no LANES_NO_FETCH. The add/commit/`pull --rebase`/push in whatever repository held the file, outside any lock and with git's words sent to /dev/null, is deleted; the helper's own words are printed, with a note for each of its exits (2: S3 refused and the file is written, not committed; 3; 6: kept on HEAD, the publish act named). `handoff_written=1` exactly where the helper's stdout line names the file it wrote, and the pending intent binds that path. - Under `--restart` the preparing bind names that file at its digest now (`none` where it is absent), before the write. - A why's control characters are spelled as spaces in the subject (`subject_text`), which `write-handoff` requires. - `append-line` gains LANES_LANE; a `--restart` respawn line carries LANES_ROUTE_WRITES, so the supervisor's lane-start resolves the checkout the intent bound. The t018 single-repository goldens move exactly where the old commit act printed (`t018-handoff/single-repository-decoys.golden` :34-36 and :108-110, `t018/single-repository.golden` :142-144): `handoff commit: ...` and `handoff pushed to origin/main` become write-handoff's own `committed:` and `pushed origin/main (attempt 1)` lines, its subject carries the why, and lane-handoff says which exit it read. Nothing else in either golden moves; both are re-captured by each module's own `--capture`. Tests: new tests/test_a23_lane_handoff.py (three cases, red at 84633df); hygiene's no-pull rule covers lane-handoff, and the carry rule now reads lane-start and lane-handoff. Refs #198 Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit a1f658ef2f2a3d531636d83227dcecc98993a6a8)
…, and a stamp that could not be published, or that the checkout refused, launches with the bound file at its pre-image digest (#198, slice 2b) Amendment 23, act 2's slice 2b, its tests in tests/test_supervised_restart_regressions.py: - `routed_restart_box` and `prepare_restart_routed`: `restart_box` and `prepare_restart` with the default resolution (no LANES_REPO, no LANES_FILE, `workspace.yaml` naming W, LANES_ROUTE_WRITES=1). The first start makes the lane's checkout and adds the row there; the handoff is committed and pushed from it; the intent binds the file `handoff-path` names. `bind_pending` is the one pending-intent call both share. - `test_ctx_round_trip_through_lane_checkout`: `lane-handoff --restart` writes and pushes the PAUSED block from the checkout and binds that file; its respawn line carries LANES_ROUTE_WRITES=1; a `lane-start` without the opt-in refuses (2) with nothing changed; with it, it launches with the PAUSED block as its first prompt, stamps the checkout's file once and pushes it, and the intent is `starting` at the stamped digest. W moves only by fast-forward. - `test_refused_stamp_with_restart_intent_still_launches` (#198 A2): an entry staged in the checkout makes S3 refuse the stamp; the launch exits 0 with nothing written or published, and the intent goes `pending` -> `starting` at the pre-image digest. - `test_restart_atomic_stamp_failure_preserves_original_for_retry` is rewritten for 5c's `write-handoff`: a stamp that could not be published atomically no longer refuses the launch (exit 0, the bound file unchanged, the intent at its pre-image digest), and the retry stamps it once. All three are red at the base: with `lane-handoff` from 84633df the `--restart` refuses "HANDOFF WAS NOT REFRESHED" (it resolved W's copy); with `lane-start` from e2037b9 the atomic case dies 2, the refused stamp dies 2 "the restart handoff the row names is missing", and the round trip never reaches its launch. Refs #198 Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 37b880617ac5d1791b08841e5095a0e2af368993)
… its handoff is not there, naming that file and the command that makes the checkout, and never reads W's copy in its place (#198, slice 2b)
Lane openRepoTools-3's review of #316, finding 727 and its question 2.
5d used to fall back to `hs_resolve`, which joined the row's cell to
`LANES_REPO` and then to W's `workspace-root`, wherever the file that
`handoff-path` names was missing. That read went through W, against
Amendment 23 S2 ("never through W"). The copy it found never carried this
resume's stamp, and its cell was not fenced the way the writes' cell is,
which also kept 723 open.
Now the first prompt is read only from the file `handoff-path` names, for
every launch. Where that file is not there, the launch goes on with no
first prompt, and one note names the missing file and, under the opt-in,
`LANES_ROUTE_WRITES=1 lanes-edit.sh lane-checkout <lane> --create`.
`hs_resolve` and `hs_workspace_root` had no other caller and are deleted.
New case: test_no_lane_copy_launches_with_no_first_prompt_never_W_copy
(red at 37b8806: the first prompt was W's copy).
Lane: openreposhape-2 (openRepoShape-2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit c8ac6ca71a97024ea7b4ba094b4a348c8fed2d4f)
…ff is written and nothing is committed, where their exit-0 words claimed a commit and a push (#198, slice 2b) Lane openRepoTools-3's review of #316, findings 721 and 728 and its question 4, and rv2b's SHOULD 1. Under LANES_NO_GIT=1, `write-handoff` writes the file, commits nothing and exits 0. lane-start then printed "handoff stamped, committed and pushed", which was false. lane-handoff printed "its words above say what it committed and pushed". Now both scripts say the file is written and NOT committed under LANES_NO_GIT=1. Every other exit 0 keeps its words byte for byte, so the t018 goldens do not move. The 8(d) and sibling cases wait for slice 2a's 604 and 601 (part 2). New cases, both red at c8ac6ca: test_no_git_stamp_says_written_and_not_committed and test_no_git_handoff_says_written_and_nothing_committed. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 127ac759a7ea1d62998dbed177a3c93d9f96ae4e)
…tamp, that the first prompt is the checkout's copy and origin's differs, naming both copies and the command that brings the checkout up to date (#198, slice 2b) Lane openRepoTools-3's review of #316, finding 725. Routed, a staged stray in the lane's checkout makes S3 refuse the stamp, and the checkout is not fast-forwarded. Where origin holds a newer PAUSED block from another workstation, 5d delivered the checkout's older block and did not say so. At e2037b9 the newer block was delivered. Now, where 5c wrote nothing on a plain launch, 5d compares the checkout's file with the checkout's own origin/<branch>, which the refused write has just fetched (blob ids). Where they differ, one note names both copies, `git -C <checkout> merge --ff-only origin/<branch>` once the refusal is answered, and how to read origin's copy. The launch still goes on with the checkout's copy, the file this lane's writes go to. Under a restart the bound file stays the prompt, by 5d's fences. New case, red at 127ac75: test_refused_stamp_names_a_checkout_copy_behind_origin. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 77e94b921fac0d100eddea6aeac4fe5bc757f5c2)
… printed re-run only once the restart is confirmed ready, since that write carries none of the restart's fences and exits 7 while the intent is starting (opensoft/openRepoTools#198, slice 2b) Lane openRepoTools-3's review of opensoft/openRepoTools#316, NIT 726. Where the stamp could not be written, lane-start prints the exact `write-handoff --stamp` re-run. That line carries none of a restart's fences, so run while the intent is `starting` the helper refuses it with 7. Now, under an active restart, a second line says to run it only once the restart is confirmed ready. A plain launch's words are unchanged. `test_refused_stamp_with_restart_intent_still_launches` now asserts the re-run line (`with: LANES_LANE=repoZ-1 `, which pins the battery's survivor LS49) and the new line; red at the parent for the new line. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…_ROOT, LANES_REPO and LANES_FILE beside LANES_ROUTE_WRITES, so a /ctx with a register of its own resolves it again in the new pane (opensoft/openRepoTools#198, slice 2b) Lane openRepoTools-3's review of opensoft/openRepoTools#316, NIT 729. The respawn line carried LANES_ROUTE_WRITES but not the register's own seams, so the supervisor and the lane-start it runs resolved the default W, and a /ctx with a W or a register of its own failed closed. That predates slice 2b. Now each of the three is carried where it is set, quoted as the others are; lane-handoff never sets one of its own. Its environment doc names them. New case, red at the parent: test_ctx_respawn_carries_the_register_seams. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…te only W's working tree shows a stray in W, never a hand edit and commit in W, and sends a published one to the lane's own checkout's register and the publish act from there (opensoft/openRepoTools#198, slice 2b) Lane openRepoTools-3's review of opensoft/openRepoTools#316, NIT 730. Under LANES_ROUTE_WRITES=1 with the default resolution, the rows are read from W, and the refusal said to merge the rows "by hand in" W's register and commit with `lanes-edit.sh commit`, which under the opt-in commits in the lane's own checkout, not in W. W is the readers' copy, where no tool writes (Amendment 23 S5). Now, under the opt-in: - where origin/<branch>, as W last fetched it, has fewer than two such rows, the duplicate is only in W's working tree, and the refusal names it a stray in W, which a person takes out; - where origin carries the duplicate, the merge is a hand edit of the lane's own checkout's register (`lane-checkout <lane>` names it, or `--create` makes it), published from there with `LANES_LANE=<lane> LANES_ROUTE_WRITES=1 lanes-edit.sh commit`. Without the opt-in the words are unchanged. The second arm is not reached with this helper: `canon-lane` reads the published register after W is fast-forwarded and refuses a published duplicate first (Amendment 15(d)), and where it cannot answer, `lane-dir` and the managed-ledger fence refuse it too. So under the opt-in this refusal meets the stray in W, and the second arm is the right words for a path that reaches it anyway; the comment says so. New case, red at the parent: test_duplicate_row_only_in_W_is_named_a_stray_there. And a pin, green at the parent too: test_published_duplicate_row_is_refused_before_W_is_named (canon-lane's refusal, nothing written, never the words that send a merge to W). Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…or byte what c45a452 printed": lane-handoff's commit act, re-captured from slice 2b's tools (opensoft/openRepoTools#198, slice 2b) Lane openRepoTools-3's review of opensoft/openRepoTools#316, question 3. Slice 2b replaced lane-handoff's own commit and push with one `write-handoff --prepend`, and moved the two single-repository goldens at exactly those lines (three hunks in all). "Byte for byte what c45a452 printed" was then false for them. Both module docstrings and both `capture()` docstrings now name the exception: which lines, why, and that every other line is c45a452's. The case names are kept. No behaviour changes, so there is no red case and no mutant. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…in the skill's phrases, and both scripts' exit-6 words point at the helper's account instead of saying a commit is kept on HEAD of the lane's checkout (opensoft/openRepoTools#198, slice 2b) opensoft/openRepoTools#303's fit (c) in lane openRepoTools-3's review of opensoft/openRepoTools#316, and from its review of opensoft/openRepoTools#311 at 1913db9: question 6, SHOULD 982 (which names lane-handoff:2689) and INFO 990. The register's file-level PAUSED line ended "; handoff refreshed" whatever happened. Now it keys on what `write-handoff` did, with the skill's phrases, so the two writers of the one act (Amendment 17(a)) say the same thing: - "handoff refreshed": it wrote the block and exited 0, git allowed; - "handoff written, NOT published (write-handoff exited n)": 2, 6, and any other code that wrote; "(LANES_NO_GIT=1)" for 990's harness case; - "handoff written, its publication NOT confirmed (write-handoff exited 3)": 3 only; - "handoff NOT refreshed (...)": no handoff found, handoff-path failed, write-handoff not called, or it exited n and wrote nothing. No reader parses the suffix. Exit 6 is not one state: `git add` or `commit` failed and nothing is committed, or the commit is kept on HEAD and named; and with slice 2a's 604, an 8(d) handoff's commit or push in its own repository failed. Both scripts' 6 words now say the file is written and NOT published, point at the helper's words for whether and where a commit was made, and name the publish act only for a commit kept in the lane's register checkout. The shell suite's RV-B2 (a) assertion moves with lane-start's words. test_handoff_skill_80_85's reading of lane-handoff's register line sets the record of a write that exited 0. New cases, red at the parent: test_register_paused_line_says_what_the_write_did[2, 3, 6, 1] and test_stamp_exit_6_says_what_the_helper_said_not_kept_on_HEAD (which also pins the battery's survivor LS45); test_no_git_handoff_says_written_and_ nothing_committed asserts the LANES_NO_GIT=1 record. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f a peer moved with its row's cell during the stamp is still delivered; the slice's tests split their composite asserts, share one copy of each W helper, and scrub a caller's WORKBENCHES_ window (opensoft/openRepoTools#198, slice 2b) rv2b's NITs on opensoft/openRepoTools#316. NIT 1. Where a peer moves the lane's handoff, and the row's cell with it, while this launch stamps it, the write's replay follows the cell and stamps the moved file. 5d then read the path `handoff-path` named before the write, which is gone from the checkout, and launched with no first prompt. Now 5d reads the file this call wrote (`HS_PATH` from the helper's written-file line, where that file is there). New case, red at the parent: test_first_prompt_follows_a_handoff_a_peer_moved_during_the_ stamp, whose wrapper's peer `git mv`s the handoff and edits the row's cell during `write-handoff`. NIT 2. Fifteen composite asserts (S9073) are split into one condition each: six in test_a23_lane_start, four in test_a23_lane_handoff and five in the supervised-restart cases. NIT 3. One copy of each helper: test_a23_lane_start's `_reflog` and `_assert_W_only_fast_forwarded` give way to slice 1a's `W_reflog` and `assert_W_moved_only_by_fast_forward` in test_a23_lane_start_read, which check the same three things; a new `no_auto_gc` there replaces `_quiet` and both gc loops; `FF` is dropped. `_published` and `published` stay two: the row-stamp sandbox has no `origin` and returns text, the claude-current one returns bytes. NIT 5. `WORKBENCHES_` joins both SCRUBBED_PREFIXES, so a caller's own lane window never reaches a sandbox. NIT 4 needs no change here: slice 3 already spells the PAUSED subject as lane-handoff does (`${ws:-unknown}`, control characters made spaces). Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rd for word: a 0 is "handoff refreshed", LANES_NO_GIT=1 included, a 2 or 6 that wrote is "NOT published", and a 3 or any other exit after a write is "its publication NOT confirmed" (opensoft/openRepoTools#198, slice 2b) Lane openRepoTools-3's answer 6 on opensoft/openRepoTools#311 asked for one set of record phrases for the act's two writers, "refined on both sides". Slice 3 took it on the skill's side (its F23 and F24, at 2a420e0 on the code leg), and this commit makes lane-handoff's 4(b) line read the same: - a 0 records "handoff refreshed", which claims no commit. Under LANES_NO_GIT=1 that is now the record too, where item 8 wrote "handoff written, NOT published (LANES_NO_GIT=1)": the step line already says that nothing was committed (728), and the skill keeps the 0 record for every 0 (F24, which answers INFO 990 for both writers); - a 2 or a 6 that wrote: "handoff written, NOT published (write-handoff exited <n>)"; - a 3, or any other exit after a write: "handoff written, its publication NOT confirmed (write-handoff exited <n>)", since such an exit claims nothing either way (item 8 said "NOT published" for the others); - "handoff NOT refreshed (<why>)" where nothing was written, unchanged. The comment over the record names the set. Item 8's explicit 3 arm assignment goes, since 3 now takes the default. Cases: test_register_paused_line_says_what_the_write_did gains a row for an exit 5 after a write, and test_no_git_handoff_says_written_and_ nothing_committed asserts "; handoff refreshed"; both red at the parent. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… refreshes' scope, a refresh that could not fast-forward W, the stamp's LANES_LANE, both stale-row recoveries, the checkout made at the row, and lane-handoff's exit words, its printed block and a handoff-path that failed (opensoft/openRepoTools#198, slice 2b) m2b's battery of 59 one-line mutants of 2b's own code left 26 alive on 10-23. Earlier items pinned I1a, I2a and I2b (items 1 and 2), LS49 (item 4) and LS45 (item 8); LS46, LS47 and LH04 are part 2's 733 cases. This commit adds a case, or an assertion in one, for each of these, and each is shown killing its mutant: - LS03 and LS02: a recording LANES_EDIT shows no refresh-workspace without the opt-in, and none for a caller's LANES_REPO under it; - LS06: a normal routed start says nothing of a refresh that failed and reads the row from W's working tree; - LS07, LS10 and LS12: where W holds a commit of its own, the refresh cannot fast-forward it; the launch says so, reads the row a peer pushed from origin/main as W last fetched it, and offers no second row; - LS29: a first start says nothing of a checkout that could not be made; - LS41: the stamp's write-handoff carries LANES_LANE; - LS17: without the opt-in, a start behind a peer's row names refresh-workspace, never a fetch and merge typed in W; - LS19: under the opt-in, a row only W's working tree carries is named a stray in W; - LH13: lane-handoff's exit-0 step line; LH14: exit 2's own note ("Never re-run this handoff"); LH16: the block printed where nothing was written; LH03: a handoff-path that failed is said, the block printed, and the register records "handoff NOT refreshed (handoff-path exited 1)". LS12 and LH13 are rewritten against today's code (LS12's recorded text did not match, LH13's arm changed in item 2). Not pinned, and named in the PR body: LS08, LS21, LH07 and LH11 (equivalent today, or needing restart plumbing), LS52 (its fallback is gone since item 1) and LS20 (the shell suite's :3189, CI only). No behaviour changes. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…2b, so 2b's cases run on the verbs it calls: 601 in the shared translation, 602, 603's 7, 604's 8(d) commit, 605, 732 and 991 (opensoft/openRepoTools#198) Main named 2a's head at 14:07Z. This slice stood on f00def1 (A46); 2a's round since then, A47 to A60 with slice 1b merged at 59551dd, changes lanes-edit.sh and its tests only: - A54, 601 (and the precondition of 723): write-handoff, handoff-path and set-restart-intent --handoff refuse a handoff in W or in another checkout of the register, in the translation the three share; - A55, 602: a cell or --target whose . or .. components climb out of the checkout is refused; - A56, 603: write-handoff answers the shared act's two restart-fence 2s (the bound file, the pre-image) with 7; - A57, 604: an Amendment 8(d) handoff is committed and pushed in its own repository, as lane-start and lane-handoff did at e2037b9; - A58, 732: refresh_workspace_strays' git status in W takes no optional lock; - A59 and A60, 605 and 991: a fenced --prepend takes --expected-digest none only, and no glob character in a handoff's path. The merge is clean: no hunk was resolved by hand. git merge-tree of 1320847 into this branch's e5c3326 gave tree 660ad87 before the merge was made, and the merge commit's tree is that tree. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he register beside W, is neither stamped nor delivered by lane-start and takes no PAUSED block from lane-handoff, now that slice 2a refuses it in the translation all three verbs share (opensoft/openRepoTools#198, slice 2b) Lane openRepoTools-3's review of opensoft/openRepoTools#316, MUST 723. With the lane's cell naming repoZ-2's handoff in repoZ-2's own clone of the register beside W, lane-start stamped repoZ-1's RESUMED line into that clone, uncommitted, and launched with repoZ-2's top block as its first prompt; lane-handoff wrote the PAUSED block there the same way. Slice 2a's 601 (A54), merged at e12b369, puts the refusal in the translation write-handoff, handoff-path and set-restart-intent share, and item 1 (727) made 5d read only the file handoff-path names. So no 2b code changes; one case per call site pins it: - lane-start: nothing is written in the sibling's file or checkout, none of its block is delivered, and the launch goes on with no first prompt, write-handoff's words naming another checkout of the register; - lane-handoff: nothing is written there, the block is printed, and the register's PAUSED line records "handoff NOT refreshed (handoff-path exited 2)". Both cases were red at e5c3326, before the merge (the sibling's file written), and are green on it. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… reads a refused stamp's 7 as lost ownership, since slice 2a now answers both restart fences with 7 (opensoft/openRepoTools#198, slice 2b) Lane openRepoTools-3's review of opensoft/openRepoTools#316, SHOULD 724. Since slice 2a's 603 (A56), merged at e12b369, write-handoff answers the shared act's two restart-fence 2s (the bound file, the pre-image) with 7. So a bound handoff a peer changed after binding came back from 5c as 7, and lane-start, which asked the 7 first, said "this restart attempt lost ownership of its handoff". 5c now asks hs_bound_unchanged first and dies "the restart handoff changed before its owned resume stamp"; a 7 with the bound file unchanged is still lost ownership. Both exit 2, and S3's 2 stays a note (test_refused_stamp_with_restart_intent_still_launches). New case, red on the merge before this commit: test_a_bound_handoff_changed_before_the_stamp_is_named_so, whose wrapper changes the bound file just before the real write-handoff. It also pins the battery's LS47 (733's M2). Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tted and pushed in its own repository at both call sites, and both scripts' exit-0 words point at the helper's account, which may say nothing was committed (opensoft/openRepoTools#198, slice 2b) Lane openRepoTools-3's review of opensoft/openRepoTools#316, SHOULD 722 and 721's last case, with 982's 8(d) case from its review of opensoft/openRepoTools#311. Lane 3 read Amendment 23 S2 as governing, and slice 2a's 604 (A57), merged at e12b369, commits and pushes an 8(d) handoff in its own repository, as e2037b9 did. Pinned at both call sites: the stamp and the PAUSED block are committed there by pathspec and pushed to that repository's origin, its tree clean, the register taking no commit for them; an 8(d) stamp whose push fails there is a 6 whose note points at the helper's words, never at HEAD of the lane's checkout. A 0 is still not always a commit: an 8(d) handoff in no work tree, or a clone of the register not beside W, is committed nowhere, and the helper's note says so. So both scripts' exit-0 words now end as slice 3's 0 arm does (its F24), "or that nothing was committed": - lane-start: "handoff stamped through `write-handoff`, which exited 0: <file>: <stamp> (its words above say what it committed and pushed, or that nothing was committed)", where it said "handoff stamped, committed and pushed"; - lane-handoff: "... its words above say what it committed and pushed, or that nothing was committed". The three golden lines of lane-handoff's exit-0 step (decision 22's hunks) and the shell suite's :3822 (CI only) move with them. New cases, red at e5c3326 before the merge (the 8(d) file left uncommitted), and the two exit-0 cases red on the merge before this commit's words: test_an_8d_cell_is_stamped_committed_and_pushed_in_its_ own_repository, test_an_8d_stamp_whose_push_fails_there_says_what_the_ helper_said, test_an_8d_cell_takes_the_block_committed_and_pushed_in_ its_own_repository. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d trip while W is behind and cannot be fast-forwarded, and a why with a tab in lane-handoff (opensoft/openRepoTools#198, slice 2b) Lane openRepoTools-3's review of opensoft/openRepoTools#316, SHOULD 733, its remaining cases, and slice 2a's Q2 caveat: - M1 (the battery's LS46): under a restart, a stamp write-handoff refuses with 7 and no written line, the bound file unchanged, dies 2 "lost ownership of its handoff before the resume stamp", nothing launched (with slice 2a's 603 this is the fence's code, and S3's 2 stays a note); - 733's first case and 2a's Q2 caveat: with W holding a commit of its own and a peer's push since, no refresh can fast-forward W; the /ctx round trip still writes and binds the lane's checkout's file, path and digest through handoff-path, the launch says W was not fast-forwarded, delivers and stamps that file, and W's HEAD does not move; - M4 (the battery's LH04): a why with a tab refreshes the handoff, the subject carrying a space (decision 19). M2 is the case of the previous commit (724). M3 has no case of its own: handoff_written on a written but uncommitted /ctx is set from the written-file line, which S3's 2 prints, and the battery's LH12 (the same flag held at 0) is killed by the round trip. No behaviour changes; each case passed before this commit's tests were added, so each is shown by its mutant. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ich brings slice 1a's merge of openRepoTools-code main 577110e) into slice 2b, so the slice stands on the code leg's main and its front door (opensoft/openRepoTools#198) Main named 2a' at 16:2xZ. This slice merged 2a's 1320847 at e12b369, and 2a' contains it; it adds slice 1b's round as rebuilt on the code leg and, through slice 1a's 903d751, the code leg's main 577110e: the cutover's own commits (among them 6314fc8, the code leg's front door with .gitattributes, the LF rule) and code PRs 3 to 7, T017's five lanes-edit.sh fixes. 31 files differ between 1320847 and 2b1a232; of the files this slice changes, only tests/test_lane_helpers.sh and tests/test_repo_hygiene.py, in hunks this slice does not touch. 1b' and main are not merged here on their own: 2a' carries them, as main asked. The merge is clean: no hunk was resolved by hand. git merge-tree of 2b1a232 into this branch's c12f078 gave tree 4b6b9ea before the merge was made, and the merge commit's tree is that tree. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideImplementationRoute lane-start’s Rule 3 stamp and lane-handoff’s PAUSED block through the lane’s writable checkout with write-handoff, while keeping W fast-forward-only and preserving restart-specific refusal fences.
TestsAdd coverage for routed stamp and handoff writes, failure and recovery messaging, restart behavior, missing or moved handoffs, alternate repositories, and W’s fast-forward-only movement.
Update launch-read regressions and environment scrubbing to verify W moves only by fast-forward and sandbox runs do not inherit caller window variables.
Align shell regressions for stale-row recovery and refused or successful stamp publication with the new write-handoff behavior.
Extend hygiene checks to prohibit pulls and carry promises in both lane scripts.
Refresh the tooling goldens and document their lane-handoff output exception, while retaining the surrounding baseline output.
Update the skill regression to expect the PAUSED record phrase produced by a successful handoff write.
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
… brings lane-start and lane-handoff on write-handoff and the three-name _NO_PULL_FILES that slice 3 left to it (opensoft/openRepoTools#198) Slice 2b's head on the code leg, feat/198-a23-slice-2b-start-handoff at a44b9d2 (2b', which carries 2a', 1b', 1a' and the code leg's main 577110e), named by main for the one sitting that lane openRepoTools-3 ruled (opensoft/openRepoTools#198): slice 3 lands last, right after 2b, and its merge tree must equal this head's tree. The tree is `git merge-tree --write-tree 95c52cc a44b9d2` = bebe083. The merge base is 2b1a232, the 2a' head that slice 3 merged at 95c52cc; from it 2b' changes 15 files (2123 insertions, 537 deletions). Of slice 3's own files it touches one, tests/test_handoff_skill_80_85.py, by one line in _lane_handoff_writes (it binds handoff_record in the stand-in script), in a hunk slice 3 does not touch, and it leaves skills/handoff/SKILL.md and tests/test_handoff_skill_commit_block.py as they are. It also changes tests/test_repo_hygiene.py's _NO_PULL_FILES to ("lanes-edit.sh", "lane-start", "lane-handoff"), which slice 3 left to it (lane 3's answer 3). The merge is clean: no hunk was resolved by hand. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…wner case hold on CI's git 2.56.0) into slice 2b (opensoft/openRepoTools#198) CI on #18 failed 2 of 3654 at 2b1a232, the two `other-owner` cases of `test_a_clone_git_cannot_read_is_never_taken_for_no_repository` in tests/test_a23_write_handoff.py. 56a9b87 is 2a's fix for them: the case sets `GIT_CONFIG_NOSYSTEM=1` beside git's test hook, and skips, saying why, where git still reads the clone. It changes that one test file by 32 lines added and 2 removed, and nothing else. This slice carried the same test file at a44b9d2, with 2b1a232's version of it, so it would have failed the same two cases on CI's git. The merge is clean: no hunk was resolved by hand. git merge-tree of 56a9b87 into this branch's a44b9d2 gave tree c17ffb5 before the merge was made, and the merge commit's tree is that tree. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
… brings A61, which makes 2a's other-owner case hold on CI's git 2.56.0, and it changes no file of this slice (opensoft/openRepoTools#198) Slice 2b's new head on the code leg, feat/198-a23-slice-2b-start-handoff at 4031100 (2b''), named by main. It is a --no-ff merge of 2a'' (56a9b87) into a44b9d2 (2b'), the head that slice 3 merged at 6b81f19. 56a9b87 is A61, a test-only fix to 2a: CI's git 2.56.0 failed test_a_clone_git_cannot_read_is_never_taken_for_no_repository and its two other-owner cases, which slice 3 carried through 2a', and the case now sets GIT_CONFIG_NOSYSTEM=1 and skips, saying why, where git still reads the clone. CI at 95c52cc failed only those two (3734 passed). The tree is `git merge-tree --write-tree 7690a1f 4031100` = fdf667e. The merge base is a44b9d2; from it 2b'' changes one file, tests/test_a23_write_handoff.py (32 insertions, 2 deletions), and relative to this branch's 7690a1f the merge changes that file and no other. None of this slice's files is touched. The merge is clean: no hunk was resolved by hand. Lane: openreposhape-2 (openRepoShape-2) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
lane-start and lane-handoff write the Rule 3 stamp and the PAUSED block with one write-handoff through the lane's checkout, W moves only by fast-forward, and a launch refuses only at a restart's fences (opensoft/openRepoTools#198)lane-start and lane-handoff write the Rule 3 stamp and the PAUSED block with one write-handoff through the lane's checkout, W moves only by fast-forward, and a launch refuses only at a restart's fences



Lane: openreposhape-2 (openRepoShape-2)
Claim: opensoft/openRepoTools#198 (comment)
Re-homed from opensoft/openRepoTools#316
77e94b9on opensoft/openRepoToolsfeat/198-a23-slice-2b-start-handoff, the archived original. That branch is not pushed again.4031100on opensoft/openRepoTools-codefeat/198-a23-slice-2b-start-handoff. The old head's rebuild is31990c4; this round's commits follow it, and the last two are merges of slice 2a' (a44b9d2, then4031100with A61).leg: codeentries), and the commit was made again on its rebuilt parent. Author, dates and message are kept, with a(cherry picked from commit …)line added. Old main'sf18b818, which the old stack stood on, is the code leg's0cefa1f.!, and each differs only by the cherry-pick line. No hunk of code differs, and this slice changed no spec-leg path, so nothing was dropped.Receipt: the 7 commits, old opensoft/openRepoTools sha to code-leg sha
Each subject ends with the slice's reference to the act 2 issue, left out here.
f1b19e9068f190write-handoff --stampthrough the lane's checkout, fast-forwards W before and after its writes, and is refused after its first write only by a restart's own fences84633dfce73c92a1f658eb848bd8write-handoff --prependthrough the filehandoff-pathnames, so its handoff is committed and pushed under the checkout's lock and never by its own pull and push in W37b88063ce57f6c8ac6cadbfbec6127ac75dc50eb577e94b931990c4Stacked on
Slice 2a' on the code leg,
feat/198-a23-slice-2a-handoff-verbsat56a9b87: 2a's round head1320847(old7bc572c, A60) with slice 1b at34799b7, which brings slice 1a's merge of the code leg'smain(577110e), merged as2b1a232, and A61 on top of it (2a's decision 32: the fix for the two cases CI failed at2b1a232). This branch merged1320847ate12b369, 2a' at2b1a232asa44b9d2, and 2a' at56a9b87as4031100, all clean. This PR's own diff isgit diff 56a9b87 HEAD:lane-start,lane-handoffand their tests.Why one PR for both scripts (the plan's §3, slice 2b):
/ctx's round trip compares paths with-efand by digest.lane-handoffbinds the restart intent, andlane-startchecks it. If either script moved alone, every/ctxunder the opt-in would refuse as "different handoffs".This round: lane openRepoTools-3's review of opensoft/openRepoTools#316 at
37b8806, and its review of opensoft/openRepoTools#311Lane openRepoTools-3's review of opensoft/openRepoTools#311 (comment 6376170218) touched this slice in three places (982, question 6, 990), and its review of opensoft/openRepoTools#316 said LAND AFTER FIXES.
Each fix has a case that was red before it, or, where the case pins what already held, a mutant the case kills; each has its own commit. The docstring change (question 3) needed neither. Commits before
31990c4were made on the old root and are named by their old shas.c8ac6ca(dbfbec6)LANES_NO_GIT=1127ac75(dc50eb5)77e94b9(31990c4)e97ad3f--restartrespawn droppedLANES_WORKSPACE_ROOT,LANES_REPOandLANES_FILE67e6da5retired_word's pipe was missing from "Not changed"2bd3ea2fb4a7b0handoff refreshedwhatever happened; the 6 arm said "kept on HEAD"c1f2928,439699fWORKBENCHES_not scrubbed2e4d7dde5c3326e12b36958309ba615cfdd5bf9bbbc12f078main)a44b9d2tests/test_a23_write_handoff.pyfailed on #18 at2b1a232(2a's decision 32), and this slice carries the same file4031100Decisions
LANES_ROUTE_WRITES=1,write-handoffwrites W under W's lock, with S3 and S4.lane-start's andlane-handoff's unlocked W commits are gone in both modes. Those are lane openRepoTools-3's finding 282 on Amendment 23 slice 1b: every writer fetches and fast-forwards under its lock or refuses with nothing written, pushes with no pull and reads origin back, a refused push replays the one edit, andcommitwith nothing staged is the publish act (#198) openRepoTools#307, its first two writers.LANES_REPOorLANES_FILEis the caller's register (the seam), so W is not what is read.refresh-workspaceis a note.rows_for_lanereads W after the first refresh (the plan's §2.7).origin/main's register as W's tracking ref has it, and falls back to the working tree, with a note, where W has no such ref. No temporary file is used, sinceexecskips the EXIT trap.lane_register_followinlane-start.lane-endkeeps its own follow (slice 4's).lane-checkout <lane> --create, under the opt-in with the default resolution, and never in a dry run. A refusal is a note, and the launch goes on (1a's SHOULD 2). After the row, the writable handoff path thathandoff-pathnames is printed beside the row's spelling.LANES_LANE=<lane> write-handoff <lane> --stamp <line> --subject <subject>, with noLANES_NO_FETCH. Under an active restart it adds--restart <op> <gen> <attempt> starting <transcript> --expected-digest <digest>.ri_expected_digestbecomes the digest on stdout.hs_git_netandhs_carry_noteare deleted, as the plan says. That settles lane openRepoTools-3's request (282) thaths_carry_note's middle branch name the publish act: there is no carry note left to reword, and no commit oflane-start's outside a lock.handoff-pathnames, which is the onewrite-handoffwrites.hs_resolve(W's copy), with a note. A checkout that could not be made then does not cost the first prompt.-efand digest fences still stand behind it.pending→startingat the pre-image digest (Lane writers commit first and sync second, so a pull that refuses or conflicts strands the commit and later writes stack on it: fast-forward before the edit, and refuse before committing (fail closed) openRepoTools#198 A2).lanes-edit.sh refresh-workspace. Where it is a caller's checkout, they namegit -C <checkout> fetch origin main && git -C <checkout> merge --ff-only origin/main.LANES_LANE=<lane> lanes-edit.sh commit "<what it is>"", the publish act, which also carries a pending hand edit.request-handoffgainsLANES_LANEin its env. The printed step line is unchanged.lane-handoff's file ishandoff-path <lane> --create, run with its stderr shown and withoutLANES_NO_FETCH, so the cell is read from the freshestorigin/main.write-handoff's S3 fast-forwards a stale checkout, and its 8 means there is nothing to write into.LANES_LANE=<lane> write-handoff <lane> --prepend <block> --subject "handoff(<lane>@<ws>): PAUSED, <why>", with[--restart <op> <gen> 0 preparing none]under a restart, noLANES_NO_FETCHand no--expected-digest, replacespublish-handoffand the commit block.top_block's output alone.write-handoffadds---and a blank line, the same bytes as before.handoff_written=1exactly where stdout carries thepath<TAB>digestline: exits 0, 3, 6, and S3's 2, which writes and does not commit.handoff_filebecomes that path, so the pending intent and its read-back bind the file that was written./dev/null.append-linegainsLANES_LANE. The skill test'sappend-line ("PAUSED — lane …")regex still finds the one call.--restartrespawn line carriesLANES_ROUTE_WRITESwhen it is set, so the supervisor and thelane-startit runs resolve the checkout the intent bound. Without it, an opted-in/ctxbinds the lane's checkout, and its respawn reads W and refuses with "different handoffs". The new round-trip case shows that refusal.hs_resolve's case (c) is no longer a stamp target. The stamp goes only wherewrite-handoffresolves the row's cell, in the checkout writes go through (S5: never W). The shell suite's CN-2 becomes "not stamped, the line printed".handoff-pathafter the row also runs in a dry run, withLANES_NO_FETCH=1there. An active restart's--no-launchis a dry run, and 5d's strict branch needs the bound file in it. Elsewhere it fetches, so a new lane's first start still finds the row it pushed from its checkout before W's ref moved.handoff-pathruns withLANES_NO_FETCH=1, like every other restart read there. It keepslane-start's two refusals word for word: "the restart handoff the row names is missing" and "the restart intent and register name different handoffs".handoff-pathgave, athandoff_digestof it now (nonewhere it is absent), before the write.write-handoff's 8: the block is printed, and the gate refuses with "the HANDOFF WAS NOT REFRESHED", as before (the shell suite's repoHF-12).subject_text,LC_ALL=C).write-handoffrefuses a subject that carries one (64, nothing written). The door already refuses a newline and a carriage return, so this only keeps a why with a tab refreshing the handoff, as the oldgit commit -mdid.lane-startreads the restart intent's answer to its end (intent_field), foreri_state,eri_opand the twelveri_*fields.f1b19e9hadtest_restart_missing_checksum_is_not_launch_authorityexit 141 (SIGPIPE):printf … | awk '… {print $2; exit}'underpipefaillost a race against a writer that was not done.intent_fieldkeeps the FIRST value, as the early exit did.test_restart_atomic_stamp_failure_preserves_original_for_retryasserted exit 2. Now a stamp that could not be published atomically is a note (decision 8): the launch exits 0, the bound file is unchanged, and the intent isstartingat the pre-image digest. The retry stamps it once.lane-handoff's commit act printed (t018-handoff/single-repository-decoys.golden:34-36,108-110andt018/single-repository.golden:142-144).handoff commit: <subject>andhandoff pushed to origin/mainbecomewrite-handoff's ownlanes-edit: committed: <subject>andlanes-edit: pushed origin/main (attempt 1), beforehandoff refreshed: …. After it comeslane-handoff's line naming the exit it read.--capture, normalised as before._NO_PULL_FILESgainslane-startandlane-handoff. The newtest_no_lane_script_promises_the_carry[lane-start|lane-handoff]reads both scripts. At the base,lane-handoffhad a carry promise ("captured by the next lane's commit") and twopull --rebaselines.handoff-pathnames, for every launch. Where it is missing, the launch goes on with no first prompt, and one note names the missing file and, under the opt-in,LANES_ROUTE_WRITES=1 lanes-edit.sh lane-checkout <lane> --create. W's copy is never read in its place.hs_resolveandhs_workspace_rootlost their last caller and are deleted, which retires 7's fallback and 15's case (c).LANES_NO_GIT=1, lane-start says "Rule 3's stamp is written in and NOT committed: LANES_NO_GIT=1 commits and pushes nothing", and lane-handoff says "the block is written in and nothing is committed or pushed". 36 words every other 0.origin/<branch>, which S3 has just fetched (blob ids). Where they differ, one note names both copies andgit -C <checkout> merge --ff-only origin/<branch>. The launch goes on with the checkout's copy, the file this lane's writes go to.write-handoff --stampre-run. Under an active restart a second line says to run it only once the restart is confirmed ready, since that write carries none of the restart's fences and exits 7 while the intent isstarting. A plain launch's words are unchanged.LANES_ROUTE_WRITES, the--restartrespawn line carriesLANES_WORKSPACE_ROOT,LANES_REPOandLANES_FILEwhere each is set, quoted as the others are. lane-handoff never sets one of its own. Without them the new pane resolved the default W, and a/ctxwith a register of its own failed closed. This predates 2b.lanes-edit.sh commit, which under the opt-in commits in the lane's own checkout. Now, under the opt-in:origin/<branch>, as W last fetched it, has fewer than two such rows, the duplicate is only in W's working tree, and the refusal names it a stray in W, which a person takes out;LANES_LANE=<lane> LANES_ROUTE_WRITES=1 lanes-edit.sh commit.canon-lanereads the published register after W is fast-forwarded and refuses a published duplicate first (Amendment 15(d)), andlane-dirand the managed-ledger fence refuse it too. A case pins that, and the code's comment says so. Its mutant (I6c) is not pinned.capture()docstrings say which lines moved (the commit act's three hunks, decision 22), why, and that every other line isc45a452's. The case names are kept.handoff-pathand writes it with ONEwrite-handoff --wholecall from the lane's own checkout, so it spells, commits in, pulls and pushes no checkout of its own (#198) openRepoTools#311; slice 3's F23 and F24). lane-handoff's 4(b) line keys on whatwrite-handoffdid:handoff refreshedon a 0,LANES_NO_GIT=1included: it claims no commit, and the step line says what was done (25, 36);handoff written, NOT published (write-handoff exited <n>)for a 2 or a 6 that wrote;handoff written, its publication NOT confirmed (write-handoff exited <n>)for a 3, and for any other exit after a write, which claims nothing either way;handoff NOT refreshed (<why>)where nothing was written: no handoff found,handoff-pathfailed,write-handoffnot called, or it exited n and wrote nothing.lane-handoff:2689).git addorcommitfailed and nothing is committed, or the commit is kept on HEAD and named; and since 2a's 604, an 8(d) handoff's commit or push in its own repository failed. Both scripts' 6 words now say the file is written and NOT published, point at the helper's words for whether and where a commit was made, and name the publish act only for a commit kept in the lane's register checkout. This supersedes 5's "kept on HEAD".handoff-pathnamed before it.W_reflog,assert_W_moved_only_by_fast_forwardand a newno_auto_gcintest_a23_lane_start_readreplace their copies._publishedandpublishedstay two, because the row-stamp sandbox has nooriginand returns text, and the claude-current one returns bytes.WORKBENCHES_joins bothSCRUBBED_PREFIXES.write-handoff,handoff-pathandset-restart-intentshare (A54), and 5d reading only the filehandoff-pathnames (24), a row cell naming another lane's handoff in that lane's clone of the register beside W is refused at every call site. lane-start writes nothing there, delivers none of its block and launches with no first prompt, naming why. lane-handoff writes nothing there, prints its block, and recordshandoff NOT refreshed (handoff-path exited 2). No 2b code changed for it; one case per call site pins it.hs_bound_unchangedfirst and dies "the restart handoff changed before its owned resume stamp"; a 7 with the bound file unchanged is still "lost ownership". Both exit 2, and S3's 2 stays a note.e2037b9did. Pinned at both call sites: the stamp and the PAUSED block are committed there by pathspec and pushed to that repository's origin, its tree clean, and the register takes no commit for them. A 0 may still commit nothing (an 8(d) handoff in no work tree, a clone of the register not beside W), so both scripts' exit-0 words now point at the helper's note "or that nothing was committed", as the skill's 0 arm does (F24). lane-start's 0 says "handoff stamped throughwrite-handoff, which exited 0: : (its words above say what it committed and pushed, or that nothing was committed)". The three golden lines of lane-handoff's exit-0 step and the shell suite's:3822move with them. An 8(d) stamp whose push fails there is a 6 with the helper's words (982's 8(d) case).What changed
lane-start:ls_refreshcalls (decision 2) and the rows source (3);write-handoff --stamp(5, 8);request-handoff's env (10);LANES_ROUTE_WRITES).lane-handoff:handoff-path --create(11);write-handoff --prepend, and the commit block is deleted (12, 18, 19);append-line's env (13);--restartrespawn line (14);tests/test_a23_lane_start.py(8 cases at first, 24 now) andtests/test_a23_lane_handoff.py(3 cases at first, 13 now), ontest_lane_start_row_stamp's sandbox with the default resolution and the opt-in;tests/test_a23_lane_start_read.pyfollow decisions 3 and 4: W moves only by fast-forward, and the checkout-refusal cases keep "could not be made" and "exited 4";tests/test_supervised_restart_regressions.py: the pipe-sizedrestart-intentanswer case (20); the default-resolution variant (routed_restart_box,prepare_restart_routed, sharingbind_pendingwithprepare_restart);test_ctx_round_trip_through_lane_checkout;test_refused_stamp_with_restart_intent_still_launches; and the atomic-stamp case's rewrite (21);tests/test_lane_helpers.sh, run in CI only::3189's recovery text (9);LANES_WORKSPACE_ROOT=$WS2: not stamped, the line printed (15);tests/test_repo_hygiene.py(23);Functions this PR changes in
lane-startandlane-handoffThis list is for lane openRepoTools-4's opensoft/openRepoTools#303 ("every read of a lane's log reports whether it happened"), which may need these two scripts. It was compiled from
git diff e2037b9 HEADby function body, and checked again againstgit diff 1320847 HEADfor this round.lane-start(56 → 56 functions):ls_refresh,ls_register_text,ls_rows_source,hs_bound_unchanged,intent_field;hs_git_net,hs_carry_note,lane_register_follow, and, with 24,hs_resolveandhs_workspace_root;rows_for_lane,row_names_for_lane;eri_*,ri_*, the binding), the stale-checkout recoveries,request-handoff's env, section 5, 5c and 5d.rows_for_lanereads the register, not a log, and thelogandlane-reconcilecalls are as they were.lane-handoff(47 → 48 functions):subject_text;top_block,sanitize,cut_to_line, the supervisor and every log, row and lifecycle function are as they were;append-line's env in section 4(b), the--restartrespawn line and the header.Tests
One pytest process at a time, with every
LANES_*,LANE_START_*,TMUX*andWORKBENCHES_*variable unset, a refusingghstub first onPATH,GH_TOKEN=bogusandGIT_SSH_COMMAND=false. The bench was loaded by other lanes' runs throughout.The module set (run at
a44b9d2, the merge of 2a'; the four rows marked4031100run again at this head, the merge of 2a' with A61, which changestests/test_a23_write_handoff.pyand nothing else):tests/test_a23_lane_start.py4031100)tests/test_a23_lane_handoff.py4031100)tests/test_supervised_restart_regressions.py -k "routed or refused_stamp or atomic_stamp or restart_owned or respawn or ctx or second_ctx or plain_handoff or handoff_publishers or bound_handoff or lost_ownership or W_behind or larger_than_a_pipe or missing_checksum or interrupted_stamp or opening_prompt or explicitly_clears_previous"tests/test_a23_lane_start_read.pytests/test_lane_start_row_stamp.pytests/test_lane_start_claude_current.pytests/test_handoff_skill_80_85.pytests/test_triad_lane_tooling.pytests/test_triad_lane_tooling_handoff.pytests/test_repo_hygiene.py4031100)tests/test_a23_write_handoff.py(slice 2a's)4031100)The triad skips are
NEEDS_UPSTREAM, as before. Before the merge of 2a', hygiene'stest_the_root_carries_the_line_ending_rulefailed on every commit of this round for want of.gitattributes, which came with the code leg's front door (6314fc8) through 2a'. Not run on the bench, and asked of CI: the shell suite (tests/test_lane_helpers.sh, whose:3755and:3822move in this round), the whole oftests/test_supervised_restart_regressions.py, and the full suite.Red first, then green, then a killed mutant, for each item of this round:
e97ad3f)31990c4: no "only once this restart is confirmed ready"-k "refused_stamp or atomic_stamp or restart_owned"3 passed67e6da5)e97ad3f: noLANES_WORKSPACE_ROOT=in the respawntest_a23_lane_handoff4,80_85412bd3ea2)67e6da5: the stray case got W's words; the published pin passed-k "duplicate or launch_creates or fast_forwards"4,_read10fb4a7b0)c1f2928)fb4a7b0: 6 failed (the four record rows, theLANES_NO_GITrecord, the stamp's exit 6)-k "exit_6 or no_git"2; t018 as above439699f)c1f2928: theLANES_NO_GITrecord and an exit-5 row2e4d7dd)c1f2928: a moved handoff launched with no first prompttest_a23_lane_start15,_read10,test_a23_lane_handoff8,row_stamp3,claude_current34, supervised list 13e5c3326)test_a23_lane_start21,test_a23_lane_handoff1058309ba)e5c3326, before the merge: the sibling's file written, at both call sites615cfdd)5bf9bbb)e5c3326: the 8(d) file left uncommitted; on the merge: the old exit-0 wordsc12f078)Part 2's four commits were tested as one tree (11 cases passed at 16:12Z) and then made by re-running each item's edit script in order on the merge; the four commits' tree is that tested tree byte for byte.
Before this round, on the old root: run 39893128849 at
37b8806hadtestsat 3183 passed, 75 skipped, 1 failed andtests-no-submoduleat 2386 passed, 872 skipped, 1 failed, the failure in both being the runner image's knowntest_a_command_that_ignores_term_is_killed_after_the_grace[host].Lane openRepoTools-3's answers to this PR's four questions
refresh_workspace's fetch and merge take W's mutex (try once, a note if held), and that its stray scan be lock-free. The lock-free scan is 2a's 732 (A58), merged here; the mutex is for the flip.LANES_NO_GIT=1: named (decision 25), with one case per script.Not changed
lane-startreads it. That was CI's 141, and the contact point lane openRepoTools-3 named for 2b. The other early-stopping pipes are left for lane-start: a reader that stops early, under set -euo pipefail, can end lane-start with no message, or take the minted-transcript branch for a session it has recorded (the shape of #280) openRepoTools#281, which is unclaimed and waits for Brett's word. They are listed so that nobody reads them as done:lane-start:sed | head -n 1onworkspace.yaml;ld_row'sawk … exitonswapped's answer, unguarded;printf | grep -qxin anelif, where a SIGPIPE reads as "not in the cell";lrec_*reads, guarded by|| x="", so a SIGPIPE loses the verdict silently;lane-handoff: its own restart and record reads.handoff_digest_of'ssha256sum | awk '{print $1; exit}'is safe, because its writer's one line is complete before awk can act on it.LANES_ROUTE_WRITESstays opt-in, and its default is not flipped.lane-endkeeps slice 1a's register follow (slice 4, DRAFT Amendment 23 S6.2:lane-end --sweep-checkoutsremoves the register checkouts CLOSED lanes left under<W>-lanes/only where nothing holds them, leaves first, each decided under its lock after a fetch, and records them in a NOTED line (#198, slice 4) openRepoTools#308). The handoff skill still pulls and commits itself until slice 3.top_block, the PAUSED block's bytes, the supervisor, and every log, row and lifecycle write oflane-handoffare unchanged. So are the transcript reservation, the intent'sstartingwrite and 5e inlane-start.LANES_REPO=$WIPseam, as the plan accepted. CI passed them at84633df, and again withlane-handoff's change at37b8806(run 39893128849). Amendment 23's default-resolution behaviour is proven in the pytest modules above.Refs opensoft/openRepoTools#198
🤖 Generated with Claude Code
retired_word'sawk … exitover the row and over the published row (731), unguarded. It is safe in practice, since each is one short line. It joins the lane-start: a reader that stops early, under set -euo pipefail, can end lane-start with no message, or take the minted-transcript branch for a session it has recorded (the shape of #280) openRepoTools#281 list above.request-handoffwithoutLANES_LANE) and LH07 (the preparing bind's digestnone): they need a binding gate or restart plumbing no bench case reaches;write_lane_ofroutesrequest-handoffby its lane argument today;handoff-pathandwrite-handoffprint the same path;:3189pins it, in CI only;write-handoffcall, and its gap note namingwrite-handoff --prepend. Fit (c) is decision 31.write-handoff --prependcommand instead; the same change in lane-handoff's notes was not part of this round.docs/README-lanes.mdis unchanged. The manual's lines forlane-startandlane-handoffare slice 5's.Refs opensoft/openRepoTools#198
🤖 Generated with Claude Code