Repository navigation
Adopt the three-repository shape: openRepoTools-spec and openRepoTools-code - #344
Merged
Merged
Conversation
…s-code openRepoTools keeps its name, its identity and its full history and becomes the assembly root of the project. The two legs are NEW repositories extracted with `git filter-repo`, so every moved file keeps the commits that made it. Nothing was deleted: what leaves this tree arrives in a leg at the same path, mounted back here at spec/ and code/. MOVED TO THE SPEC LEG (openRepoTools-spec @ de756faf8797): docs/ ideation/ openspec/ specs/ MOVED TO THE CODE LEG (openRepoTools-code @ d9e7d568011b): .github/ .gitmodules claude-current claude-restart-check commands/ contracts/ lane lane-end lane-handoff lane-rename lane-start lane-worktrees lanes lanes-edit.sh lanes-index link-estates openRepoTools park pyproject.toml repos.tsv resume skills/ src/ status tests/ upstream/ STAYS IN THE ASSEMBLY ROOT: .gitattributes .gitignore AGENTS.md CLAUDE.md LICENSE README.md WRITTEN BESIDE, NOT OVER (this repository had the name first): shape/README.md <- the shape's README.md shape/AGENTS.md <- the shape's AGENTS.md shape/CLAUDE.md <- the shape's CLAUDE.md shape/.gitignore <- the shape's .gitignore shape/.gitattributes <- the shape's .gitattributes APPENDED TO .gitattributes, after this repository's own lines, which are unchanged (each pinned copy outside shape/ checks out with LF, as the pin records it): /scripts/validate-pins.py text eol=lf /scripts/validate-manifest.py text eol=lf /scripts/bootstrap.py text eol=lf /Makefile text eol=lf /.github/workflows/validate.yml text eol=lf /AGENTS-shape.md text eol=lf /scripts/repo_shape.py text eol=lf /scripts/validate-repository-naming.py text eol=lf /contracts/repository-naming.yaml text eol=lf FOLLOW-UPS, which this commit does NOT do: - .github/workflows/release.yml in the code leg names `docs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `docs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - claude-current in the code leg names `docs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `docs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - lane-start in the code leg names `docs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `docs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - lanes-edit.sh in the code leg names `docs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `docs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - openRepoTools in the code leg names `docs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `docs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/conftest.py in the code leg names `docs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `docs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/run.sh in the code leg names `docs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `docs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/test_install_skill_and_hook.py in the code leg names `docs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `docs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - … and 9 more file(s) under the code leg naming `docs/` - tests/test_release_workflow.py in the code leg names `ideation/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `ideation/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - .github/workflows/release.yml in the code leg names `openspec/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `openspec/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - lane-handoff in the code leg names `openspec/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `openspec/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - lanes-edit.sh in the code leg names `openspec/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `openspec/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/conftest.py in the code leg names `openspec/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `openspec/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/test_lane_helpers.sh in the code leg names `openspec/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `openspec/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/test_release_workflow.py in the code leg names `openspec/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `openspec/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/test_test_roots.py in the code leg names `openspec/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `openspec/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - .github/workflows/release.yml in the code leg names `specs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `specs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - openRepoTools in the code leg names `specs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `specs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/conftest.py in the code leg names `specs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `specs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/test_install_payload_source.py in the code leg names `specs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `specs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/test_package_stamp.py in the code leg names `specs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `specs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/test_park_resume_commands.py in the code leg names `specs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `specs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/test_release_workflow.py in the code leg names `specs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `specs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - tests/test_repo_hygiene.py in the code leg names `specs/`, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan's `legs.code_path` mounts it, to `specs/` in the spec leg, where `legs.spec_path` mounts it — or take the path from the environment - … and 1 more file(s) under the code leg naming `specs/` - keep the block at the end of .gitattributes that opens with `# openRepoShape (#471): the pinned shape copies below check out with LF everywhere, as contracts/shape-pin.yaml records their bytes`: the source repository already has a .gitattributes, so the shape's copy was written beside it as shape/.gitattributes, which governs only its own directory, and the split appends one `text eol=lf` line to .gitattributes for each pinned copy outside it. That block is what makes every checkout, Windows included, write those copies with the bytes contracts/shape-pin.yaml records; without it a Windows clone reports shape-copy-drift on each one. None of the source's own lines is changed. Merge the rest of shape/.gitattributes into .gitattributes only if the whole project should check out with LF, and only then remove shape/.gitattributes: `update-shape.py check` reports its pin row `merged-away`, and `apply` drops the row - merge shape/.gitignore into .gitignore: the source repository already has that name, so the shape's copy was written beside it and NOTHING was overwritten. Then remove shape/.gitignore: `update-shape.py check` reports its pin row `merged-away`, and `apply` drops the row - add the line `Read AGENTS-shape.md first — the rules of this repository's shape.` to the existing AGENTS.md rather than replacing it with shape/AGENTS.md: AGENTS.md is what this project's agents ALREADY read, and `contracts/path-classification.yaml` keeps it at the root (`root-assistant-instructions`) because it addresses the whole project. Then delete shape/AGENTS.md. Nothing was overwritten. - add the line `Read AGENTS-shape.md first — the rules of this repository's shape.` to the existing CLAUDE.md rather than replacing it with shape/CLAUDE.md: CLAUDE.md is what this project's agents ALREADY read, and `contracts/path-classification.yaml` keeps it at the root (`root-assistant-instructions`) because it addresses the whole project. Then delete shape/CLAUDE.md. Nothing was overwritten. - merge shape/README.md into README.md: the source repository already has that name, so the shape's copy was written beside it and NOTHING was overwritten - review the root's diff together with openRepoTools-spec and openRepoTools-code, the two new repositories `execute` creates and pushes before the split; against GitHub it opens the split's pull request itself, whose base is the plan's `tracking_branch`, the branch the assembly root and both legs track - Preserve original .gitmodules, upstream/openRepoShape gitlink and contracts/openreposhape-pin.yaml together in code; rehearse existing-submodule extraction/removal and recursive bootstrap before real execution. Never weaken blob verification or edit the standard in place. - Add an assembly openRepoTools compatibility entry point after byte-preserving split verification; resolve one immutable code pin for all installer artifacts and preserve OPENREPOTOOLS_REPO/REF forks, raw/gh and offline checkout behavior. - Separate code, assembly and spec roots in test fixtures and hygiene checks; code CI must supply the exact compatible spec/assembly context where a test reads product documentation. - Current .specify and agent links are ignored local bootstrap artifacts, not the 200-file source tree; capture local configuration and regenerate root workflow using setup-openspeckit after manifest/legs are present. - Preserve all branch/PR/worktree and dirty/untracked work; source main extraction does not transport unfinished feature branches. Migrate selected patches to paired feature branches with old-to-new receipts before rebinding lanes. - Review genuine bounded features/<NNN-feature>/openspec/ amendment records explicitly as code; canonical/full proposals and archives remain spec even when created on a feature branch. No existing bounded amendment paths were observed; do not manufacture them for historical features. - Preserve approved original repository/commit/path provenance and verify correspondence to extracted spec identities, repairing relative links, selected OpenSpec roots/stores and paired feature paths without guessing filtered commit hashes. - Use the adopted manual amendment workflow with immediate working Speckit updates and one docs reconciliation issue at the first amendment. Schema, root routing, bootstrap distribution and upstream placement automation are pending in their owners; do not patch pinned shape copies or assume other workstations are updated. - Reconcile the tested migration net effect and all amendment dispositions in one final docs batch before completed assembly advancement; prepare docs/code PRs together, link landed code/evidence, close reconciliation after docs landing, and archive only after implementation and assembly pins land. - The wheel declares license-files = ["LICENSE"] relative to pyproject.toml, which moves to the code leg while LICENSE stays in the root: apply T006 code-0001 (the code leg's byte-identical LICENSE, .gitattributes and front door) in openRepoTools-code inside the cutover, right after execute and before the code leg's first package or release run. At the cutover, as the owner's acts: create the testpypi and pypi environments and the tag ruleset in openRepoTools-code, add a test.pypi.org trusted publisher for openRepoTools-code, and add a pypi.org pending publisher naming openRepoTools-code, release.yml and the pypi environment (#228).
|
Sorry @brettheap, your pull request is larger than the review limit of 150,000 diff characters |
…S.md opens with the shape's pointer and a short map of the three repositories, README.md gains them and the lockstep invariant, and every path that crossed into a leg names that leg. Rehearsal patch for #186, task T006 of specs/004-migrate-to-triad/tasks.md, against run C's rehearsed split 69b8924. Nothing under shape/ and no file with a row in contracts/shape-pin.yaml is touched. - AGENTS.md: line 1 is the exact pointer that openRepoShape 7f84ca4's SHAPE_POINTER_LINE and its adopt follow-up require. A seven-entry map follows: spec, code, this root, the tests, the lane tooling's code and manual, paired feature worktrees, and the local-rehearsal file-transport flag. The original AGENTS.md comes after it, unchanged except for 16 path repairs (docs/ -> spec/docs/, openspec/ -> spec/openspec/, and upstream/, contracts/, tests/ and .github/ -> code/...). 316 -> 340 lines. - README.md: a "Three repositories" section and "The lockstep invariant", which contracts/{spec,code}-pin.yaml's `resync_runbook: README.md#the-lockstep-invariant` names and which only shape/README.md carried. The install section now says the one-liner is unchanged and that the installer is code/openRepoTools. 12 path repairs, and the pin-bump block re-rooted with `cd code`. 486 -> 510 lines. - .gitignore: the shape's `.venv/` and `.DS_Store` merged in, and `/worktrees/`, the line the three-leg bootstrap requires. - .gitattributes: the same `* text=auto eol=lf` rule, re-explained for this root's pinned copies. The installer reason moved with its files to code/.gitattributes. - CLAUDE.md is unchanged: "Read AGENTS.md." is byte-identical to the shape's own rendered shape/CLAUDE.md. The two length caps in code/tests/test_repo_hygiene.py, 316 and 486, are today's counts. Once T009 points those tests at the assembly root, each cap is raised in a dated entry naming the rule its lines bought. Re-cut on 2026-10-19 (lane openRepoTools-1) against the root files #228's series leaves, 006-release-pypi-t025 b3aab89 with 006-release-pypi-pr3fix c6cea2a merged in (neither main 55aae16 nor 006-release-pypi d10cfb1 changes the four), and the .gitattributes block openRepoShape 190133d's split appends, headed `# openRepoShape (#471): ...`. Seven hunks had stopped applying where #227, #237 and #228 rewrote the lines around them: AGENTS.md's skip-no-lane-guard repair and its three under CI ruling 1, ruling 3 and the bash 3.2 paragraph, and README.md's install sentence and its `code/tests/run.sh` and `code/commands/swap.md` repairs. Each keeps its own lines, re-anchored one for one, so the repairs are still 16 and 13: ruling 1's `.github/workflows/tests.yml`, in the sentence #227 and #228 rewrote, is one of them, and no other line added since names a path that crossed into a leg. .gitattributes' last paragraph no longer says no path is listed by name, because the #471 block after the rule names nine; it says the block stays last. AGENTS.md 330 -> 354 lines and README.md 505 -> 529; the assembly-root caps move with them in t009-assembly-caps.patch. Lane: openRepoTools-1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ch runs the code leg's suite composed and refuses any absent context. validate.yml is a pinned shape copy, so the job lives in composed.yml. T010 of specs/004-migrate-to-triad/tasks.md (#186). Lane: openRepoTools-1
…e runs, so the suite's zsh cases run instead of skipping (part of #186) Root follow-up, part of #186, applied at T014 of specs/004-migrate-to-triad/tasks.md. Gate C's sentence names it "the zsh install in composed.yml", right after T010's exact-pin job, the commit before this one, which creates the file. What changes. One step in the exact-pins job of .github/workflows/composed.yml, after the manifest and pin checks and before the test runner's install: apt-get update and apt-get install zsh, then command -v zsh and zsh --version, so the run's log names the zsh the suite ran with. No other step and no other file changes. Why. On ubuntu-24.04 a composed run skips 66 conditional cases: 60 that need zsh, 1 byte-count case and 5 wheel cases. Of the three ways offered, accept the skips, fail the job on any skip, or install zsh, Brett Heap chose to install it. The 60 cases then run, and 6 skips remain, as in rehearsal D's composed run on a bench that has zsh; the suite's -rs still lists each one. Not pinned. The job already takes its runner image and python 3.x as the runner provides them, and pins the actions, the test runner and the commits this root records; the zsh step prints the version it got. Lane: openRepoTools-1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ation the code pin names and nothing else. T007 of specs/004-migrate-to-triad/tasks.md (#186). The documented one-liners fetch openRepoTools from this repository's root, and after the split the installer is the code leg's. This file keeps that line working and adds no installer mechanics. In a checkout it requires the pin, the gitlink and the implementation's bytes to name one commit, and then execs code/openRepoTools with every argument. That is the same process, so the exit status and signals are the implementation's. Anywhere else it resolves the ref once and reads contracts/code-pin.yaml at that commit. It checks that the gitlink at the pin's submodule_path in that commit is the pinned commit, so the lockstep rule is enforced here and not left to whichever code a stale pin selects. Only then does it fetch openRepoTools from the pinned repository at the pinned commit, and run it from stdin with OPENREPOTOOLS_REF set to that commit, so the implementation reads the same pin. The pin reader is a deliberate copy of the implementation's, guarded by the code leg's tests/test_install_payload_source.py. Lane: openRepoTools-1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
de756faf8797 -> 3c3816210b91, tree bc2d1813f9c60bc6119d2f724a947276527b46b4bf4c8c8b4068cc6a8eac8089. No workflow reference names this leg, so the gitlink and the pin file are the whole of it. The gitlink at spec, `commit:` and `digests.tree_sha256` in contracts/spec-pin.yaml, and every workflow reference to opensoft/openRepoTools-spec move in ONE commit because `scripts/validate-pins.py` refuses when they disagree — a gitlink advanced alone is red on the next pull request, and on somebody else's change. Written by openRepoShape's `scripts/bump-leg.py`; the digest is recomputed from the leg's own objects, not adjusted. Cutover: #186
d9e7d568011b -> 2a057a6d84e5, tree 31123e2d08efe36583e72956ed8b8dbbe4b968c75402b59af5b8952be83ef6d5. No workflow reference names this leg, so the gitlink and the pin file are the whole of it. The gitlink at code, `commit:` and `digests.tree_sha256` in contracts/code-pin.yaml, and every workflow reference to opensoft/openRepoTools-code move in ONE commit because `scripts/validate-pins.py` refuses when they disagree — a gitlink advanced alone is red on the next pull request, and on somebody else's change. Written by openRepoShape's `scripts/bump-leg.py`; the digest is recomputed from the leg's own objects, not adjusted. Cutover: #186
…UDE.md and shape/README.md, and its CLAUDE.md now carries the line that points to AGENTS-shape.md, as AGENTS.md already does (part of #186) Root follow-up, part of #186 and the last follow-up in Gate C's sentence ("the shape/*.md deletion"), applied at T014 of specs/004-migrate-to-triad/tasks.md. It deletes three files, adds one line to a fourth, and changes no other path. What changes. shape/AGENTS.md, shape/CLAUDE.md and shape/README.md are deleted, and CLAUDE.md gains the line that points to AGENTS-shape.md, the line AGENTS.md already carries. It is CLAUDE.md's new first line, where T006's assembly-0001 puts it in AGENTS.md, and the file's old line follows it unchanged. Why the three copies can go. The adoption plan's follow-ups 29, 30 and 31 ask for that line to be added to AGENTS.md and to CLAUDE.md, with the shape's copy of each then deleted, and for shape/README.md to be merged into README.md. T006's assembly-0001, already in this root, added the line to AGENTS.md ahead of a short map of the three repositories, and gave README.md the sections on the three repositories and the lockstep invariant, which only shape/README.md carried. It leaves CLAUDE.md alone, so CLAUDE.md gets its line here, and with the three deletions all three follow-ups are done. None of the three copies is a pinned shape file: contracts/shape-pin.yaml has no row for them, and this commit does not touch it. What stays. shape/.gitignore, its row in contracts/shape-pin.yaml and the .gitignore comment that calls that copy pinned and left in place are as they were, and nothing else under shape/ changes. The plan's follow-up 28, which merges shape/.gitignore into .gitignore and then removes it, is its own root change after the root-split pull request merges, made with update-shape.py apply, which also drops the pin row. Why it is made on the root and not as a patch. shape/README.md carries the root's clone URL, a local path in rehearsal D and the GitHub URL in the real split, so a deletion patch cut on rehearsal D's bytes would not apply to the real split. Made on the real root clone, the commit needs no such base: git rm takes the three files whatever their bytes, and the one added line does not depend on the URL. Why this slot. As the cutover's last follow-up it goes on the root after the two commits that bump the assembly root's pins of the spec and code legs, which Gate C's order puts before it, and before the root's push to the split's pull request branch, so that the checks run on the root before that push already see the three deletions and the new line. Lane: openRepoTools-1 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3c3816210b91 -> 64a1a989fe7b, tree 0aa2803cf44fc7494369144ff85aa93d79ac713314ea0c9fdcbfdb3ced1fb055. No workflow reference names this leg, so the gitlink and the pin file are the whole of it. The gitlink at spec, `commit:` and `digests.tree_sha256` in contracts/spec-pin.yaml, and every workflow reference to opensoft/openRepoTools-spec move in ONE commit because `scripts/validate-pins.py` refuses when they disagree — a gitlink advanced alone is red on the next pull request, and on somebody else's change. Written by openRepoShape's `scripts/bump-leg.py`; the digest is recomputed from the leg's own objects, not adjusted. Cutover: #186
|
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Adopt the three-repository shape: openRepoTools-spec and openRepoTools-code
openRepoTools keeps its name, its identity and its full history and becomes the assembly root of the project. The two legs are NEW repositories extracted with
git filter-repo, so every moved file keeps the commits that made it. Nothing was deleted: what leaves this tree arrives in a leg at the same path, mounted back here at spec/ and code/.MOVED TO THE SPEC LEG (openRepoTools-spec @ de756faf8797):
docs/
ideation/
openspec/
specs/
MOVED TO THE CODE LEG (openRepoTools-code @ d9e7d568011b):
.github/
.gitmodules
claude-current
claude-restart-check
commands/
contracts/
lane
lane-end
lane-handoff
lane-rename
lane-start
lane-worktrees
lanes
lanes-edit.sh
lanes-index
link-estates
openRepoTools
park
pyproject.toml
repos.tsv
resume
skills/
src/
status
tests/
upstream/
STAYS IN THE ASSEMBLY ROOT:
.gitattributes
.gitignore
AGENTS.md
CLAUDE.md
LICENSE
README.md
WRITTEN BESIDE, NOT OVER (this repository had the name first):
shape/README.md <- the shape's README.md
shape/AGENTS.md <- the shape's AGENTS.md
shape/CLAUDE.md <- the shape's CLAUDE.md
shape/.gitignore <- the shape's .gitignore
shape/.gitattributes <- the shape's .gitattributes
APPENDED TO .gitattributes, after this repository's own lines, which are unchanged (each pinned copy outside shape/ checks out with LF, as the pin records it):
/scripts/validate-pins.py text eol=lf
/scripts/validate-manifest.py text eol=lf
/scripts/bootstrap.py text eol=lf
/Makefile text eol=lf
/.github/workflows/validate.yml text eol=lf
/AGENTS-shape.md text eol=lf
/scripts/repo_shape.py text eol=lf
/scripts/validate-repository-naming.py text eol=lf
/contracts/repository-naming.yaml text eol=lf
FOLLOW-UPS, which this commit does NOT do:
docs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, todocs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentdocs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, todocs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentdocs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, todocs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentdocs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, todocs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentdocs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, todocs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentdocs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, todocs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentdocs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, todocs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentdocs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, todocs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentdocs/ideation/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, toideation/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentopenspec/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, toopenspec/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentopenspec/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, toopenspec/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentopenspec/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, toopenspec/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentopenspec/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, toopenspec/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentopenspec/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, toopenspec/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentopenspec/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, toopenspec/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentopenspec/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, toopenspec/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentspecs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, tospecs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentspecs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, tospecs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentspecs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, tospecs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentspecs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, tospecs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentspecs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, tospecs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentspecs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, tospecs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentspecs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, tospecs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentspecs/, which moves to the spec leg: it must read across the assembly root — from the code leg, where the plan'slegs.code_pathmounts it, tospecs/in the spec leg, wherelegs.spec_pathmounts it — or take the path from the environmentspecs/# openRepoShape (#471): the pinned shape copies below check out with LF everywhere, as contracts/shape-pin.yaml records their bytes: the source repository already has a .gitattributes, so the shape's copy was written beside it as shape/.gitattributes, which governs only its own directory, and the split appends onetext eol=lfline to .gitattributes for each pinned copy outside it. That block is what makes every checkout, Windows included, write those copies with the bytes contracts/shape-pin.yaml records; without it a Windows clone reports shape-copy-drift on each one. None of the source's own lines is changed. Merge the rest of shape/.gitattributes into .gitattributes only if the whole project should check out with LF, and only then remove shape/.gitattributes:update-shape.py checkreports its pin rowmerged-away, andapplydrops the rowupdate-shape.py checkreports its pin rowmerged-away, andapplydrops the rowRead AGENTS-shape.md first — the rules of this repository's shape.to the existing AGENTS.md rather than replacing it with shape/AGENTS.md: AGENTS.md is what this project's agents ALREADY read, andcontracts/path-classification.yamlkeeps it at the root (root-assistant-instructions) because it addresses the whole project. Then delete shape/AGENTS.md. Nothing was overwritten.Read AGENTS-shape.md first — the rules of this repository's shape.to the existing CLAUDE.md rather than replacing it with shape/CLAUDE.md: CLAUDE.md is what this project's agents ALREADY read, andcontracts/path-classification.yamlkeeps it at the root (root-assistant-instructions) because it addresses the whole project. Then delete shape/CLAUDE.md. Nothing was overwritten.executecreates and pushes before the split; against GitHub it opens the split's pull request itself, whose base is the plan'stracking_branch, the branch the assembly root and both legs track