Skip to content

T017: A tree record that names no absolute path makes its lane UNREAD, so a sync and a reconcile keep the lane's rows instead of swapping the tree's row for one keyed by the record's id (opensoft/openRepoTools#302) (part of opensoft/openRepoTools#186) - #9

Merged
brettheap merged 1 commit into
mainfrom
fix/pathless-tree-record-302
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/pathless-tree-record-302 at 01c83b70ebf3, for opensoft/openRepoTools#302 (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, 7c80dc826965, carries it.

It carries the spec-leg part of that branch's own change, which is its head against 3e97ae5, the head of fix/control-root-unsearchable-291 it is stacked on, with no merge of main: docs/README-lanes.md, +22 −9. The change's other four paths (lanes-edit.sh, lanes-index, tests/test_lanes_index.py and tests/test_pathless_tree_record_302.py) are the paired commit in opensoft/openRepoTools-code. It is stacked on the spec PR for opensoft/openRepoTools#291 (#8), as the original is; the patch applied without conflict, at no offset.

What was wrong and what changed

What was wrong

The manual still said that a tree's path can be empty (a sidecar with no path:), which has been stale since opensoft/openRepoTools#252: a record with no path: line is not a whole record, and the helper lists it under its own id. It also said nothing of what a tree record that names no absolute path costs its lane. opensoft/openRepoTools#302's code now names such a lane UNREAD, beside the record's row, so that lanes-index sync and reconcile --source inventory hold the lane's rows instead of swapping the tree's row for one keyed by the record's id or by the relative text; one such record holds every row of its lane until it is put right.

What changed

docs/README-lanes.md, +22 −9, four hunks at git's default context, in the order of the file:

  • The inventory index's path and branch row: names malformed sidecar (A lane sidecar passes validation on its schema: line alone, so a truncated schema: 1 record is read AND replaced openRepoTools#115), says each kind keeps the path it names and has the record's id where it names none, says that the lane of a record that could not be read, or that was read and names no absolute path (none, an empty one, or a relative one), is UNREAD beside its row, and states the cost: one such record holds every row of its lane, while one that names an absolute path keeps its key, is rewritten in place and holds nothing.
  • The keyed-by-path sentence: its example is now "a record that is not whole and names a whole one's path", where it said "two with no path:".
  • The paragraph on which lanes get their own UNREAD line: adds a lane that holds a record that was read and names no absolute path (no path: line, an empty one or a relative one, in a record that is not whole or is of another schema).
  • The marker-row sentence: the key is what makes it one because a hand-made sidecar's branch can read the same, and so can an older helper's row for a sidecar with no path:; it no longer says that a tree's path can be empty.
  • A new passage, "the hold is the whole lane's": one record that could not be read, or that names no absolute path, keeps every row of its lane as the last sync that read it left them, so the lane's other trees, and any new ones, stop reaching the index until that record is put right; a record that is not whole or of another schema but names an absolute path keeps its key and holds nothing.
  • The named-read paragraph's last sentence: adds "or one that was read names no absolute path" to what is the lane's own UNREAD line.

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 (3e97ae5..01c83b7), 4 in all, are carried by one commit in this leg, 7c80dc826965. 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).

e094080de29f Add the tests that a tree record that is read and names no absolute path holds its lane's rows in the inventory index, as part F holds a record that could not be read (#302)
d035807239e7 lanes-edit.sh worktrees names a lane UNREAD beside a tree record that was read and names no absolute path, so a sync keeps the lane's rows instead of swapping the tree's row for one keyed by the record's id (#302)
e7f86b6fe02d The README and the lanes-index comments no longer say a sidecar with no path: is a tree with an empty path, and the README says what a record that names no absolute path costs its lane (#302)
01c83b70ebf3 Add the tests that the UNREAD line names every tree record that names no absolute path, and that the clause holds its own lane and no other (#302)

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

Of these, the commit that touches docs/README-lanes.md (the original's range on that path) is e7f86b6fe02d. 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#291.

The pairing

The code part of this change is the commit 4ed3fd2ad6fe on fix/pathless-tree-record-302 in opensoft/openRepoTools-code, its own PR, opensoft/openRepoTools-code#6 (base fix/control-root-unsearchable-291). 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#6, 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/pathless-tree-record-302 in opensoft/openRepoTools-code, commit 4ed3fd2ad6fe.

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#6 (fix/pathless-tree-record-302 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; the comment ids are copied from the root draft and were not re-read (no network): lane 3's design review (comment 6352328413, PROCEED) ruled R4, "revise the existing test and the stale README sentence, with 524's three passages added and the cost stated"; its review of the finished code (comment 6371844475, READY AFTER FIXES) found R4 and 524 done, and asked for two tests only; its re-check of the last head (comment 6375703768) is READY TO LAND, with no finding. The manual's commit (e7f86b6) is in this PR's single commit.

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#302 (comment 6349903174)

🤖 Generated with Claude Code

Summary by Sourcery

Clarify lane inventory semantics so records without absolute paths preserve their lane’s rows during synchronization and reconciliation until they are fixed.

Enhancements:

  • Update the lane documentation to define pathless or non-absolute tree records as unread and clarify that they hold the entire lane’s existing rows until corrected.
  • Clarify inventory row identity and handling for malformed, unknown-schema, and pathless sidecar records.

Documentation:

  • Document the UNREAD lane behavior and reconciliation consequences for tree records without absolute paths.

…lane UNREAD, so a sync and a reconcile keep the lane's rows instead of swapping the tree's row for one keyed by the record's id

This is the T017 continuation, in this leg
(opensoft/openRepoTools-spec), of the original opensoft/openRepoTools
branch fix/pathless-tree-record-302 at
01c83b70ebf3a91adea40cf76fe4f1d8a2eecf48, issue
opensoft/openRepoTools#302. The original is stacked on
fix/control-root-unsearchable-291 (opensoft/openRepoTools#291, head
3e97ae51445), so its own change is its head against that head, and it
has no merge of main. Spec-leg part of its own change:
docs/README-lanes.md (+22 -9: the path and branch row, the keyed-by-path
sentence, the paragraphs on which lane gets its own UNREAD line and on
the lane-wide hold, and the marker sentence). Its other paths
(lanes-edit.sh, lanes-index, tests/test_lanes_index.py and
tests/test_pathless_tree_record_302.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#291, as the original does; the apply was clean,
with no offset.

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 (3e97ae5..01c83b7):
e094080de29f Add the tests that a tree record that is read and names no absolute path holds its lane's rows in the inventory index, as part F holds a record that could not be read (#302)
d035807239e7 lanes-edit.sh worktrees names a lane UNREAD beside a tree record that was read and names no absolute path, so a sync keeps the lane's rows instead of swapping the tree's row for one keyed by the record's id (#302)
e7f86b6fe02d The README and the lanes-index comments no longer say a sidecar with no path: is a tree with an empty path, and the README says what a record that names no absolute path costs its lane (#302)
01c83b70ebf3 Add the tests that the UNREAD line names every tree record that names no absolute path, and that the clause holds its own lane and no other (#302)

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

Update the lane inventory documentation to explain when a tree record makes its lane UNREAD, how that holds the entire lane’s rows, and how absolute-path records are handled.

  • docs/README-lanes.md L3876-3885, L3891-3897 (+3 small edits)

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