Repository navigation
Pinned shape copies: AGENTS-shape.md's CONTRACTS_DIR sentence is false for every scaffolded root, and the chain WARNING offers remedies the scaffold lacks (one shape bump before the v1.1.0 tag) #610
Description
Shape-copy text, in one shape bump: the CONTRACTS_DIR sentence, the chain WARNING's remedies and raw --pin-source, validate-pins' note, and THE LOCKSTEP RULE's bump line.
From the checklist triage of 2026-10-15; Brett Heap approved its recommendations at 2026-10-15T16:49:38Z. One pull request covers the lines below.
Lands after: #570, #575 and #576.
Decision applied: the triage's D6: one shape bump before the v1.1.0 tag, so every project re-pins once for v1.1.0.
Lines
- L2-33: pinned AGENTS-shape.md says the root Makefile exports
$(CURDIR)/spec/contracts; untrue for every scaffolded root. Where: templates/assembly-root/AGENTS-shape.md:78-81; scripts/shape_materialize.py:982-994 (ADOPT_MAKEFILE_BLOCK); adopt-project.py:8269. Effort S; all. On main26c1600: Measured at 26c1600: a scaffolded root's Makefile has noCONTRACTS_DIR, andmake contracts-dirsaysNo rule to make target 'contracts-dir', while its AGENTS-shape.md:80 says the root Makefile exports it; only adopt appends the block; bootstrap.py: a leg detached off the pin is left where it is and said, so a commit made there is no longer stranded when its branch is already at the pin, thenot moving an existing branchline names where the checkout is, and bump-leg.py and AGENTS-shape.md say "or says why not" (#533) #556 has landed (64fc9a8), so the item's "after bootstrap.py: a leg detached off the pin is left where it is and said, so a commit made there is no longer stranded when its branch is already at the pin, thenot moving an existing branchline names where the checkout is, and bump-leg.py and AGENTS-shape.md say "or says why not" (#533) #556" order is met, no open PR touches this file, and the adopt half rides with adopt-project.py: the Makefile blockexecuteappends and the cross-leg follow-up name each leg where the plan mounts it, so--spec-path legs/specexports aCONTRACTS_DIRthat exists and a nested--code-pathgets the right../path (#522) #572 (adopt-project.py: a non-default--spec-pathor--code-pathis ignored by the adopted Makefile'sCONTRACTS_DIRand by the cross-leg follow-up path #522). (source) - 576/2: the scaffold's
declared-unverifiedWARNING offers a sibling checkout and--link-source, neither of which the scaffold has. Where: scripts/repo_shape.py_chain_link_findings(:1455-1463); scaffold-project.py :854. Effort S; all. On main26c1600: Main'stest_scaffold_keeps_its_old_warning_for_a_pin_source_with_no_manifestpasses, and it pins the scaffold printing "(a sibling checkout, SHAPE_PIN_SOURCE_OPENXDOX, or --link-source openXdox= ...)";scaffold-project.py --helphas no--link-source, :854 passesroot=None, and validate-repository-naming.py, repo_shape.py, validate-pins.py: a bare--link-sourceis the first chain link's tree alone, and a source that names no path is refused (#441, #442) #576's head keeps the text. (source)
Rides along (backlog; tick it here if the same change covers it)
- L2-30: the scaffold's
declared-unverifiedWARNING prints--pin-sourceraw, so an ESC in the path reaches stderr. Where: scripts/repo_shape.pylink_declarations(:2670-2710, for example :2703); scaffold-project.py:877. Effort S; all. On main26c1600: Measured at 26c1600:--pin-sourceatx\x1b[31mRED, whoseproject.yamlholdsneutral_product_pins: 5, gave rc 0 and a raw\x1b[31min the WARNING on stderr; neither scaffold-project.py and adopt-project.py: a pin recordsdigest_source: local-cloneand never the--pin-sourcepath, so no committed pin file holds a local directory, and a--pin-sourcenothing reads ispin-source-unused(#540) #570 nor validate-repository-naming.py, repo_shape.py, validate-pins.py: a bare--link-sourceis the first chain link's tree alone, and a source that names no path is refused (#441, #442) #576 changeslink_declarations, and repo_shape.py is a shape copy (scripts/shape_materialize.py:1896), so the fix moves a digest. (source) - L2-31: the root's
validate-pins.pyprints an unused--pin-sourceas typed; an ESC reaches the terminal. Where: templates/assembly-root/scripts/validate-pins.py:1074 (main), :1224 (validate-pins.py and validate-family.py: THE LOCKSTEP RULE closes the count only where a leg or member is out of step, a lone digest or workflow-reference mismatch names itsbump-leg.pyline, and holder remedies branch first (#539) #575 0680799), :1090 (validate-repository-naming.py, repo_shape.py, validate-pins.py: a bare--link-sourceis the first chain link's tree alone, and a source that names no path is refused (#441, #442) #576 c8b1c45). Effort S; all. On main26c1600: Measured at 26c1600 on a freshly scaffolded root:validate-pins.py --pin-source <dir named x\x1b[31mRED>printednote --pin-source …x\x1b[31mRED: not usedraw; validate-pins.py and validate-family.py: THE LOCKSTEP RULE closes the count only where a leg or member is out of step, a lone digest or workflow-reference mismatch names itsbump-leg.pyline, and holder remedies branch first (#539) #575 and validate-repository-naming.py, repo_shape.py, validate-pins.py: a bare--link-sourceis the first chain link's tree alone, and a source that names no path is refused (#441, #442) #576 both edit this pinned file and leave the line as it is. (source) - L2-39: THE LOCKSTEP RULE names
family.py bump --member <Project> --to <commit>with no--family-rootor branch step. Where: templates/family-root/scripts/validate-family.py:100-105 (main and validate-pins.py and validate-family.py: THE LOCKSTEP RULE closes the count only where a leg or member is out of step, a lone digest or workflow-reference mismatch names itsbump-leg.pyline, and holder remedies branch first (#539) #575 0680799). Effort S; all. On main26c1600: The sentence is unchanged at validate-pins.py and validate-family.py: THE LOCKSTEP RULE closes the count only where a leg or member is out of step, a lone digest or workflow-reference mismatch names itsbump-leg.pyline, and holder remedies branch first (#539) #575's head;bump's--family-rootisrequired=True(scripts/family.py:4949); and validate-pins.py and validate-family.py: THE LOCKSTEP RULE closes the count only where a leg or member is out of step, a lone digest or workflow-reference mismatch names itsbump-leg.pyline, and holder remedies branch first (#539) #575's_switch_line(:124-140 at 0680799) givesaddandremovethe branch step but not this sentence. (source)
Each line above is marked → this issue on its tracking issue. Tick it there too when this closes.
The lines as written on the tracking issues
L2-33 (P3; templates/assembly-root/AGENTS-shape.md, #572 review): the pinned AGENTS-shape.md says the root Makefile exports
$(CURDIR)/spec/contracts, which is untrue for a non-default adoption and for every scaffolded root.
templates/assembly-root/AGENTS-shape.md:78-81at 9ddb7ef: "the root Makefile exports$(CURDIR)/spec/contractsonce". The scaffold appends no such block: withscaffold-project.py --spec-path legs/spec,make contracts-dirsays "No rule". An adoption exports its own spec path after adopt-project.py: the Makefile blockexecuteappends and the cross-leg follow-up name each leg where the plan mounts it, so--spec-path legs/specexports aCONTRACTS_DIRthat exists and a nested--code-pathgets the right../path (#522) #572.- The file must stay placeholder-free (
scripts/shape_materialize.py:446-452), so the fix is path-free wording. It changes a pinned copy: each root's nextupdate-shape.py checkshows oneupstream-changed AGENTS-shape.mdrow, whichapplyre-copies. That is an ordinary update, not a conflict.- Sequence it after bootstrap.py: a leg detached off the pin is left where it is and said, so a commit made there is no longer stranded when its branch is already at the pin, the
not moving an existing branchline names where the checkout is, and bump-leg.py and AGENTS-shape.md say "or says why not" (#533) #556, which edits the same file at:83-97. The adopt half is next to the adopt-project.py: a non-default--spec-pathor--code-pathis ignored by the adopted Makefile'sCONTRACTS_DIRand by the cross-leg follow-up path #522 line on Tracking: adopt-project.py, converting an existing repository in place #457.
The scaffold's
declared-unverifiedWARNING names remedies the scaffold lacks: "(a sibling checkout, SHAPE_PIN_SOURCE_, or --link-source = would let it be read)".
scaffold-project.pyhas no--link-source, and reads no sibling checkout: it callslink_pins_from_trees(chain, None, ...).- The text is
_chain_link_findings' (scripts/repo_shape.py).- It neighbours L2-25 above, which is about setup's step (4).
L2-30 (P3; scripts/repo_shape.py, #570 review): the scaffold's chain WARNING
declared-unverifiedprints--pin-sourceraw, so an ESC in the path reaches stderr.
scripts/repo_shape.py:2693-2709buildsf"{path}: ..."inlink_declarations, andscaffold-project.py:829prints it, at 79dfd33.- Repro (
review570-79dfd33/fix-list.md, U1): a clone atx<ESC>[31mREDwhoseproject.yamlholdsneutral_product_pins: 5exits 0 with a raw ESC on stderr. This confirms w540's note.- Direction: spell the path as
pin-source-unreadabledoes for a path that is not printable.
L2-31 (P3; templates/assembly-root/scripts/validate-pins.py, #570 review): the root's
validate-pins.pyprints--pin-sourceas typed in its "not used" note, and an ESC reached the terminal.
templates/assembly-root/scripts/validate-pins.py:1074at 79dfd33:f"--pin-source {typed}: not used ...". Evidence:review570-79dfd33/tools/xver-out/validate-pins-esc-note.txt.- It is a pinned copy, unchanged by scaffold-project.py and adopt-project.py: a pin records
digest_source: local-cloneand never the--pin-sourcepath, so no committed pin file holds a local directory, and a--pin-sourcenothing reads ispin-source-unused(#540) #570, so a change re-pins every root once.- Direction: spell
typedbefore printing, and bundle it with the next change to this file (Pinned validators: THE LOCKSTEP RULE only where it applies, and remedies that name thegit switch -cstep (one shape bump) #539 edits the same file) so roots re-pin once.
L2-39 (nit; templates/family-root/scripts/validate-family.py, #575 writer): the holder's THE LOCKSTEP RULE sentence names
family.py bump --member <Project> --to <commit>with no--family-rootand no branch step.
templates/family-root/scripts/validate-family.py:100-105at 93b68f6. Since family.pyadd,bumpandremovecommit straight onto the holder's tracking branch, andadd's NEXT pushes a<branch>that does not exist, though AGENTS.md says to land each as a pull request #487 a realbumprefuses the holder's tracking branch, and run from the standard's checkout it needs the holder's path. Pinned validators: THE LOCKSTEP RULE only where it applies, and remedies that name thegit switch -cstep (one shape bump) #539 gives theaddandremoveremedies theswitch -cline (_switch_line,:119-131) but not this sentence. The unfinished rv539 simulation confirms it.- Direction: give the sentence the same
git -C <holder> switch -c family/bump-<member>line and the holder's path. It is a pinned copy, so bundle it with the next change to the file.
Activity
brettheap commentedon Oct 15, 2026
CLAIMED — lane openRepoShape-2, session 81650e29-c906-4fe8-96c9-55580bfe0c44@Eagle, 2026-10-15T18:25:56Z, for #610
Logged in
lanes/log/openRepoShape-2.mdat0f4beb29762df57451633c064f7eaacebb1678c8.The three reads (lane-collision-protocol Rule 1):
family.py and validate-family.py: where an earlier act left the branc…
Merge origin/main f6376d7 into fix/610-pinned-text, so the PR's pinne…
AGENTS-shape.md: says where a source's own Makefile leaves the `CONTR…
repo_shape.py: `git_out` names the folder git ran in with `shown_path…
repo_shape.py: git_out's docstring says which controls git 2.43 repla…
Merge main a524542 (#638, #635, #640) into fix/610-pinned-text: remed…
family.py and validate-family.py: where an earlier act left the branc…
Merge main 95780dd (#637, #607) into fix/611-validate-family-head-git…
validate-family.py and family.py: a gitlink no section of HEAD's `.gi…
Merge main 95780dd (#638, #635, #640, #623, #637) into fix/610-pinned…
Merge main c6122e8 (#639) into fix/610-pinned-text: _check_member_git…
Pinned shape copies: one bump, so AGENTS-shape.md is true of every ro…
1 remaining item
adopt-project.py: `_git_out_exact` refuses in the pinned `git_out`'s …
Merge main 2fac979 into fix/648-bootstrap-and-gate-order: #634's per-…
Merge #682's head 45c512e into fix/681-validate-family-remedies: `_ch…
family.py init: git's words in the commit-identity refusal are spelle…
bootstrap.py and validate-family.py: a member no credential would che…
family.py init: the creator is asked whether a file can hold it which…
bump-leg.py: the branch is read in full and pushed as `refs/heads/<b>…
validate-pins.py and repo_shape.py: a pin, the manifest, a shape copy…
bootstrap.py: the `merge --ff-only`, `--continue` and `--abort` lines…
validate-pins.py and repo_shape.py: `--root` and gh's stderr are spel…
validate-pins.py and repo_shape.py: gh's stderr that is not UTF-8 is …
the family root's siblings.py and bootstrap.py: a member's path this …
the assembly root's validate-manifest.py and bootstrap.py: a path thi…
validate-family.py: `git-not-runnable` counts only an `OSError` that …
tests/test_path_guard_hygiene.py and shape-doctor.py: a bare is_file/…