Repository navigation
lane and lane-handoff refuse empty and flag-shaped flag values, and lane-handoff renames the window only once the handoff can no longer be refused (#80 slices B and C) - #220
Merged
Conversation
…ane-handoff renames the window only once the handoff can no longer be refused (#80 slices B and C) Copilot's review of workBenches#91 found these against the vendored bytes, and each was still true at f87fd5a: - `lane --dir --all` took `--all` as the checkout (item 1), and `--force --dry-run` ran a real takeover whose why was `--dry-run`. The three spaced value arms now refuse a `-`-led value with 64 and name the `=` spelling. - `lane-handoff --lane=` and `--writers-file=` (items 6 and 8), and the other five `=` forms, took an empty value as no flag at all. One arm ahead of the seven now refuses it. Under them, the spaced form's refusal ran inside `$( )`, so it printed REFUSED and carried on: `--lane --restart` handed off the window's lane with exit 0. Every spaced arm now ends `|| exit`. - `have_tmux` answered for any tmux server, inside a client or not (item 10). It now requires `$TMUX`, as `lane`'s `tmux_here` does. - The window ref and id checks were prefix globs (item 3), so `s:1junk` and `@21junk` went into the append-only `window` sub-field. They are now whole-string matches, for tmux's answers and the launcher's fallbacks. - The window rename ran before the `--late` preconditions, the snapshot file, the row read and the `--restart` binding, and its failure was swallowed (items 2 and 11). It now runs after the last refusal and before the PAUSED record, and a refused rename is a refusal that names what had already landed. The suite's fake tmux gains `$FAKE_TMUX_RENAME_FAIL`. Slice A, the two fixes in skills/handoff/SKILL.md (items 4 and 7), is deferred. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideThis PR hardens File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
…I tests this PR on today's main Main moved 15 commits past this branch's base f87fd5a, through the suite's machinery and pin (.github/workflows/tests.yml, contracts/openreposhape-pin.yaml, tests/conftest.py, tests/test_repo_hygiene.py, upstream/openRepoShape), after this PR's last green run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…I tests this PR on today's main Main moved 4 commits past this branch's base 2cb14a9, through the suite's machinery and pin (), after this PR's last green run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
brettheap
added a commit
that referenced
this pull request
Oct 18, 2026
…ane holds the object (#74) (#204) Landed on Brett Heap's word "land #204 #206 #208 #218 #220 #221 when green" (2026-10-18), by lane openRepoTools-5. Required Linux CI (guard-launch-mode, tests, tests-no-submodule; run 39137725493) was green on head af5b7ce with main 586dea2 in its tree. Independent review (lane 5, Opus, of 4996156; the merges of main add nothing to the PR's diff): LAND. Closes #74 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brettheap
added a commit
that referenced
this pull request
Oct 18, 2026
…so a migrated PAUSED row stops showing NO LOG (#89) (#206) Landed on Brett Heap's word "land #204 #206 #208 #218 #220 #221 when green" (2026-10-18), by lane openRepoTools-5. Required Linux CI (guard-launch-mode, tests, tests-no-submodule; run 39137733527) was green on head cd3ced0 with main 586dea2 in its tree. Main 0a49697 merged with head cd3ced0 is tree f88c2f1, which queue run 39137981522 (workflow_dispatch of tests on 3f5f4b9) tested whole and green. Independent review (lane 5, Opus, of 00b75e6; the merges of main add nothing to the PR's diff): LAND. Brett Heap confirmed the unpickable (row) lanes as built (2026-10-18). Closes #89 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brettheap
added a commit
that referenced
this pull request
Oct 18, 2026
…or binding log instead of guessing a branch (#60) (#208) Landed on Brett Heap's word "land #204 #206 #208 #218 #220 #221 when green" (2026-10-18), by lane openRepoTools-5. Required Linux CI (guard-launch-mode, tests, tests-no-submodule; run 39137741203) was green on head 3edaf0a with main 586dea2 in its tree. Main be82c20 merged with head 3edaf0a is tree cfd2ee6, which queue run 39137988005 (workflow_dispatch of tests on 9db4863) tested whole and green. Independent review (lane 5, Opus, of c252a3c; the merges of main add nothing to the PR's diff): LAND. Closes #60 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brettheap
added a commit
that referenced
this pull request
Oct 18, 2026
…s why refuse it before writing, and the deferred lane-start command keeps --agent (#85, #72 items 5, 6) (#218) Landed on Brett Heap's word "land #204 #206 #208 #218 #220 #221 when green" (2026-10-18), by lane openRepoTools-5. Required Linux CI (guard-launch-mode, tests, tests-no-submodule; run 39137747959) was green on head bfc5ddd with main 586dea2 in its tree. Main fca60f5 merged with head bfc5ddd is tree b188309, which queue run 39137992777 (workflow_dispatch of tests on 586df3b) tested whole and green. Independent review (lane 5, Opus, of 99f3853; the merges of main add nothing to the PR's diff): LAND. Brett Heap confirmed refusing CR/LF at the door (2026-10-18). Part of #85. Part of #72 (items 5-6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brettheap
marked this pull request as ready for review
October 18, 2026 15:59
|
Sorry @brettheap, you've used your own review budget of 250,000 diff characters for the last 7 days. You can request another review in 1 day and 9 hours by commenting |
brettheap
added a commit
that referenced
this pull request
Oct 18, 2026
…ession ids, so the dead-lane --force check and duplicate-holder fail closed (#67) (#221) Landed on Brett Heap's word "land #204 #206 #208 #218 #220 #221 when green" (2026-10-18), by lane openRepoTools-5. Required Linux CI (guard-launch-mode, tests, tests-no-submodule; run 39137764839) was green on head 14696c7 with main 586dea2 in its tree. Main be0743b merged with head 14696c7 is tree 0052eff, which queue run 39138003629 (workflow_dispatch of tests on 147cbf6) tested whole and green. Independent review (lane 5, Opus, of fbd2bb1; the merges of main add nothing to the PR's diff): LAND. Closes #67 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brettheap
pushed a commit
that referenced
this pull request
Oct 18, 2026
… this PR on today's main One conflict, in tests/test_lane_helpers.sh, in the FAKE TMUX header: #220's paragraph on FAKE_TMUX_RENAME_FAIL (its code is the rename-window arm below, which merged cleanly) and this PR's FAKE_TMUX_SILENT paragraph and block both insert directly before `case "${1-}" in`. Resolved as #220's independent review asked: #220's FAKE_TMUX_RENAME_FAIL comment first, then a `#` separator, then this PR's FAKE_TMUX_SILENT comment and block, both before the `case`. They do not interact: the silent-server exit answers before any arm runs, and the rename refusal lives in the rename-window arm. Every line of both sides is kept. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Part of #80: slices B (flag values) and C (tmux and the window). Slice A, the two fixes to
skills/handoff/SKILL.md(items 4 and 7), is deferred and remains open. Details under Remaining.What was wrong
These are Copilot's findings on workBenches#91 against the vendored bytes. I checked each one at
f87fd5aby running the new cases against that commit's code; the results are quoted below.lane:215. Inlane --dir --all,--dirtakes--allas its value. At f87fd5a this exits 0 with a checkout called--all, so the "every repository" listing the person asked for never runs.--force --dry-runhas the same flaw:--dry-runbecomes the why of a real takeover, and that why is written into another place's append-only log.lane-handoff:242and:248.--lane=and--writers-file=accept an empty value. So do the other five=forms:--operation=,--at=,--agent=,--transcript=and--dir=. At f87fd5a all seven exit 0.x="$(flag_value …)", and adieinside$( )only exits that subshell. The command printsREFUSEDand then carries on with the value empty. At f87fd5a,lane-handoff --lane --restart clearexits 0 after this:--restarthad been consumed.--writers-file ""also exits 0, and writes a handoff with no briefs.lane-handoff:351.have_tmuxchecks only for the binary. Run from a shell outside tmux (env -u TMUX), f87fd5a renames the window and recordswindow hfsess:0 @21, both read from whatever client the tmux server last saw.lane-handoff:434.*:[0-9]*and@[0-9]*are prefix globs. At f87fd5a, the append-only log takeswindow hfsess:1junk @21junkwhen the values come from tmux, andwindow hfsess:7junk @77junkwhen they come from the launcher's environment.lane-handoff:519. The rename ran before every remaining refusal: the--latepreconditions, the writers' snapshotmktemp, the row read (sread register-row) and the--restartbinding. Two of those refusals say "nothing was renamed". At f87fd5a a refused--laterenames the window first (rename-window repoHF-7is logged: before 1, after 2). A failed rename was also swallowed. With the fake tmux refusing the rename, f87fd5a exits 0 and writes the PAUSED record and the row anyway.Already fixed on main (no change here):
tests/test_lane_helpers.shruns$HANDOFF_CMD(38 invocations at f87fd5a).lanes-edit.sh publish-handoffstages the new handoff withmktemp "$pbh_target.resume.XXXXXX"in the target's own directory and installs it withmv -f, after resolving the symlink (landed in Keep supervised manual ctx as legacy compatibility and refuse managed lanes #121).lane-handoffwrites the handoff through it.What changed
lane: a newnot_a_flaghelper. The spaced--dir,--forceand--waitarms now refuse a value that starts with-, exit 64, and name the=spelling (--dir=--all). Empty=values were already refused at each arm.lane-handoffparser:=*arms, refuses--operation= | --at= | --lane= | --agent= | --transcript= | --writers-file= | --dir=with exit 2. Becausecasetakes the first match, the=*arms still accept a value that starts with-. For example,--lane=-xstill reaches the lane-name check.|| exit, soflag_value's refusal ends the command and keeps its own exit status.lane-handoffonly, in the seven spaced arms (--operation,--at,--lane,--agent,--transcript,--writers-file,--dir). At f87fd5a,lane-handoff --laneprintedREFUSEDfrom inside$( ), then ranshift 2with one argument left. Thatshiftfails and consumes nothing, so the loop never ended and printedREFUSEDon every pass. At this head the same command exits 2, with oneREFUSED.lanenever had the loop: its spaced--force,--waitand--dirarmsdiein the main shell and exit 64.have_tmux: now also requires$TMUX, the same test aslane'stmux_here. The header's environment line says so.window_ref_ok(^.+:[0-9]+$) andwindow_id_ok(^@[0-9]+$) are written in POSIXcase, the waylane-startwrites its id check. They are applied to the live tmux values and to theWORKBENCHES_CLAUDE_WINDOW_REF/_IDfallbacks.--restartbinding), and before section 4, where the PAUSED record is built and written.--latestill renames, just before its own PAUSED, as it did before.Functions and regions edited
At head
9f6fd2d, as old-line to new-line ranges against f87fd5a:lane: newnot_a_flag()(new 228-245, aftertake_arg). The argument loop's--force,--waitand--dirspaced arms (old 236, 238, 240).lane-handoff: header exit-code and env comments (old 105, 111).lane-handoff: comment aboveflag_value()(after old 243).lane-handoff: argument loop. New empty-=arm after--restart-status, and|| exiton the spaced arms at old 276-288. Old 289 (--dir=*) and the--)/*)whyarms at old 290-292 are untouched; A one-line record can't take a newline: append-line and lane-handoff's why refuse it before writing, and the deferred lane-start command keeps --agent (#85, #72 items 5, 6) #218 (append-lineproves its one line AFTER writing it, so alane-handoff --whycarrying a newline corrupts LANES.md and leaves the checkout dirty #85/Ten hardenings Copilot rounds 4–6 raised on #47, filed rather than taken: the test lock's ownership, three signal/status gates, a deferred command that drops --agent, and the handoff skill catching up with its command #72) edits those.lane-handoff:have_tmux()and its comment (old 408-411).lane-handoff: newwindow_ref_ok()/window_id_ok()and the four checks in the identity-triple block (old 1551-1564).lane-handoff: removed the rename block (old 1817-1825) and left a 4-line pointer.lane-handoff: new section 3a with the rename, inserted after old 2147. That is between the handoff commit block and section 4's header. Old 2148-2152 sit between it andsanitize(old 2153), which A one-line record can't take a newline: append-line and lane-handoff's why refuse it before writing, and the deferred lane-start command keeps --agent (#85, #72 items 5, 6) #218 edits.tests/test_lane_helpers.sh: the shared fake tmux. A header note (after old 299) and theFAKE_TMUX_RENAME_FAILhook inrename-window(after old 355).tests/test_lane_helpers.sh: thelanesection, after the--led-name fence cases (after old 5929).tests/test_lane_helpers.sh: the Amendment 17 section, new parts 3b and 3c after the--latecases (after old 9787). They add lanesrepoHF-80…repoHF-83.Conflict checks: I ran
git merge-tree --write-treeof this head against every open PR head, #195-#218. All merge clean, including #218 (#85/#72, thewhy/sanitizeedits). Lane 3'sfeat/triad-lane-toolingandfeat/triad-lane-tooling-handoffalso merge clean. Their nearest hunks are at old 1894, 1974-1996, 2057, 2217 and 2339. The removed block (old 1817-1825) and the new 3a (after old 2147) are 69 or more lines from any of them.Tests
New cases in
tests/test_lane_helpers.sh:lanesection:lane --dir --allgives 64 with the--dir=--allhint.--force --dry-runand--wait --switchgive 64 in the same words. None of the three launches anything.=forms give 2, each with its own flag named.--lane --restartgives 2 with exactly oneREFUSEDand no lane resolved after it.--writers-file ""gives 2 and never reaches the poll.--lane=-repoHF-4still reaches the lane-name check.--laterenames nothing.FAKE_TMUX_RENAME_FAIL=1the result is 2, with tmux's words and thetmux rename-windowact, the rename attempted once, no PAUSED and no row flip. A plain re-run then gives 0, renames, and writes one PAUSED and flips the row.env -u TMUX, the handoff gives 0, renames nothing, and records nowindow.; window hfsess:7 @77;).windowsub-field.Fail-before and pass-after, locally and in isolation. Per the lane's rule, I did not run the full suite locally. I built a trimmed copy of the new
tests/test_lane_helpers.sh, containing the global setup, thelanefence cases and the whole Amendment 17 section up to its launcher table, plus the footer. I ran it underenv -i HOME PATH LANG USERin two scratch trees that carry the same test file:git archive f87fd5aand this head's files.161 passed, 41 failed. All 40 new-case failures are the defects above.201 passed, 1 failedThe single failure in both runs is an existing assertion that reads
repoSW-1, a fixture seeded in a section the trim leaves out. It is not in a section this PR touches.I tried to run the
tests/test_supervised_restart_regressions.pycases that drivelane-handoff --restartthroughtests/run.sh … -k …. The wrapper waited out its 590-second bound on another lane's live pytest run, so those are left to CI, the suite of record.bash -npasses onlane,lane-handoffandtests/test_lane_helpers.sh. Every construct used is bash 3.2-safe:case,${x%=},${x##*:}andif ! v="$(…)".Remaining
This is not a full fix for #80. Slice A is still open:
skills/handoff/SKILL.md's fenced block, at about lines 454-456.<sanitized verbatim>/<what's open…>placeholders in that block's record writes, at about lines 547-552.It is deferred because other writers are editing
SKILL.mdin that range.🤖 Generated with Claude Code
Summary by Sourcery
Harden lane and lane-handoff argument and tmux handling so refused handoffs do not cause unintended changes or record inconsistent state.
Bug Fixes:
Enhancements:
Tests: