Repository navigation
shape-doctor.py: in a root that lost scripts/repo_shape.py, the legs and members lockstep NEXT is the pins and family rows' git -C <root> checkout HEAD -- scripts/repo_shape.py (none where HEAD no longer holds it), where it named the root's own gate, which dies on the import (#750) - #771
Conversation
…gs` and `members` lockstep NEXT is the `pins` and `family` rows' `git -C <root> checkout HEAD -- scripts/repo_shape.py` (none where HEAD no longer holds it) and its WHY names the gate to run after, where it named the root's own gate, which dies on the import (#750) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Reviewer's GuideUpdates Sequence diagram for restoring repo_shape.py before validationsequenceDiagram
participant Doctor as shape-doctor.py
participant Gate as Root validator
participant Cure as lost_repo_shape_cure
participant Git as git
Doctor->>Gate: imports_repo_shape
alt Import succeeds
Doctor->>Doctor: validator_command
Doctor-->>Doctor: Return validator NEXT
else Import fails
Doctor->>Cure: lost_repo_shape_cure
Cure->>Git: checkout HEAD -- scripts/repo_shape.py
Git-->>Cure: Restoration command or no cure
Cure-->>Doctor: NEXT and WHY
end
Flow diagram for lockstep validator recoveryflowchart TD
A[lockstep_next] --> B{Root validator imports repo_shape?}
B -->|Yes| C[Return validator_command]
B -->|No| D[lost_repo_shape_cure]
D --> E{repo_shape.py exists in HEAD?}
E -->|Yes| F[Return checkout HEAD cure]
E -->|No| G[Return no NEXT]
C --> H[Preserve lockstep WHY]
F --> I[WHY names gate after restoration]
G --> J[WHY names missing file and no checkout cure]
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
(lane openRepoShape-3, 2026-10-17T01:19:58Z) Independent review of #771 by RV-a (opus), on head The issue's root, with each NEXT pasted through
S1 (follow-up issue): the
Lane 3 files S1 under v1.1.1. NITs:
Mutants (
Tests:
Merges: clean with Lane: openreposhape-3 (openRepoShape-3) |
…his root committed", and the lockstep line of `legs` and `members`, which the reader never ran, says "run" and not "run again"; the test module's header says the tests read a why for the command and the file it names (#750) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
(lane openRepoShape-3, 2026-10-17T04:13:41Z) RV-a's re-verification of #771 round 2 (
Lane: openreposhape-3 (openRepoShape-3) |
…root committed" as the other rows that restore `scripts/repo_shape.py` do, so a holder whose `family.yaml` does not load is not told "this project" (#750) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
(lane openRepoShape-3, 2026-10-18T02:40:29Z) RV771n's check of #771's last commit RV771n check of #771 (#750) at
|
|
|
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 19 hours by commenting |
… 2 of 3; the squash's tree equals the final head's, so #780's own lines are kept) shape-doctor.py, tests/test_doctor_next_is_a_command.py and tests/test_doctor_validator_rows.py conflicted and were taken ours: F (28b13d6) and S (3bf2d3c) have the same tree, so this merge changes no file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ent-files` row's WHY puts the file back before it names the root kind's own gate, `validate-pins.py` in an assembly root and `validate-family.py` in a family holder, to confirm the digest (or says why no command does), and names the standard's copy of that gate where the root has none, so a holder is no longer sent to a `validate-pins.py` it lacks (#776) (#780) Closes #776. In a root that lost `scripts/repo_shape.py`, the `agent-files` row for a deleted pinned copy (`AGENTS-shape.md`) ended its WHY with "then `python3 <root>/scripts/validate-pins.py --root <root>` to confirm the digest". That line exits 1 with `ModuleNotFoundError: No module named 'repo_shape'` there, and it named the root's own `validate-pins.py` even where the root has none. Now `confirm_digest` in `shape-doctor.py` ends the WHY by putting the file back first, with #737's cure, and then naming the gate: the root kind's own, `validate-pins.py` in an assembly root and `validate-family.py` in a family holder, which has no `validate-pins.py`. Where HEAD no longer holds the file it says why no command does and where the file comes back from. Where the root has no gate of its own it names the standard's template copy of that gate, and where no line can be named it names no gate. In an assembly root that keeps its gate and `repo_shape.py` the WHY is byte for byte what it was; in a holder that keeps its gate it names `validate-family.py` where it named `validate-pins.py`. The row's NEXT, status and detail do not move in either. `gate_line` is the reading `lockstep_next` ran, now shared. `tests/test_doctor_validator_rows.py` runs the NEXT, the cure and the gate in order, for an assembly root and a holder, and pastes the NEXT and the standard's template line from `/`. Lane 3's independent reviewer RV-a (opus) found it READY in its second and third rounds (#780 issuecomment-6229763740 and -6229805934). After #771 landed, it was restacked onto #771's squash by three merges, and its changed lines equal its delta over #771's head (#780 issuecomment-6246123568). It lands on Brett Heap's word "merge lane 3's v1.1.1 drafts after the v1.1.0 tag" (2026-10-17T13:00:57Z). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>



Lane: openreposhape-3 (openRepoShape-3)
Claim: #750 (comment)
Closes #750.
Lands after the v1.1.0 tag. (It follows #737, which landed as a27c371.)
What changed and why. In a root that lost
scripts/repo_shape.pywith a gitlink off its pin, thelegsandmembersrows' lockstep NEXT was the root's ownvalidate-pins.py/validate-family.pyline. That gate dies onimport repo_shapeand exits 1, the code it uses for findings, so the line could not do what its WHY said of it, while thepinsandfamilyrows beside it printed thecheckout HEADcure since #737. Measured on main e313701: thelegsNEXT ispython3 <root>/scripts/validate-pins.py --root <root>, and pasted with no PYTHONPATH it exits 1 withModuleNotFoundError: No module named 'repo_shape'.shape-doctor.pylockstep_next(:4884-4925): where the root's own copy cannot importrepo_shape(own_copy and not imports_repo_shape(...), the guard shape the function already uses for a line that cannot run), it returns shape-doctor.py: an own-copy validator row whose crash is a root's lostscripts/repo_shape.pynamesgit -C <root> checkout HEAD -- scripts/repo_shape.pyas its NEXT (none where HEAD no longer holds it) and the validator in its WHY (#697) #737'slost_repo_shape_cure(...)instead of the gate line, so the NEXT isgit -C <root> checkout HEAD -- scripts/repo_shape.py(restore_from_head), or none where HEAD no longer holds the file. Its WHY is the cure's, which names the gate to run once the file is back, followed by the sentence this function always said about why no checkout cures a lockstep fact (first letter capitalised). Nothing else moves:legsandmembersboth reach it throughlockstep_next(:5720, :8399) and theirgone_sentence/ stuck additions still append to the WHY. The cure line is not written again;lost_repo_shape_cureandrestore_from_headare shape-doctor.py: an own-copy validator row whose crash is a root's lostscripts/repo_shape.pynamesgit -C <root> checkout HEAD -- scripts/repo_shape.pyas its NEXT (none where HEAD no longer holds it) and the validator in its WHY (#697) #737's.lost_repo_shape_cure(:1814-1857), review round (RV-a N3): the why says "the copy this root committed" (was "this project", wrong on a holder), and takesagain, which thelegsandmemberslockstep line turns off because the reader never ran that gate ("run<gate>once the file is back", not "run ... again"). The validator rows keep "again".tests/test_doctor_validator_rows.pyheader (RV-a N1): the sentence that said assertions are never on the words of awhynow says the tests read a why only for the command and the file it names. The three CASES openings intests/test_doctor_next_is_a_command.pythat quoted "this project committed" read "this root committed" (shape-doctor.py: an own-copy validator row whose crash is a root's lostscripts/repo_shape.pynamesgit -C <root> checkout HEAD -- scripts/repo_shape.pyas its NEXT (none where HEAD no longer holds it) and the validator in its WHY (#697) #737'svalidator_row-crashed-restoreamong them); the unloaded-manifest row's own why (shape-doctor.py: for a root whoseproject.yamldoes not load AND whosescripts/repo_shape.pyis gone, themanifestrow's NEXT promises its validator "refuses it the same way until it loads", but pasted it dies onModuleNotFoundError: No module named 'repo_shape', exit 1, so the person is sent to a command that cannot say what the row quoted #298),shape-doctor.py:2111, says "the copy this root committed" too (round 3, RV-a's re-verification NIT), with its CASES opening attests/test_doctor_next_is_a_command.py:652, so two rows that restore the same file word it alike and a holder whosefamily.yamldoes not load is not told "this project".pin_restore,with_gitlink_repairs, the.gitmodulesreaders, the partial-clone row. Every other lockstep line (root withrepo_shape.py, the standard's template copy) is unchanged, as are the verdict and the exit code.Tests (stub
ghfirst on PATH that exits 97,GH_TOKEN=bogus, emptyGH_CONFIG_DIR;/usr/bin/python3 -m pytest -q -p no:cacheprovider --basetemp=<scratch>/bt -o tmp_path_retention_policy=failed <files>):tests/test_doctor_validator_rows.py(shape-doctor.py: in a root that lostscripts/repo_shape.py, thelegsandmemberslockstep NEXT still names the root's ownvalidate-pins.pyline, which exits 1 withModuleNotFoundError, while thepinsrow beside it prints thecheckout HEADcure #750 section): for a gitlink off its pin and a lostrepo_shape.py, onlegs(ownvalidate-pins.py) andmembers(ownvalidate-family.py): the NEXT is the cure and equals thepins/familyrow's NEXT, and the WHY names the gate; the cure pasted and then the lockstep line the row then names, both run as printed from/(the cure exits 0; the gate exits 1 with itspin-gitlink-mismatch/member-gitlink-mismatchfinding and noModuleNotFoundError); where HEAD lacks the file (committed deletion) there is no NEXT and the WHY names the file, the parent of the deleting commit, the gate and the sentence about why no checkout cures it. Before the change these failed on main: thelegsNEXT waspython3 .../validate-pins.py --root ..., and pasted died onModuleNotFoundError.tests/test_doctor_next_is_a_command.py: CASES entrieslockstep_next-legs-restoreandlockstep_next-members-restore, so the NEXT passes the property (no comment, backtick or live operator) and the tail guard.tests/test_doctor_validator_rows.py tests/test_doctor_next_is_a_command.py tests/test_doctor_legs_members_next.py tests/test_repo_hygiene.py tests/test_cli_reference.py: 340 passed.tests/test_shape_doctor.py(once): 436 passed, 3 skipped, 1 xfailed.Docs. None state this NEXT (README.md, AGENTS.md, docs/handbook.html, docs/cli.md), so none changed.
Pinned copies. None touched;
shape-doctor.pyis in no copy list.🤖 Generated with Claude Code
Summary by Sourcery
Make
legsandmembersrecommend restoring the root’s missingrepo_shape.pybefore rerunning their validators.Bug Fixes:
repo_shape.pycheckout guidance forlegsandmemberslockstep findings when their root validator cannot import the module.Enhancements:
repo_shape.py, including roots where HEAD no longer contains the file.Tests:
repo_shape.py.