Skip to content

T017: Where a lane's log or register cannot be read, a named worktree read is UNREAD, not none, the listing says what is missing, a writer is unknown, not 0, and lane-state exits 10, not 8 (opensoft/openRepoTools#290) (part of opensoft/openRepoTools#186) - #7

Merged
brettheap merged 1 commit into
mainfrom
fix/named-read-none-290
Nov 8, 2026

Conversation

@brettheap

@brettheap brettheap commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

What this is

This is the T017 continuation, in this leg (opensoft/openRepoTools-code), of the opensoft/openRepoTools branch fix/named-read-none-290 at b99f904e15b8, for opensoft/openRepoTools#290 (part of opensoft/openRepoTools#186). The original tree and branch stay as the archived original (lane 4's decision, opensoft/openRepoTools#186 comment 6548343086). One commit here, 2c15aa6613c3, carries it.

It carries that branch's own change against 50d05d4, with its merge of main 50d05d4 (db5d564) left out, for the code leg's paths: lanes-edit.sh (+233 −30), lanes-index (+22 −2), tests/test_lanes_index.py (+1) and the new tests/test_named_read_unreadable_290.py (+569). Its one other path, docs/README-lanes.md (+31 −8), is the spec leg's, in the paired PR. lane-start, lane-handoff and lanes have no diff.

What was wrong and what changed

What was wrong

Where a lane's log, or the register its name is resolved by, could not be read, six reads answered as if there were nothing to read. A named worktrees <lane> said none (8), a name typed in another case said none, a tree's writer read 0, the lanes listing said nothing of a list of the logs it could not make, one log file that would not open dropped every log after it when there was no origin, and lanes-index read a failed lane-state as generation 0.

Found by the independent review of opensoft/openRepoTools#289 as its SHOULD-3, together with four items opensoft/openRepoTools#289's writer found and left alone and a NIT from opensoft/openRepoTools#289's delta review r3 (NIT-A). All of them exist at main before opensoft/openRepoTools#289. opensoft/openRepoTools#289 made the whole listing (worktrees --all, the read the inventory index syncs from) refuse a partial read with a PARTIAL line; the reads below are outside that, and each still took a read that failed for an answer (R22, Amendment 7(d)).

  1. A named read answered "none" over a log it could not read. worktrees <lane> found the lane's trees under the root its log's dir places, and the listing threw away a failed git show of that log: no dir, the third rung, no trees there, and exit 8 with no warning. lanes --worktrees <lane> said "no worktree is inventoried for lane X". (Review SHOULD-3, probe P4.)
  2. With the register unreadable, a name typed in another case said "none". It resolved as typed, found no root, and answered 8.
  3. A tree's writer read 0, "nobody is writing there", where the register's ids, or the lane's log (its binding), were never read.
  4. The lanes listing said nothing where the list of the logs could not be made, so a lane with a log and no register row was missing from it. An empty listing over a register, an archive and a list of the logs that could not be read said "no lane is recorded" (exit 8).
  5. With no origin, one log file that would not open left no warning, and mawk (Debian's and Ubuntu's awk) ends at the first file it cannot open, so every log after it was dropped too.
  6. lanes-index read a failed read of a lane's log in lane-state as generation 0 (exit 8). A sync held the lane's rows for "its generation reads 0": the right outcome for the wrong reason (NIT-A). A reconcile said the generation "went back from 1 to 0", and removed the rows.

What changed

