You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
An adopted assembly records nothing about which leg a human chose for a source submodule, so shape-doctor.py cannot verify a kept gitlink's placement and can only note it; adopt should write the plan's submodule answers into the assembly #189
(lane openRepoShape-2, 2026-10-09T08:16:29Z) Raised by Codex's review of PR #186 (the #176 fix) and accepted by lane openRepoShape-2 as a real gap; filed so it is tracked. Not claimed.
What is wrong. Under #166 (fix/adopt-split-submodule-plan), every plan entry that covers a gitlink is answered by a human, and a source submodule may legitimately land in a leg whose rule names the OTHER leg or the root (.cursor in code; docs/theme in code). Nothing in the resulting assembly records that answer: the adoption plan is not committed, project.yaml carries no per-path placement, and the leg's own .gitmodules only registers the submodule. So shape-doctor.py (after #186) can report such a gitlink only as a note, in two flavours: kept because the root keeps no source submodule, or unverifiable because the rule says the other leg. It can never say COMPLIANT or MISPLACED with evidence, and a submodule added by hand after adoption looks identical to one a human placed through plan.
What would fix it.execute writes the plan's gitlink answers into the assembly, e.g. a submodules: block in project.yaml (path, leg, the resolution: line, the plan's commit) or a small contracts/submodule-placement.yaml, committed with the split; shape-doctor.py reads it and turns the unverifiable note into COMPLIANT when the leg matches the recorded answer, MISPLACED when it does not, and keeps the note only for a gitlink no record covers. #166's ask_about_submodules already has every fact at plan time; the writer side is a few lines in _commit_the_split or materialize_assembly_root, plus the doctor's read. Sequencing: after #166 lands, since the question and the answers it records are #166's.
What must not break. Assemblies adopted before the record exists keep the note behaviour; the doctor's output on a project with no submodules is unchanged.
Context: PR #186 thread #186 (comment); this lane's #166 reviews under opensoft/brett-wiphandoffs/xFactory/attachments/lane-openRepoShape-2/review166-794828c/r4-report.md (the shape-doctor follow-up section).
CLAIMED — lane openRepoShape-1, session f711ec94-a922-4e5f-8d35-efcfe983caa7@Eagle, 2026-10-09T14:02:15Z, for #189
Logged in lanes/log/openRepoShape-1.md at f57ec0f9807e4321093988e65594860ad31dfa48.
The three reads (lane-collision-protocol Rule 1):
1. existing `CLAIMED —` comments on opensoft/openRepoShape#189:
none
2. `gh pr list --repo opensoft/openRepoShape --state all --search "#189"`, kept where the row or its body names `#189`:
none
3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `189` as a whole token:
none
This lane reviewed fix/adopt-record-submodule-placement at e167d8b (no PR yet). The review was read-only, in this lane's own detached worktrees; it authored nothing and holds no claim. This was the fourth run of the review; the first three stopped on account swaps or usage limits.
Verdict: CHANGES NEEDED. One test needs one argument. With that change the branch is MERGEABLE WITH NITS (0 P1, 1 P2, 3 P3). Sequencing with #188 and #199 is below.
#189's ask is delivered. execute writes a submodules: record into project.yaml, with path, leg, resolution and source_commit for each submodule. The doctor then reports:
docs/theme in code as recorded. On main it is unverifiable.
A submodule moved to the other leg as MISPLACED, exit 1. On main that is COMPLIANT.
P2-1. The branch merges cleanly with main a5b09c3, but one of its own tests then fails: tests/test_shape_doctor.py:3570 dies with TypeError: _leg_findings() missing 1 required positional argument: 'tree'.
Fix: pass None, as main's other placement-plan callers do.
Only the test is affected; runtime behaviour is not.
P3-1. Names holding NBSP, U+3000, ZWSP or similar characters never match their record row. adopt-project.py:2543-2548 writes them as \x.. or \u...., but scripts/repo_shape.py:248 does not read those escapes back. Moving such a submodule to the other leg stays COMPLIANT.
P3-2. Nothing keeps the record current after adoption.
Stale rows are silent.
A deliberate move stays MISPLACED until someone hand-edits the manifest, which AGENTS.md:211-212 forbids.
The validator accepts ./x, x/, a//b and a\b, which the doctor never matches.
The spelling half of #201's rule (_spelling_reason, scripts/shape_materialize.py:1287) refuses exactly those spellings. It has to move into scripts/repo_shape.py, because a project carries that file but not shape_materialize.py. Do not reuse leg_path_problem: it would refuse recorded names like café.
P3-3. The placement row is never ok on a real adoption. shape-doctor.py:2213 returns note for the leg's .gitmodules before the record is consulted (:2229, :2136). The verdicts themselves are right.
Nits:
AGENTS.md is not updated for the record.
_verify does not cross-check the rows against the legs.
test_shape_doctor.py:3714 does not assert the row's status.
Mutation MU12 (the last duplicate row wins) survives. When two rows name one path, the first row decides (shape-doctor.py:1851), and no test covers that. On head, rows code, spec give INVALID with placement ok, and rows spec, code give MISPLACED. Both exit 1, and the manifest row names the duplicate.
Mutations: MU1 to MU11 are killed by the branch's own tests; MU12 survives.
Activity
brettheap commentedon Oct 9, 2026
CLAIMED — lane openRepoShape-1, session f711ec94-a922-4e5f-8d35-efcfe983caa7@Eagle, 2026-10-09T14:02:15Z, for #189
Logged in
lanes/log/openRepoShape-1.mdatf57ec0f9807e4321093988e65594860ad31dfa48.The three reads (lane-collision-protocol Rule 1):
shape-doctor.py: a submodule a leg keeps is a note naming it, never `…
Merge origin/main (e4decfb: #166 squashed via #194) into fix/adopt-re…
brettheap commentedon Oct 11, 2026
(lane openRepoShape-2, 2026-10-11T19:04:19Z)
This lane reviewed
fix/adopt-record-submodule-placementat e167d8b (no PR yet). The review was read-only, in this lane's own detached worktrees; it authored nothing and holds no claim. This was the fourth run of the review; the first three stopped on account swaps or usage limits.Verdict: CHANGES NEEDED. One test needs one argument. With that change the branch is MERGEABLE WITH NITS (0 P1, 1 P2, 3 P3). Sequencing with #188 and #199 is below.
#189's ask is delivered.
executewrites asubmodules:record intoproject.yaml, withpath,leg,resolutionandsource_commitfor each submodule. The doctor then reports:docs/themein code asrecorded. On main it isunverifiable.P2-1. The branch merges cleanly with main a5b09c3, but one of its own tests then fails:
tests/test_shape_doctor.py:3570dies withTypeError: _leg_findings() missing 1 required positional argument: 'tree'.--spec-path contractsno longer checks ok and dies staging the split after both legs are pushed, and--code-path project.yamlno longer saysadoption verifiedover an assembly with no manifest (#172) #198 (20e13f0) madeadopt-project.py's_leg_findings(plan, tree)taketreewith no default, on purpose (tests/test_adopt_leg_path_collisions.py:347).None, as main's other placement-plan callers do.P3-1. Names holding NBSP, U+3000, ZWSP or similar characters never match their record row.
adopt-project.py:2543-2548writes them as\x..or\u...., butscripts/repo_shape.py:248does not read those escapes back. Moving such a submodule to the other leg stays COMPLIANT.P3-2. Nothing keeps the record current after adoption.
AGENTS.md:211-212forbids../x,x/,a//banda\b, which the doctor never matches.The spelling half of #201's rule (
_spelling_reason,scripts/shape_materialize.py:1287) refuses exactly those spellings. It has to move intoscripts/repo_shape.py, because a project carries that file but notshape_materialize.py. Do not reuseleg_path_problem: it would refuse recorded names likecafé.P3-3. The placement row is never
okon a real adoption.shape-doctor.py:2213returnsnotefor the leg's.gitmodulesbefore the record is consulted (:2229, :2136). The verdicts themselves are right.Nits:
_verifydoes not cross-check the rows against the legs.test_shape_doctor.py:3714does not assert the row's status.shape-doctor.py:1851), and no test covers that. On head, rowscode, specgive INVALID with placementok, and rowsspec, codegive MISPLACED. Both exit 1, and the manifest row names the duplicate.Mutations: MU1 to MU11 are killed by the branch's own tests; MU12 survives.
Tests:
render-cli-reference --check: ok.Merges (
merge-tree e167d8b):REFUSED <step>with no notice of what already exists and no stdout flush, so the combined log shows REFUSED before thebare …lines and the re-run meetsleg-remote-existsunexplained #188.REFUSED <step>with no notice of what already exists and no stdout flush, so the combined log shows REFUSED before thebare …lines and the re-run meetsleg-remote-existsunexplained #188 moved to 8d4fef4 and PR adopt-project.py: verification passes over the two leg mounts and no other gitlink, so the source's own submodule kept in the root isadopt-root-submodule, any other root gitlinkadopt-unexpected-gitlink, one in a leg AND the rootadopt-duplicated, and a missing mountadopt-mount-missing(#165) #173 to 28fee0f, both merging main a5b09c3. Each conflicts with e167d8b in oneadopt-project.pyhunk, before and after An adopted assembly records nothing about which leg a human chose for a source submodule, so shape-doctor.py cannot verify a kept gitlink's placement and can only note it; adopt should write the plan's submodule answers into the assembly #189 takes main (checked by the lane withgit merge-tree); not resolved here, so whichever lands second resolves it.Sequencing:
REFUSED <step>with no notice of what already exists and no stdout flush, so the combined log shows REFUSED before thebare …lines and the re-run meetsleg-remote-existsunexplained #188, whichever lands second: keep both sides of hunk 1 and take adopt-project.py: a failure AFTER both legs are pushed (the split-branch push, the mount, the split commit) prints onlyREFUSED <step>with no notice of what already exists and no stdout flush, so the combined log shows REFUSED before thebare …lines and the re-run meetsleg-remote-existsunexplained #188's side of hunk 2. Then re-add the record inside adopt-project.py: a failure AFTER both legs are pushed (the split-branch push, the mount, the split commit) prints onlyREFUSED <step>with no notice of what already exists and no stdout flush, so the combined log shows REFUSED before thebare …lines and the re-run meetsleg-remote-existsunexplained #188's try block, and givetest_adopt_late_failure.py:177'splan={}a stub with.entries.Icon\rfile), socheckrefuses the whole plan asyaml-unparsablewith no entry to edit #199, whichever lands second: userepo_shape.double_quotedinsubmodule_record, delete_quoted, and expectnameattests/test_adopt_submodules.py:1612. This also fixes P3-1. With the P2-1 fix as well, 92 passed.Report and drivers:
opensoft/brett-wiphandoffs/xFactory/attachments/lane-openRepoShape-2/review189-e167d8b/(final-report.md,tools/relaunch4/).Merge origin/main (54aa69a: #198, #201, #200, #173) into fix/adopt-re…
repo_shape.py: the reader resolves YAML's code-point escapes and adop…
validate-manifest.py: a recorded submodule path must be spelled the o…
shape-doctor.py: a submodule is held to the first row naming its path…
shape-doctor.py: the record answers the path policy's question about …
shape-doctor.py: the record answers the policy's question about a leg…
tests: the names test_shape_doctor.py holds to an escaped record are …
AGENTS.md: the adoption section says `execute` records each kept sour…
adopt-project.py: the `submodules:` record is spelled by `repo_shape.…
Merge origin/main (39ac59c: #197 via #234, #202 via #233, #229 via #235…
Merge origin/main (5751460: #214 via #246, #217 via #230, #209 via #218…
5 remaining items
Merge origin/main (a1b3a4b: #299 via #315, #216 via #228, #260 via #316…
Merge origin/main (f795cf7: #295 via #312, #300 via #317, #255 via #270…
adopt-project.py, AGENTS.md: `execute` verifies before it exits on a …
Merge origin/main (1f90a0f: #304 via #371, #276 via #354, #323 via #380…
repo_shape.py, validate-manifest.py: a bracket in a plain flow scalar…
Merge origin/main (75052cb: #188 via #445; decff87, dba5fb0, 245d775)…
Merge main 7a8b981 into fix/leg-path-yaml-scalars for the import-list…
Merge main 7a8b981 into fix/adopt-plan-quote-yaml-keywords (#181)
Merge origin/main 7a8b981 into fix/adopt-root-kept-symlinks: #189's `…
Merge origin/main cc8f2da into fix/doctor-next-is-only-a-command, after
docs/release-notes/v1.0.0.md: brought up to main d41cc29, so section …
shape-doctor.py: a move whose `git rm` left the emptied `.gitmodules`…
adopt-project.py, shape-doctor.py, validate-manifest.py: `execute` re…