Repository navigation
Make lane-end's synopsis say what a DUPLICATE retire does, read a state cell that breaks the phrase's grammar whole instead of narrowing it, and correct the TAKEOVER grammar table and two tests.yml header comments - #202
Merged
Conversation
|
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 23 hours and 12 minutes by commenting |
Reviewer's GuideThis PR makes four precision corrections: it aligns lane-end help text with DUPLICATE retirement behavior, hardens malformed state-cell handling with fail-closed scanning and regression coverage, documents the missing lane TAKEOVER form, and updates tests workflow comments to reflect actual checkout and trigger behavior. Flow diagram for fail-closed lane-end state-cell scanningflowchart TD
A[Read register state cell] --> B{Valid phrase shape?}
B -->|Yes| C[Scan state word and phrase parts]
B -->|No: over cap, pipe, CR/LF, or wrong part count| D[Scan whole cell]
C --> E{Open LANDING detected?}
D --> E
E -->|Yes| F[Keep lane open]
E -->|No| G[Allow lane to end]
File-Level Changes
Assessment against linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
…a valid wide line is not held under a C locale, and run the boundary tests under C and UTF-8 (#90 part a) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ene rule spells it (#90 part a) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ich already makes #126 items 2 and 3 accurate Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…-8, and reads a count it cannot make as a line over the cap (#90 part a) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…he byte count for any other text (#90 part a) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…n iconv's exit status, which musl's does not set (#90 part a) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… rule) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…e-end's test must not print an integer-expression error (#90 part a) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 18, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This was referenced Oct 18, 2026
This was referenced Oct 19, 2026
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.



Three small precision fixes that lane openRepoTools-4 took over from lane openRepoTools-3 (TAKEOVER comments on each issue), and a note that #227 settled the fourth. The commits, oldest first:
d77504cthe proving tests,1a22dd7lane-end(#96 and #90 part a together),3296573the docs row,42a1085thetests.ymlcomments (superseded by #227, see below),2c5b3f2and748e0efthe first fix round (the review's character-count finding, then the hygiene rule onwc), the merge of origin/main with #227, the merge with #212, then the second fix round (03a60f9the tests for text that is not UTF-8 and for a failingwc,f2d559dthe validity check,ffcca3cthe validity check taken from aniconv -cround trip) and the merge with #216, #199 and #201. Brett Heap lifted the closeout direction for these follow-ups.#96 —
lane-end's synopsis said a DUPLICATE retire "ends nothing"Wrong: the top-level USAGE entry read
retire a live FORK (pid or uuid) or a DUPLICATE (pid); ends nothing. True of a FORK; false of a DUPLICATE HOLDER, whose retire TERMs the bg-pty-host pair (#39).--helpprints that synopsis.Fix:
lane-endlines 30-34. The entry is split in two: a FORK "writes nothing and kills nothing"; a DUPLICATE "TERMs a background holder's pair, only reports any other; the row is not written", matching the OPTIONS paragraph below it.Reconcile on landing: open PR #205 rewrites the duplicate-holder retire from "TERMs the pair" to "the bg-pty-host parent and every child". The synopsis here says "pair". The two PRs do not conflict textually, so git will not flag it: whichever of #202 and #205 lands second should reconcile the word.
Test:
tests/test_precision_90a_96.py::test_the_synopsis_says_what_a_duplicate_holder_retire_doesand::test_the_synopsis_keeps_the_fork_and_the_duplicate_on_their_own_linesread the USAGE block oflane-end --helpentry by entry, because the OPTIONS paragraph already says TERMs and a whole-help match would pass on main.Closes #96
#108 — the TAKEOVER grammar table omitted the
lane:formWrong: the table documented only
TAKEOVER ← <stale claim URL>; the prose at the stale-claim paragraph (and the code) also writeTAKEOVER ← lane:<dispossessed lane>.Fix:
docs/README-lanes.mdline 678, one row,issue or PR, worded like its neighbours (a kind and the verb with its payload). Docs only, so no test.Closes #108
#126 — nothing left to change here: #227 settled it
The branch first corrected two
tests.ymlheader comments (item 2 and item 3 of the issue; commit42a1085). Brett Heap's #227 ("run the test suite on Linux only") then rewrote that header and removedtests-windows,parse-macosandtests-macos, so the merge of origin/main takes main'stests.ymlwhole and this PR no longer touches it. Checked against main's new text:tests-no-submodule): main now reads "submodules: true,tests-no-submoduleexcepted: it checks outsubmodules: falseon purpose". Accurate.workflow_dispatchwas not named amongtests-macos's homes):tests-macosis gone. The newon:comment says "push(main only) and the nightlyschedulerun those same three jobs", andworkflow_dispatchruns them too. That is a smaller omission in ci: run the test suite on Linux only #227's own text, left alone here.AGENTS.mdlisted thepull_requestjobs wrongly): ci: run the test suite on Linux only #227 rewrote the rule; it now namesguard-launch-mode,testsandtests-no-submoduleand the four triggers, which is accurate.labeledandtests-macos'sif:): not added, and moot, since no job reads thereadylabel now and theif:is gone. ci: run the test suite on Linux only #227 deleted the macOS parse hygiene test, and added no replacement for the trigger text.AGENTS.mdandtests/test_repo_hygiene.pyare untouched by this PR.Refs #126 (items 2, 3: settled by #227, no change here)
#90 part (a) —
cell_for_scanskipped O1's grammarWrong:
lane-end's narrowed scan of a register state cell checked the STATE word, the UTC shape and the part count, but not ratified decision O1's other rules for the phrase's line (at most 240 characters, no|, no CR/LF). A cell whose third part broke one was narrowed to its state word, so an openLANDINGin that prose was never seen and the lane ENDED. That is the no-object-log fallback, the one path that still decides a merge hold from prose, and Rule 6 stops being enforced for it.Fix:
lane-endcell_for_scanand its comment (lines 1726-1789). The cap,|and CR/LF are checked beside the existing part-count test, and a cell that fails any of them is scanned whole, like a diary: fail-closed. Both call sites (this checkout's row and the published row on origin/main) share the function.The cap is 240 characters, and
${#x}is bytes under a C locale, socell_for_scancounts characters itself, the same in every locale: past 240, and only if the text is valid UTF-8, the count is redone with the continuation bytes taken out (tr -d '\200-\277' | wc -c | tr -d ' ', the padding striptest_no_shipped_bash_reaches_for_gnu_only_utilities_unaccompaniedasks for). Without that, a valid 240-character line of—and→read as past the cap underLC_ALL=Cand a lane merely waiting for a LANDING was held (the review's first finding). Text that is not valid UTF-8 keeps the byte count, which can only over-count: stray continuation bytes follow nothing and are no characters, and taking them out undercounted them, so a hand-edited non-UTF-8 cell of 241 bytes was accepted as 240 (the review's second finding). Validity is taken from aniconv -c -f UTF-8 -t UTF-8round trip (the text is UTF-8 when it comes back unchanged), not fromiconv's exit status: thebash:3.2image's musliconvexits 0 on invalid input, which the first version of the check trusted and so accepted all three cases there. A missingiconvor a failingwcreads as a line over the cap.set-row-statedoes not count characters in every locale either:lanes-edit.sh'srow_state_checkcounts bytes underLC_ALL=C, and a 240-character line of—/→is refused there as "720 characters". That is filed as #234 and not touched here.Tests (all but the controls fail on main, see below), each run under
LC_ALL=Cand a UTF-8 locale:tests/test_precision_90a_96.pytest_a_line_over_the_cap_cannot_hide_an_open_landing(a 241-character line endingLANDING #7)test_a_line_with_a_pipe_or_a_carriage_return_cannot_hide_an_open_landing(two cases)test_the_published_row_is_read_whole_when_it_is_not_the_phrasetest_a_wide_line_one_past_the_cap_cannot_hide_an_open_landing(241 characters of—/→)test_a_line_that_is_not_utf8_cannot_hide_an_open_landing(three cases: 241 stray\x80bytes, a 241-byte Latin-1 line with one°, and a valid 240-character line with one stray byte appended)test_a_count_that_cannot_be_made_is_a_line_over_the_cap(a stubwcthat fails on-c; the|| cfs_len=241fail-safe;Clocale only, since a UTF-8 locale never recounts a 240-character line)test_a_line_exactly_at_the_cap_is_still_prose(240 characters namingLANDING #7is a lane waiting, not a hold),test_a_wide_line_exactly_at_the_cap_is_still_prose(the same in—/→, about 680 bytes, which fails underLC_ALL=Cwith a byte count) andtest_a_line_over_the_cap_that_holds_nothing_still_ends.Each case runs a real
lane-endin the lane-start sandbox with a stublane-worktrees, so a cell wrongly read as clear is a lane that ENDS.Refs #90 (part a). Part (b),
lane-start's refused append, has an open question and is not touched.Not touched, and nearby writers
None of the off-limits files is touched (the installer,
tests/conftest.py,tests/run.sh,tests/test_repo_hygiene.py,AGENTS.md,specs/004-migrate-to-triad/**,lane-handoff,lane-worktrees,lane-end~200-215 and ~1971-2143,docs/README-lanes.mdpast ~3830). README.md and.github/workflows/tests.ymlare unchanged.Other writers in nearby spots, which these hunks do not overlap: lane openRepoTools-5 edits
docs/README-lanes.md~597 andlane-end~1107-1300 and ~1401-1449; another lane-4 writer editslane-end~711.Verification
All local runs under the shared pytest lock, with every
LANES_*andTMUX*unset, on 2026-10-18.Second fix round, red to green (
tests/test_precision_90a_96.py, 26 cases: eachlane-endcase runs underLC_ALL=Cand under a UTF-8 locale):lane-endput back to the first fix round's (27074e0: thetrrecount with no validity check): 6 failed, 19 passed, 1 skipped. The six aretest_a_line_that_is_not_utf8_cannot_hide_an_open_landing, its three inputs under both locales, eachassert 0 == 2:lane-endexited 0 and ENDED the lane over the open LANDING. The skip is the failing-wctest under the UTF-8 locale, which never reacheswc.tests/test_precision_90a_96.pywithtests/test_repo_hygiene.py(mainf5c3bcd's hygiene rules, including the bench-root path rule): 214 passed, 1 skipped, the same skip; the same 214 and 1 again on8ff52c2.wctest (test_a_count_that_cannot_be_made_is_a_line_over_the_cap,Clocale) pins the|| cfs_len=241fail-safe itself, red to green. A failingwcreads as a line over the cap either way, because without the||the count comes back empty and[ "" -le 240 ]is an error, which also reads as over the cap. That error is printed (lane-end: line 1771: [: : integer expression expected), so the test asserts"integer expression" not in result.stderr. Without the||: 1 failed, 1 skipped ([C], at that assertion). With it, in the green run above: passed. And with a failingwcread as a SHORT line (|| cfs_len=0) it goes red as well: 1 failed, 1 skipped (assert 0 == 2, the lane ENDED over the LANDING).bash 3.2: the extracted
cell_for_scanran on six cases (a valid 240-character line of—/→, a valid 241-character one, 241 stray\x80bytes, a 241-byte Latin-1 line with one°, a valid 240-character line with one stray byte, an ASCII 240) underLC_ALL=C,POSIXand UTF-8, with bash 5.2 on the host and with bash 3.2.57 in thebash:3.2image (musliconv): all six correct everywhere, narrowed only for the two 240-character valid lines. The first version of the check, which trustediconv's exit status, got all three invalid cases wrong in that image; that is why validity is aniconv -cround trip. Withiconvoff the PATH it fails closed (the valid wide line is held, the three invalid ones too).CI: head
ffcca3c, run 39086159056:tests,tests-no-submoduleandguard-launch-modegreen. Head45e81c4(the merge with mainf5c3bcd), run 39094650878:tests,tests-no-submoduleandguard-launch-modegreen. Head8ff52c2(the pinned assertion), run 39112708025: see the checks.Earlier rounds, for the record: main f87fd5a plus only the first test file gave 6 failed, 2 passed (the pipe and published-row cases fail as
assert 0 == 2, the lane ENDED over the open LANDING); the first fix round's byte-countinglane-endagainst the extended tests gave 1 failed, 17 passed (test_a_wide_line_exactly_at_the_cap_is_still_prose[C], exit 2 where 0 is right: the review's false hold), and 18 passed once fixed.CI's Linux
testsjob is the suite of record for everything else.🤖 Generated with Claude Code
Summary by Sourcery
Harden
lane-endstate-cell interpretation and clarify its retire synopsis while completing the TAKEOVER grammar documentation.Bug Fixes:
lane-endsynopsis so FORK and DUPLICATE HOLDER retire behavior is described accurately.Enhancements:
lane:<dispossessed lane>form of TAKEOVER state transitions.Documentation:
Tests:
wc, and published rows.