All in lanes-edit.sh unless said.

  • A checked read of a lane's log (lane_log_events <lane> checked). It says whether the read happened. A published log that origin's tree names and git could not show is 1, and so is a tree that could not be listed to ask; a path the tree does not name is still no log, 0. With no origin, a log directory that is there and cannot be searched is 1, and so is a log file that is there and will not open. Without checked the status is the parser's, as before.
  • The named read (worktrees <lane>) reads its lane's log once, with that status, and hands the read to the listing, so the row and the root its trees are found under come from one read. Where it failed and no LANES_LANE_STATE_ROOT names the root, the answer is one UNREAD line naming the log, with exit 0, never the 8 of "none". lanes --worktrees <lane> prints it as inventory NOT READ. A lane with a register row and no published log still answers none: a log that is not there is not one that could not be read.
  • The register behind the name. worktrees asks the register (register_text_checked) before canon_lane resolves the name by it; a read that succeeds is the cached text both take, and one that fails is not kept. Where it failed and no tree is found under the name as typed, the answer is one UNREAD line naming the register.
  • A tree's writer is 0 only where that was established. writer_live is empty, unknown, where the register's ids were not read, and it is empty whatever a live record says where the lane's log, which holds its binding, was not read, as it already was for a lane bound elsewhere. A live record that names one of the ids that were read is still 1 where the lane's log was read. This holds for the named and the whole read.
  • The lanes listing says what it could not read. Where the list of the published logs could not be made, it says that a lane with a log and no row in the register or the archive is missing. Where the events' own list could not be made, it says that no lane's log is read in it and classes no row DORMANT. A listing that names no lane where the register, the archive or the list of the logs could not be read exits 1, the listing could not be read, and no longer 8; lanes refuses on it.
  • With no origin, each log file is parsed on its own. A file that will not open is named in the read's warnings, the logs after it are still read, and worktrees --all reports PARTIAL over it.
  • lane-state reads the lane's dir once, with its status, when no LANES_LANE_STATE_ROOT names the root, and hands it on as the payload the root is found by. It hands it on quoted where it holds a space and bare where it does not, the rule lane-start's quote_subfield writes it by, so a dir with a space and a dir with a quote mark both come back whole (ruling 3 below). Where the log could not be read it exits 10 with its own sentence, which says that this is not "no snapshot" (8), never the 8 that lanes-index took for generation 0. lanes-index holds such a lane's rows for that reason, in a sync and in a reconcile, and gives lane-state's own first sentence as the why, and drops the trailing lanes-edit: (exit N) line that die adds under LANES_DEBUG. A reconcile used to remove the rows; the review accepted the change, because holding is what both acts already do over a snapshot that cannot be read, and only a transient failure reaches it, since a persistent one makes the whole listing PARTIAL first.
  • The contract comments in lanes-edit.sh, lanes-index (+22 −2) and tests/test_lanes_index.py (+1, one assertion that a lane's dir is not read again) say the same. The manual's matching text is the paired spec PR's.

Unchanged: a lane with a register row and no published log still says none, a readable log with no trees is still 8, and lane-trees still answers 8 over a log it cannot show (opensoft/openRepoTools#303).

Brett Heap's rulings, in lane 4's window: (1) on 2026-10-21, logged at 15:41:06Z ("yes as recommended"): every read of a lane's log should report whether it happened, which changes what lane-start and the handoff are told, so it is a separate v1.2.0 issue, opensoft/openRepoTools#303 (it also covers lane-trees answering none over an unreadable log, and, with no origin, a log directory that can be listed but not searched dropping log-only lanes from lanes); lane_log_events without checked is left as it was; and a named read whose register check failed answers UNREAD, not none, where it finds no tree. (2) On 2026-10-22, logged at 12:04:14Z ("yes as recommended"): the two lane-name problems the review found are opensoft/openRepoTools#310. (3) The rule lane-state follows was ruled for opensoft/openRepoTools#295: on 2026-10-21, logged at 13:43:54Z, yes, quote only where a space is for #295 (his words, byte for byte); it applies to lane-state for the same reason, because payload_subfield ends a quoted value at its first ".

Not in this PR

Old to new: the receipt

The original's own non-merge commits in opensoft/openRepoTools (50d05d4..b99f904), 11 in all, are carried by one commit in this leg, 2c15aa6613c3. The list is the commit's own body, and it equals the original's non-merge commits read from the chain's refs/root/ ref (checked).

b4b0355fd081 Add the tests that a read which could not be made never answers none: the named worktree read, the lanes listing, the no-origin log read and lanes-index's generation read (#290)
286e82197e9a Add the guards a fix for the named read needs: one read of the lane's log, no writer over a binding nobody read, no DORMANT class over a log list that failed, and lane-state's 10 naming the snapshot it found (#290)
f14efed183bd WIP: A named worktree read says NOT READ where its lane's log or the register its name is resolved by could not be read, the lanes listing says a log list it could not make, and lane-state is 10 over a log it could not read (#290) - written, not yet run green
4b1031d78337 The guard for a lane with no published log asks with no control-root override, as a workstation does, so a read that took "no such log" for "could not be read" now fails it (#290)
41ca9cb19683 A named read whose lane's log tree cannot be listed is pinned as an UNREAD line, so the ls-tree that tells an unreadable log from an absent one is tested (#290)
e5069fe5e236 The lanes contract, both exit-code tables and the manual's list of reads that fail closed now name what #290 changed: the listing's 1, lane-state's 10 over a log it could not read, and the events' list of the logs (#290)
a2b52ed1c8a5 The comment over the inventory read's own two log-list reads no longer says known_lanes answers 0 either way: its published list answers 1 where it could not be made (#290)
da187ba448d5 The hold lanes-index makes over lane-state's 10 gives lane-state's own sentence with LANES_DEBUG set, not the "(exit 10)" line die adds after it (#290)
9c0aae54978e Add the test that lane-state finds a lane's snapshot by the whole dir its log records, bare with a quote mark in it as on main, and quoted with a space in it (#290)
bc825a4bf326 lane-state hands the dir it read on quoted only where it holds a space, as lane-start writes it, so a bare dir with a quote mark in it finds its snapshot as on main (#290)
b99f904e15b8 The lane-state dir test now pins a bare dir holding a TAB and a quote mark, read whole as on main, so the rule stays a space and not any whitespace (#290)

The subjects are the original's, byte for byte; a bare (#N) in them names the root issue. f14efed183bd is a WIP checkpoint whose subject says "written, not yet run green"; it is the original's own commit, listed as it was written, and this commit carries the final state that the later commits turned green.

Resolutions

git apply --3way left five conflict blocks, four in lanes-edit.sh and one in lanes-index; tests/test_lanes_index.py applied at an offset of 6 lines.

  1. lanes-edit.sh, the file's exit-code header for 10: A named worktree read answers "none" for a lane whose log or register could not be read (from #289's review) openRepoTools#290's sentence, then A lane control root that cannot be searched reads as "no trees", so an inventory sync removes its rows (from #289's review) openRepoTools#291's, each kept word for word; the "Both" that opened A lane control root that cannot be searched reads as "no trees", so an inventory sync removes its rows (from #289's review) openRepoTools#291's moves to the end of A named worktree read answers "none" for a lane whose log or register could not be read (from #289's review) openRepoTools#290's last line.
  2. lanes-edit.sh, worktree_rows' hand-off of the dir: Three ways a stored lane sub-field is misread: a TAB in a recorded dir drops the lane from worktrees --all, payload_subfield expands backslash escapes through awk -v, and request-handoff writes its by host sub-field unquoted openRepoTools#301's decode, then A lane whose recorded dir has a space is missing from worktrees --all and the inventory index: worktree_rows hands lane_control_root the dir unquoted, and payload_subfield cuts it at the first space openRepoTools#295's quote case, then A named worktree read answers "none" for a lane whose log or register could not be read (from #289's review) openRepoTools#290's UNREAD block, as the root's ORDER.md section 6 sets it (lane 3, comment 6368074244 on Three ways a stored lane sub-field is misread: a TAB in a recorded dir drops the lane from worktrees --all, payload_subfield expands backslash escapes through awk -v, and request-handoff writes its by host sub-field unquoted openRepoTools#301).
  3. lanes-edit.sh, the lane-state exit-code comment for 10: A named worktree read answers "none" for a lane whose log or register could not be read (from #289's review) openRepoTools#290's sentence, then A lane control root that cannot be searched reads as "no trees", so an inventory sync removes its rows (from #289's review) openRepoTools#291's, each kept word for word; the "And so is a" that opened A lane control root that cannot be searched reads as "no trees", so an inventory sync removes its rows (from #289's review) openRepoTools#291's moves to the end of A named worktree read answers "none" for a lane whose log or register could not be read (from #289's review) openRepoTools#290's last line.
  4. lanes-edit.sh, lane-state's 10) case: A lane control root that cannot be searched reads as "no trees", so an inventory sync removes its rows (from #289's review) openRepoTools#291's comment and its lookup_blocked die, with A named worktree read answers "none" for a lane whose log or register could not be read (from #289's review) openRepoTools#290's lane_control_root "$lane" "$lst_pay", as the A named worktree read answers "none" for a lane whose log or register could not be read (from #289's review) openRepoTools#290 and A lane control root that cannot be searched reads as "no trees", so an inventory sync removes its rows (from #289's review) openRepoTools#291 drafts' landing notes set it.
  5. lanes-index, lane_generation's docstring: A named worktree read answers "none" for a lane whose log or register could not be read (from #289's review) openRepoTools#290's whole; its first line already drops the "is there" that A lane control root that cannot be searched reads as "no trees", so an inventory sync removes its rows (from #289's review) openRepoTools#291's b0a631b took out.

The pairing

The manual's part of this change (docs/README-lanes.md, +31 −8 (here +31 −7)) is the commit 430ea20784ac on fix/named-read-none-290 in opensoft/openRepoTools-spec, its own PR, opensoft/openRepoTools-spec#10 (base fix/pathless-tree-record-302). The code leg's checks read the manual through OPENREPOTOOLS_SPEC_ROOT: tests/test_repo_hygiene.py reads docs/README-lanes.md (call sites at lines 1373, 1404, 1423, 3139 and 3572 of the code leg's main; 1404 is the tuple of surfaces that a loop reads through doc()) and tests/test_test_roots.py pins which manual a run reads. The code leg's own CI (OPENREPOTOOLS_COMPOSED: '0', no spec leg beside the checkout) skips those checks, so they bind only in a composed run or with the variable set to a spec clone. A search of the manual lines this change touches for the strings those checks pin (the rung-count heading, the two settlement quotes, every lane on this workstation, the exit-code section's two markers and lane-end <lane> --retire) finds none: read, not run. So the two PRs are one change in two repositories, and they land together, as a pair. The code PR goes first, so that the manual never describes behaviour the code lacks: this PR first, then its spec PR, opensoft/openRepoTools-spec#10. The state that order passes through, the code chain's tip beside the spec leg's main, passed -k test_repo_hygiene in the independent review (run (e) under Tests: 223 passed, 14 skipped; that run read the chains' tips, not this commit alone). The other order's state, the spec tip beside the code leg's main, was not run. I found no check that turns either order red; that is a reading, not a run.

Tests

Run by the CODE writer, in a sandbox clone, with env -i (HOME, XDG_* and TMPDIR inside the sandbox), OPENREPOTOOLS_CODE_ROOT set and OPENREPOTOOLS_COMPOSED=0, as the leg's CI sets it. Each targeted run read this branch's own commit in its own worktree; that commit was 5f2995d43893 before the message amend, and the amend kept its tree, so the results stand for 2c15aa6613c3.

run exit result time
bash -n on lanes-edit.sh, lane and lanes, at every commit of the chain 0 all ok -
py_compile on every changed .py file and on lanes-index 0 all ok -
run.sh -k "test_named_read_unreadable_290 or test_lanes_index" 0 120 passed (22 + 98, split inferred) 479.24 s

shellcheck, over the whole chain (main to the tip): errors 0 to 0 and warnings 108 to 108 (lane 14 to 14, lanes 8 to 8); notes up by 3, 2 and 2, all SC1003 on the literal '\' patterns of opensoft/openRepoTools#301's commit.

The pair runs below are of the two chains' tips. This commit is the code chain's tip, so they ran at this commit, with the spec chain's tip beside it. They are lane 4's independent paired review, 2026-10-31 (the letters are the review report's own), with OPENREPOTOOLS_SPEC_ROOT set to the spec clone shown, env -i, TMPDIR=/tmp and a 54-character XDG_STATE_HOME.

run code + spec exit counts time
(a) -k test_repo_hygiene code tip 5f2995d43893 + spec tip 8104f2cf965c 0 223 passed, 14 skipped, 2944 deselected 11.1 s (33 s wall)
(b) -k test_repo_hygiene, baseline code main 2a057a6 + spec main 9f8b21a 0 223 passed, 14 skipped, 2772 deselected 9.2 s (10 s wall)
(c) -k lane_helpers code tip + spec tip 0 42 passed, 6 skipped; 0 FAIL in the shell suite (the wrapper asserts " passed, 0 failed"), with a 54-character state root 2188.6 s (36:28)
(e) -k test_repo_hygiene code tip 5f2995d43893 + spec main 9f8b21a 0 223 passed, 14 skipped 5.5 s

The pair runs read the chains' tips as they were before the message amend (code 5f2995d43893, spec 8104f2cf965c). The amend kept every tree (git diff from each old commit to its new one is empty), so the runs stand for the amended tips, code 2c15aa6613c3 and spec 430ea20784ac. No failure is new at the tips. Run (d), the manual-reading tests at each branch, was skipped under the review's brief, because none of the five branches' test files reads the manual.

The CODE writer's first run of -k lane_helpers at the chain's tip, with a 212-character run root, gave 5 FAILs in the shell suite (4870 ok, 5 FAIL, 3 skipped), because rc_tree_id in tests/test_lane_helpers.sh lacks the 180-character cap that tree_id_for in lanes-edit.sh has, so at that length the two names differ and the planted records are never read; the chain changes neither, and run (c) above, with the 54-character state root, gave 0 FAIL.

Not run: the suite at the leg's main for comparison, bash 3.2, macOS and the assembly's composed check; the submodule was not initialized, so 6 tests skip.

Test files this commit adds or changes:

  • tests/test_named_read_unreadable_290.py, new (+569): 22 cases from 17 test functions at the root head, on test_lanes_index's own estate. A named read whose published log could not be read, or whose log tree could not be listed, is one UNREAD line and not none, run without the fixture's LANES_LANE_STATE_ROOT; with no origin, a log directory at mode 000 or 400 and a log file at 000 say so; a lane with a row and no published log still says none; the register unreadable, a name typed in another case never says none; a tree's writer is not pronounced where its lane's log was not read; the lanes listing says when the list of the logs could not be made; an unreadable log file is said and drops no other; a lane-state whose log failed holds the lane in a sync and a reconcile, with and without LANES_DEBUG; and lane-state's hand-off of the dir, three ids (quote-mark, space and tab-and-quote).
  • tests/test_lanes_index.py, changed (+1): one assertion, that a lane's dir is not read again.

The original's own record, from the root repository, at the root heads and not repeated in this leg: red on main's code (11 failed, 2 passed, the two passes being what must not change); 259 passed, 2772 deselected for -k "test_named_read_unreadable_290 or repo_hygiene" at b99f904's bytes; 31 mutants of the fix, each killed by an assertion in these cases (28 of the named-read fix, three of the quoting rule, run through tests/run.sh).

Release notes (v1.2.0)

Not established: whether lane 3 accepts this line, which it has not seen. No release-notes line was ever recorded for this PR; the line below comes from the checkpoint of the root drafts.

A named worktrees <lane> read says UNREAD where the lane's log or the register could not be read, instead of none. The lanes listing says what it could not read and exits 1 where it names no lane for that reason, a tree's writer is unknown instead of 0 where the lane's binding was not read, and lane-state exits 10, not 8, over a log it could not read, so lanes-index holds that lane's rows. (opensoft/openRepoTools#290)

The line is here, in the code PR of the pair, and only here: the paired spec PR, opensoft/openRepoTools-spec#10, repeats none.

Review

READY, lane 4's independent paired review of both chains, 2026-10-31. It found no MUST and no SHOULD against the commits, and three NITs. Report sha256: 4ac9e5441affc6aeac48e6d73419580f6786440dc0e5dd32722cc40b8070a682. The review read the chains before the message amend (tips 5f2995d43893 and 8104f2cf965c, the same trees as the amended tips).

The original's recorded review, from the root repository (no lane 3 review comment exists for it): an independent review of db5d564, by an Opus reviewer that wrote none of the code, is LAND, with no MUST; all seven items fail closed in the code. Its fix round was checked by a second read (DELTA OK): SHOULD-1 (two edges of the checked read pinned by no test: 4b1031d, 41ca9cb), N1 (the contract comment, the exit-code table's row for 10 and the list of reads that fail closed: e5069fe), N2 (a2b52ed) and N3 (da187ba) fixed, N4 shown by a mutant, and N5, the lanes footer's wording, fixed on opensoft/openRepoTools#291's branch. A later quoting fix (9c0aae5, bc825a4, b99f904) was found after the review and delta-reviewed by another Opus reviewer: LAND, no MUST and no SHOULD, five NITs, none needing action before landing. The root's CI run 39863631490 at b99f904 was green on all four jobs.

Landing

It lands only on Brett Heap's word, PR by PR; nothing in this text is a landing.

Lane: openRepoTools-4
Claim: opensoft/openRepoTools#290 (comment 6313867435)

🤖 Generated with Claude Code

Summary by Sourcery

Distinguish unreadable lane metadata from genuinely absent data across worktree reads, lane listings, and lane-state synchronization.

New Features:

  • Report unreadable lane logs and registers explicitly in named worktree reads instead of treating them as empty inventories.
  • Preserve unknown writer status when the register or lane binding cannot be read.
  • Report incomplete lane listings and unreadable log files, including partial-read diagnostics.
  • Return a distinct lane-state failure for unreadable logs so lanes-index can hold affected rows safely.

Bug Fixes:

  • Prevent unreadable logs from being mistaken for missing logs, generation zero, or no recorded lanes.
  • Ensure later log files are still processed when an earlier log cannot be opened.
  • Preserve lane snapshot directory values across quoting cases, including spaces and embedded quote or tab characters.

Enhancements:

  • Read named lane logs once and reuse the result consistently across inventory and worktree resolution.
  • Expand regression coverage for unreadable named reads, partial listings, writer status, lane-state handling, and directory forwarding.

Tests:

  • Add comprehensive regression tests covering unreadable logs and registers, partial listings, no-origin parsing, writer uncertainty, lane-state holds, and directory quoting.
  • Verify that lanes-index does not reread a lane directory during synchronization.

…e read says UNREAD instead of none, the lanes listing says what is missing, a tree's writer is unknown instead of 0, and lane-state exits 10 instead of 8

T017 continuation, in opensoft/openRepoTools-code, of the
opensoft/openRepoTools branch fix/named-read-none-290 at
b99f904e15b88da1e3f575e258cbd134f7747f63 (issue
opensoft/openRepoTools#290). It carries that branch's own change
against 50d05d4, with its merge of main 50d05d4 (db5d564) left out, for
the code leg's paths: lanes-edit.sh, lanes-index,
tests/test_lanes_index.py and tests/test_named_read_unreadable_290.py.
Its one other path, docs/README-lanes.md (+31 -8), belongs to the spec
leg and is not in this commit. A named worktrees read whose lane's log
or register could not be read is one UNREAD line, not none; a tree's
writer is unknown, not 0, where the binding was not read; the lanes
listing says what it could not read and exits 1 where it names no lane
for that reason; with no origin each log file is parsed on its own; and
lane-state exits 10, not 8, over a log it could not read, which
lanes-index holds the lane's rows for.

The subjects below are quoted from the originals; a bare #N in them is
opensoft/openRepoTools#N.

Old-to-new receipt (the original's own non-merge commits):
b4b0355fd081 Add the tests that a read which could not be made never answers none: the named worktree read, the lanes listing, the no-origin log read and lanes-index's generation read (#290)
286e82197e9a Add the guards a fix for the named read needs: one read of the lane's log, no writer over a binding nobody read, no DORMANT class over a log list that failed, and lane-state's 10 naming the snapshot it found (#290)
f14efed183bd WIP: A named worktree read says NOT READ where its lane's log or the register its name is resolved by could not be read, the lanes listing says a log list it could not make, and lane-state is 10 over a log it could not read (#290) - written, not yet run green
4b1031d78337 The guard for a lane with no published log asks with no control-root override, as a workstation does, so a read that took "no such log" for "could not be read" now fails it (#290)
41ca9cb19683 A named read whose lane's log tree cannot be listed is pinned as an UNREAD line, so the ls-tree that tells an unreadable log from an absent one is tested (#290)
e5069fe5e236 The lanes contract, both exit-code tables and the manual's list of reads that fail closed now name what #290 changed: the listing's 1, lane-state's 10 over a log it could not read, and the events' list of the logs (#290)
a2b52ed1c8a5 The comment over the inventory read's own two log-list reads no longer says known_lanes answers 0 either way: its published list answers 1 where it could not be made (#290)
da187ba448d5 The hold lanes-index makes over lane-state's 10 gives lane-state's own sentence with LANES_DEBUG set, not the "(exit 10)" line die adds after it (#290)
9c0aae54978e Add the test that lane-state finds a lane's snapshot by the whole dir its log records, bare with a quote mark in it as on main, and quoted with a space in it (#290)
bc825a4bf326 lane-state hands the dir it read on quoted only where it holds a space, as lane-start writes it, so a bare dir with a quote mark in it finds its snapshot as on main (#290)
b99f904e15b8 The lane-state dir test now pins a bare dir holding a TAB and a quote mark, read whole as on main, so the rule stays a space and not any whitespace (#290)

Resolutions (git apply --3way left five conflict blocks, four in
lanes-edit.sh and one in lanes-index; tests/test_lanes_index.py applied
at an offset of 6 lines):
1. lanes-edit.sh, the file's exit-code header for 10: opensoft/openRepoTools#290's sentence, then opensoft/openRepoTools#291's, each kept word for word; the "Both" that opened opensoft/openRepoTools#291's moves to the end of opensoft/openRepoTools#290's last line.
2. lanes-edit.sh, worktree_rows' hand-off of the dir: opensoft/openRepoTools#301's decode, then opensoft/openRepoTools#295's quote case, then opensoft/openRepoTools#290's UNREAD block, as ORDER.md section 6 sets it (lane 3, 6368074244).
3. lanes-edit.sh, the lane-state exit-code comment for 10: opensoft/openRepoTools#290's sentence, then opensoft/openRepoTools#291's, each kept word for word; the "And so is a" that opened opensoft/openRepoTools#291's moves to the end of opensoft/openRepoTools#290's last line.
4. lanes-edit.sh, lane-state's 10) case: opensoft/openRepoTools#291's comment and its lookup_blocked die, with opensoft/openRepoTools#290's lane_control_root "$lane" "$lst_pay", as the opensoft/openRepoTools#290 and opensoft/openRepoTools#291 drafts' landing notes set it.
5. lanes-index, lane_generation's docstring: opensoft/openRepoTools#290's whole; its first line already drops the "is there" that opensoft/openRepoTools#291's b0a631b took out.

Lane: openRepoTools-4
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Nov 7, 2026

Copy link
Copy Markdown

Reviewer's Guide

API

The lane-state command now distinguishes an unreadable lane log from a missing snapshot and exits 10 rather than 8.

  • lanes-edit.sh L18988-18991, L19006-19036, L19044

The worktrees command now reports named reads whose lane log or name-resolving register could not be read as UNREAD, while preserving the documented listing exit codes.

  • lanes-edit.sh L19436-19439, L19457-19463 (+2 small edits)

Implementation

Log parsing now reports unreadable files individually, and checked lane-log reads distinguish an absent log from a failed read without changing unchecked callers.

  • lanes-edit.sh L3390-3398, L3543-3557, L3575-3593 (+2 small edits)

Lane discovery and listing now propagate failures to list published logs, say what could not be read, and avoid treating failed reads as an empty listing or a DORMANT lane.

  • lanes-edit.sh L4253-4262, L8378-8387, L8432-8444 (+7 small edits)

Lane-row construction carries the checked log read into the listing and fences rows whose events or binding could not be read from false DORMANT or writer conclusions.

  • lanes-edit.sh L8354-8368, L15177-15195, L15206-15211 (+11 small edits)

The inventory-index integration and its generation-read handling are updated for unreadable lane-state reads.

  • lanes-index L1901-1909, L1914-1926

A regression assertion verifies that a named inventory read does not reread a lane's log to obtain its directory.

  • tests/test_lanes_index.py L2948

Tests

New regression coverage exercises unreadable named logs and registers, failed log listings, unknown writers, no-origin file failures, lane-state generation holds, and directory-payload handoff.

  • tests/test_named_read_unreadable_290.py L1-569

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sonarqubecloud

sonarqubecloud Bot commented Nov 7, 2026

Copy link
Copy Markdown

@sourcery-ai

sourcery-ai Bot commented Nov 8, 2026

Copy link
Copy Markdown

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 6 days and 23 hours by commenting @sourcery-ai review. Upgrade to get a review now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant