Skip to content

T017: A lane control root that cannot be searched is read as not read, not as no trees: lane-state and lane-trees exit 10, the listing says UNREAD, and a sync keeps the lane's rows (opensoft/openRepoTools#291) (part of opensoft/openRepoTools#186) - #8

Merged
brettheap merged 1 commit into
mainfrom
fix/control-root-unsearchable-291
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-spec), of the opensoft/openRepoTools branch fix/control-root-unsearchable-291 at 3e97ae514452, for opensoft/openRepoTools#291 (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, 0b6f2a0be00a, carries it.

It carries the spec-leg part of that branch's own change, which is its head against 50d05d4 with its merge of main 50d05d4 (457b73b) left out: docs/README-lanes.md, +25 −8, seven hunks. The change's other four paths (lanes-edit.sh, lanes-index, lanes and tests/test_unsearchable_control_root_291.py) are the paired commit in opensoft/openRepoTools-code. It is stacked on the spec PR for opensoft/openRepoTools#301 (#7), as the chain has it; the two touch different hunks of the manual, and the patch applied without conflict, at no offset.

What was wrong and what changed

What was wrong

The manual described a lane's control root and its reads as if a path that tests false were always a path that is gone. opensoft/openRepoTools#291's code now tells a control root nobody could look for (a folder on the way cannot be searched, or a link on the way cannot be followed) from an absence that was looked for, and reads the first as not read: lane-state and lane-trees exit 10, not 8, the listing names the lane UNREAD, a sync keeps the lane's rows, and lane-reconcile is indeterminate. The manual's exit-code row for 10, its unreadable verdict row, its rung section, its lane-trees paragraph and its inventory-index text covered only a snapshot or a trees directory that is there and cannot be read.

Two of the original's review findings are about this text. SHOULD-1: the rung section still described the old fall-through, and the first fix (7db059f) overstated, saying "every read under it is 10", where only lane-state and lane-trees exit 10 and lane-reconcile and the listing exit 0 with indeterminate or an UNREAD line; 3e97ae5, a manual-only commit, replaces that sentence. The manual's earlier "every write there fails" has one exception, which is opensoft/openRepoTools#309's (see Not in this PR).

What changed

docs/README-lanes.md, +25 −8, seven hunks, in the order of the file:

  1. The exit-code row for 10: both lane-state and lane-trees spend 10 too where the record could not even be looked for: its control root, or a directory above it, cannot be searched, or a link on the way cannot be followed.
  2. The unreadable row of the verdict table: a snapshot that is there and cannot be opened is not a lane that has none, and nor is one that could not even be looked for; lane-state exits 10 for both, never the 8 that means "this lane has no snapshot, go on".
  3. A new paragraph under "Where it lives": a rung is passed over only where its directory is established absent; where it could not be looked for, its root is the answer: lane-state and lane-trees exit 10 there, the listing names the lane UNREAD, lane-reconcile pronounces indeterminate, and every write there fails rather than filing under the next rung.
  4. The lane-trees paragraph: a trees directory that could not even be looked for is exit 10 too, the read walks up to the deepest name that is there and answers 8 only where that name could answer for the one below it, lane-state answers for the snapshot the same way, and a recorded dir whose parent could not be looked for keeps its own control root rather than falling to $PROJECTS_ROOT's.
  5. The inventory index's path row: the lane of a sidecar that could not be read is UNREAD beside it, so a sync keeps that lane's rows rather than replace the tree's row with one keyed by the record's id.
  6. The marker-row paragraph: a lane whose trees directory is there and cannot be listed, could not even be looked for, or holds a record that could not be read keeps its rows.
  7. The named-read paragraph: a lane the listing did name and could not read (its trees directory, its control root or a directory above it cannot be listed or searched, or a record of its trees cannot be read) is that lane's own UNREAD line, and only that lane's rows are held; the named read never prints PARTIAL.

The manual's added text keeps the original's bare issue numbers, such as (#N), byte for byte. In this leg's manual they name opensoft/openRepoTools issues, as its other pre-split text does.

Not in this PR

Old to new: the receipt

The original's own non-merge commits in opensoft/openRepoTools (50d05d4..3e97ae5), 11 in all, are carried by one commit in this leg, 0b6f2a0be00a. 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).

a431854c42c4 Test that a lane control root nobody could search is never read as a lane with no trees, and that an inventory sync keeps that lane's rows (#291)
02571b4ade4f A lane control root that cannot be searched is read as not read, never as no trees, so an inventory sync keeps the lane's rows (#291)
af4d132af4c7 A lane whose inventory could not be read is no longer said to have one that is there, because a blocked lookup never saw whether it was (#291)
124b509eb6f0 Test that a write under a lane control root nobody could look for fails and is filed nowhere else, and that a .lane-state link whose target is gone is unread, never none (#291)
b0a631baa46c lane_generation's docstring no longer says that a snapshot it could not read is there, because a blocked lookup never saw whether it was (#291)
7db059f458a7 The README's rung section says that a rung is passed over only where its directory is established absent, and that a rung nobody could look for keeps its root, so its reads are 10 and its writes fail (#291)
468b20e6c411 lane-reconcile no longer says that a trees directory nobody could look for is there, and says instead that whether it is there could not be read, and why (#291)
3af5006f565f The lanes-index marker comment, the second exit-10 header in lanes-edit.sh and the README's unreadable verdict row no longer say that a record nobody could look for is there (#291)
a3ea2af1946a Only the #291 cases that set a mode skip as root, so the links that cannot be followed, which set none, are proved there too (#291)
82ac6b742392 lookup_blocked's comment names its limit: a denial that the mode bits do not show still reads as absent (#291)
3e97ae514452 The README's rung paragraph now names what each surface says where a rung could not be looked for, instead of calling every read 10 (#291)

The subjects are the original's, byte for byte; a bare (#N) in them names the root issue.

Of these, the commits that touch docs/README-lanes.md (the original's range on that path) are 02571b4ade4f, 7db059f458a7, 3af5006f565f, 3e97ae514452. The others change code-leg paths only, and their part is the paired code PR's.

Resolutions

None. The patch applied clean, with no offset, onto the commit for opensoft/openRepoTools#301.

The pairing

The code part of this change is the commit ca9b847f678e on fix/control-root-unsearchable-291 in opensoft/openRepoTools-code, its own PR, opensoft/openRepoTools-code#5 (base fix/subfield-misreads-301). 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: the paired code PR, opensoft/openRepoTools-code#5, first, then this one. 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

The manual is tested from the code leg, not here: this leg has no code and no CI workflow of its own. tests/test_repo_hygiene.py reads docs/README-lanes.md through OPENREPOTOOLS_SPEC_ROOT (tests/test_test_roots.py pins which manual a run reads). The pair is fix/control-root-unsearchable-291 in opensoft/openRepoTools-code, commit ca9b847f678e.

The pair's hygiene runs, from lane 4's independent paired review (2026-10-31), with OPENREPOTOOLS_SPEC_ROOT set to the spec clone shown (env -i, TMPDIR=/tmp). They read the spec chain's tip, which carries this PR's commit with the later commits of the chain; none read the manual at this commit alone. The letters are the review report's own: (c) is the shell-suite run, in the paired code PR, and (d) was skipped.

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)
(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.

Release notes (v1.2.0)

The release-notes lines for this change are in the paired code PR, opensoft/openRepoTools-code#5 (fix/control-root-unsearchable-291 in opensoft/openRepoTools-code), once, in the PR that carries the code change. This PR 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): the independent review of 124b509 is LAND, with no MUST; its SHOULD-1, the manual's rung section, is fixed in 7db059f and, after the second read found "every read under it is 10" overstated, in 3e97ae5. Both are manual-only and are in this PR's single commit. The fix round was checked by a second read: items 2 to 6 VERIFIED, and item 1 fixed by 3e97ae5.

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#291 (comment 6313861277)

🤖 Generated with Claude Code

Summary by Sourcery

Document inaccessible lane control roots as unreadable and preserve their existing inventory rows during synchronization.

Enhancements:

  • Clarify lane documentation so inaccessible control roots and ancestor paths are treated as unreadable rather than absent, including their exit codes, reconciliation status, listing output, and fallback behavior.
  • Document that inventory synchronization preserves rows for lanes or tree records that cannot be inspected, while marking them as UNREAD.

Documentation:

  • Update lane behavior documentation for blocked searches, unfollowable links, unreadable tree records, and per-lane UNREAD reporting.

… is read as not read instead of as no trees: lane-state and lane-trees exit 10 instead of 8, the listing says UNREAD, and an inventory sync keeps the lane's rows

This is the T017 continuation, in this leg
(opensoft/openRepoTools-spec), of the original opensoft/openRepoTools
branch fix/control-root-unsearchable-291 at
3e97ae51445291fc3efdd36da5709edee3103549, issue
opensoft/openRepoTools#291. The original branched from main 50d05d4 and
its head merges 50d05d4, so its own change is its head against 50d05d4
with that merge left out (the merge's tree equals git's automatic
merge). Spec-leg part of its own change: docs/README-lanes.md (+25 -8:
the exit-code row for 10, the unreadable row of the verdict table, a
paragraph under Where it lives on when a rung is passed over, the
lane-trees paragraph, the inventory index's path row and marker-row
paragraph, and the named-read paragraph). Its other paths
(lanes-edit.sh, lanes-index, lanes and
tests/test_unsearchable_control_root_291.py) belong to the code leg and
are the paired commit there; the leg table sends docs/ to this leg with
no rename. This continuation stacks on the one for
opensoft/openRepoTools#301, as ORDER.md's chain has it; the two touch
different hunks of the manual and the apply was clean.

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 in
opensoft/openRepoTools (50d05d4..3e97ae5):
a431854c42c4 Test that a lane control root nobody could search is never read as a lane with no trees, and that an inventory sync keeps that lane's rows (#291)
02571b4ade4f A lane control root that cannot be searched is read as not read, never as no trees, so an inventory sync keeps the lane's rows (#291)
af4d132af4c7 A lane whose inventory could not be read is no longer said to have one that is there, because a blocked lookup never saw whether it was (#291)
124b509eb6f0 Test that a write under a lane control root nobody could look for fails and is filed nowhere else, and that a .lane-state link whose target is gone is unread, never none (#291)
b0a631baa46c lane_generation's docstring no longer says that a snapshot it could not read is there, because a blocked lookup never saw whether it was (#291)
7db059f458a7 The README's rung section says that a rung is passed over only where its directory is established absent, and that a rung nobody could look for keeps its root, so its reads are 10 and its writes fail (#291)
468b20e6c411 lane-reconcile no longer says that a trees directory nobody could look for is there, and says instead that whether it is there could not be read, and why (#291)
3af5006f565f The lanes-index marker comment, the second exit-10 header in lanes-edit.sh and the README's unreadable verdict row no longer say that a record nobody could look for is there (#291)
a3ea2af1946a Only the #291 cases that set a mode skip as root, so the links that cannot be followed, which set none, are proved there too (#291)
82ac6b742392 lookup_blocked's comment names its limit: a denial that the mode bits do not show still reads as absent (#291)
3e97ae514452 The README's rung paragraph now names what each surface says where a rung could not be looked for, instead of calling every read 10 (#291)

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

sourcery-ai Bot commented Nov 7, 2026

Copy link
Copy Markdown

Reviewer's Guide

Documentation

Read the exit-code, verdict, and rung guidance together to verify how blocked control-root lookups are distinguished from absence across the lane interfaces.

  • docs/README-lanes.md L1232, L3345, L3406-3412

Check the lane-trees guidance for consistent lookup behavior, including how a recorded directory affects control-root selection.

  • docs/README-lanes.md L3434-3442

Read the inventory-index and named-read guidance together to confirm that unread lanes retain their rows and are reported as UNREAD.

  • docs/README-lanes.md L3849, L3874-3875, L3921-3924

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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Approved.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

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