diff --git a/openspec/changes/migrate-to-triad/design.md b/openspec/changes/migrate-to-triad/design.md index a51ee15..ff01b5c 100644 --- a/openspec/changes/migrate-to-triad/design.md +++ b/openspec/changes/migrate-to-triad/design.md @@ -15,6 +15,15 @@ that branch work. Preserve its contracts, external launcher ownership and unmet runtime gates during replay. Removed worktrees are not an active replay queue. The [inventory](../../../specs/004-migrate-to-triad/inventory.json) is a snapshot. +*Updated 2026-10-26, in the cutover's final spec reconciliation batch (T015, under +opensoft/openRepoTools#186):* this is the preliminary baseline. The cutover ran from `main` +`33ce26dffc5286e68f1d29ab5c6458edef0330c0` (200 tracked paths, 156 commits) with openRepoShape +`190133d5e704e380c430f87ca9c4e31746de0012` (v1.1.0), on the plan regenerated for that source +and approved at Gate C. Its +[published copy](../../../specs/004-migrate-to-triad/adoption-plan-cutover-2026-10-26.yaml) +and the [as-built record](../../../specs/004-migrate-to-triad/cutover-as-built-2026-10-26.md) +set this baseline against the cutover's. The paragraph above stays as written, as history. + ## Goals / Non-Goals Preserve project identity/history, all user work, installed command behavior @@ -47,6 +56,10 @@ paths: 18 spec, 40 code, six root, none dropped, with 28 follow-ups. It records and the dependency lock. Product documentation/OpenSpec/Speckit go to spec. Root owns front-door guidance, license, project metadata and workflow bootstrap. +*Updated 2026-10-26, in the same batch:* the cutover's plan accounts for 200 paths, 108 +spec, 86 code, six root, none dropped, with 42 follow-ups (the note under Context). The +`adoption-plan.yaml` linked above is now run C's rehearsal input, as its own header says. + Genuine bounded feature amendment records at `features//openspec/` are the narrow code exception. Review them explicitly with reasoned resolutions until the upstream rule is qualified. @@ -121,9 +134,11 @@ and shape placement automation are pending, not delivered by this migration. Code CI runs implementation checks; root CI validates manifest/pins and the exact composed assembly. Supply explicit code/spec/assembly roots to tests that inspect docs or history; preserve the nested dependency pin assertions -in the code Git repository. Use the canonical serialized `tests/run.sh`, -Bash 3.2 parsing and current platform/fixture timing policies. Missing-spec -context cannot turn a required integration check into a silent skip. +in the code Git repository. Use the canonical `tests/run.sh` with the +Linux-only policy and serialized `tests/run.sh` locking, the bash 3.2 parse +living in `release.yml`'s macOS install leg, and current fixture timing +policies. Missing-spec context cannot turn a required integration check into +a silent skip. Prepare code/spec PRs together. At the first bounded amendment create one spec reconciliation issue; collect net tested effects, all dispositions, dated diff --git a/openspec/changes/migrate-to-triad/specs/repository-triad-migration/spec.md b/openspec/changes/migrate-to-triad/specs/repository-triad-migration/spec.md index f5ff667..3cd2c3b 100644 --- a/openspec/changes/migrate-to-triad/specs/repository-triad-migration/spec.md +++ b/openspec/changes/migrate-to-triad/specs/repository-triad-migration/spec.md @@ -42,10 +42,10 @@ Original worktrees and installed tools SHALL remain available until acceptance. ### Requirement: Installation retains the public interface and one revision -Existing one-line installation, command names, payload destinations/modes, -skills/hooks/receipts and supported fork/ref/local invocation SHALL remain -usable. An adopted assembly entry point SHALL resolve one immutable code -revision for the complete installation. Missing/inconsistent pin evidence +The migration SHALL keep the existing one-line installation, command names, +payload destinations/modes, skills/hooks/receipts and supported fork/ref/local +invocation usable. An adopted assembly entry point SHALL resolve one immutable +code revision for the complete installation. Missing/inconsistent pin evidence SHALL refuse before partial installation. Installed tools SHALL function without a developer assembly checkout. diff --git a/specs/004-migrate-to-triad/adoption-plan-cutover-2026-10-26.yaml b/specs/004-migrate-to-triad/adoption-plan-cutover-2026-10-26.yaml new file mode 100644 index 0000000..6d36a59 --- /dev/null +++ b/specs/004-migrate-to-triad/adoption-plan-cutover-2026-10-26.yaml @@ -0,0 +1,485 @@ +# The cutover plan for opensoft/openRepoTools (#186): FP, G5's final plan, sha256 94af9924ebbf58aad5b916528e3e2f76e6f588acd0d65cff5efe534fdadaf2d9, +# generated 2026-10-22 from source 33ce26dffc5286e68f1d29ab5c6458edef0330c0 (main) with openRepoShape adopt-project.py at +# 190133d5e704e380c430f87ca9c4e31746de0012 (v1.1.0). This copy is FP byte for byte but its local_path line. +# Authority: Brett Heap's Gate C sentence, approved 2026-10-23T11:01:55Z in lane 1's session, relayed in +# #186 comment 6363430219. Generated metadata authorizes nothing (FR-012), and execution_authorized +# below is false in every copy this script writes; whether and when execute ran is recorded elsewhere. +# Paths are relative to the source checkout (local_path published as "."). +schema_version: 1 +kind: adoption-plan + +# Written by `adopt-project.py plan`. IT IS MEANT TO BE EDITED. +# Every entry with `review_required: true` carries a `question:`; a +# human or an AI answers it by setting `leg:` to spec, code, root or +# drop and adding one line of `resolution:` beside it. `check` then +# has to pass, and `execute` REFUSES while any leg is still null. +# An entry whose rule names a default arrives with it as its `leg:` +# and `execute` takes it as written: confirm it or change it. + +generated_on: 2026-10-22 +tool: opensoft/openRepoShape adopt-project.py + +# `cloned: true` says `plan` cloned `repository` into `local_path`, so +# `check` and `execute` clone it again where that clone is gone or no +# longer whole. A path given to `plan` is never cloned again. +source: + repository: opensoft/openRepoTools + local_path: . + cloned: false + default_branch: main + commit: "33ce26dffc5286e68f1d29ab5c6458edef0330c0" + files: 200 + bytes: 9368104 + commits: 156 + +# The adopted repository KEEPS its name, its identity and +# its history and becomes the assembly root. `new-root` — a new +# root with the source reduced to one leg — is not implemented +# in v0.2; the field records which posture this plan took. +mode: in-place + +project: openRepoTools +org: opensoft +id: openrepotools +visibility: public +tracking_branch: main +adopt_branch: adopt/three-repo-shape +elected_by: "Brett Heap" +elected_on: "2026-10-04" +reference: "openxFactory docs/project-repo-schema.md" + +legs: + assembly: openRepoTools + spec: openRepoTools-spec + code: openRepoTools-code + spec_path: spec + code_path: code + +# Neutral products this project declares a pin on. A +# `` assembly root is a DESCENDANT only when +# its `open` is listed here (2026-09-02). Each pin was +# read by `plan --pin @<40 hex commit>`: the commit, and +# the `sorted-ls-tree-r-v1` digest of the product's tree there. +# `execute` writes `contracts/-pin.yaml` from +# them, as `scaffold-project.py --pin` does, and reads no network +# for them. To change a pin, re-run `plan`: a commit or a digest +# edited here is one nobody read (#273). +pins: [] + +# A leg that NO entry below assigns a path to is SEEDED from the +# shape's own leg template as one initial commit, instead of being +# extracted: `git filter-repo` over an empty path list yields an +# empty HISTORY, which is not an empty repository. The split still +# mounts it. This block RECORDS what the entries said when the plan +# was written; `check` and `execute` re-derive it from the entries, +# which are edited afterwards, and the entries always win. +seeding: + spec: + seeded_from_template: false + code: + seeded_from_template: false + +# Seeding a leg is EXPLICIT HUMAN INTENT, so `execute` refuses to do +# it unless the leg is named here (or on its own command line) with +# `--allow-empty-leg `. A repository that turns out to have no +# code is a fact worth confirming; a plan that lost every code path +# to a bad edit looks exactly the same from here. +allow_empty_legs: [] + +paths: + - path: .gitattributes + leg: root + confidence: high + rule: root-front-door + reason: "What a person or a forge reads BEFORE deciding which leg to open. The licence and the code of conduct govern all three repositories; the README is the front door of the thing an engineer clones." + files: 1 + bytes: 1857 + review_required: false + - path: .github/ + leg: code + confidence: medium + rule: consensus + reason: "every file under this path classifies as code, by 2 different rules: code-ci-workflows, extension-majority" + files: 4 + bytes: 139923 + review_required: false + - path: .gitignore + leg: root + confidence: high + rule: root-front-door + reason: "What a person or a forge reads BEFORE deciding which leg to open. The licence and the code of conduct govern all three repositories; the README is the front door of the thing an engineer clones." + files: 1 + bytes: 38 + review_required: false + - path: .gitmodules + leg: code + confidence: review + rule: ambiguous-gitmodules + reason: "`.gitmodules` is where a repository registers its submodules. Each registration and the gitlink it names are one fact recorded in two places, and which leg those dependencies belong to is a fact about this repository." + files: 1 + bytes: 121 + review_required: true + question: "When a repository is adopted, a source's own `.gitmodules` goes to the SAME leg as every submodule it registers; `execute` writes the assembly root a fresh one for its two mounts. Which leg owns the submodules, spec or code? Send `.gitmodules` there and every submodule path with it, or drop them all together. A submodule it does not register with a path and a url cannot be kept in a leg at all: drop it, or register it first. Any one submodule may also be dropped on its own; its registration stays behind in that leg, inert. `root` is not an answer for this file or for any submodule, and `adopt-project.py` refuses a plan that gives it, as it does a plan that splits them." + resolution: "Keep existing nested dependency registration with its upstream gitlink in code; assembly spec/code registrations are generated separately." + - path: AGENTS.md + leg: root + confidence: high + rule: root-assistant-instructions + reason: "The AI-assistant instruction files and their one-file directories are the same document ten times over, and it addresses the whole project. An assistant that read it from inside the code leg would be told about specifications it cannot see. Root, ruled 2026-09-02." + files: 1 + bytes: 22361 + review_required: false + - path: CLAUDE.md + leg: root + confidence: high + rule: root-assistant-instructions + reason: "The AI-assistant instruction files and their one-file directories are the same document ten times over, and it addresses the whole project. An assistant that read it from inside the code leg would be told about specifications it cannot see. Root, ruled 2026-09-02." + files: 1 + bytes: 16 + review_required: false + - path: LICENSE + leg: root + confidence: high + rule: root-front-door + reason: "What a person or a forge reads BEFORE deciding which leg to open. The licence and the code of conduct govern all three repositories; the README is the front door of the thing an engineer clones." + files: 1 + bytes: 11357 + review_required: false + - path: README.md + leg: root + confidence: high + rule: root-front-door + reason: "What a person or a forge reads BEFORE deciding which leg to open. The licence and the code of conduct govern all three repositories; the README is the front door of the thing an engineer clones." + files: 1 + bytes: 33634 + review_required: false + - path: claude-current + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 31059 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable installer payload added by merged PR #134; keep resolver/checker with commands and their implementation tests in code." + - path: claude-restart-check + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 12933 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable installer payload added by merged PR #134; keep resolver/checker with commands and their implementation tests in code." + - path: commands/ + leg: code + confidence: medium + rule: extension-majority + reason: "no rule names this path; the `.md` extension is classified as spec by the policy's extension table" + files: 3 + bytes: 8906 + review_required: false + resolution: "These Markdown command files are shipped runtime installer payloads with implementation tests, not OpenSpec or Speckit decisions." + - path: contracts/ + leg: code + confidence: high + rule: spec-governance + reason: "Requirements, decisions, contracts and governance prose — what the project has DECIDED, as opposed to what it currently runs. `contracts/` is here by the 2026-09-02 ruling even where the code reads it: the code reads across the assembly-root mount, which is what the legs are mounted for." + files: 1 + bytes: 3299 + review_required: false + resolution: "At this baseline the only contract is openreposhape-pin.yaml, a dependency lock coupled to the code gitlink and installer; future product governance contracts belong in spec and assembly pins are generated at root." + - path: docs/ + leg: spec + confidence: high + rule: spec-governance + reason: "Requirements, decisions, contracts and governance prose — what the project has DECIDED, as opposed to what it currently runs. `contracts/` is here by the 2026-09-02 ruling even where the code reads it: the code reads across the assembly-root mount, which is what the legs are mounted for." + files: 5 + bytes: 422160 + review_required: false + - path: ideation/ + leg: spec + confidence: medium + rule: extension-majority + reason: "no rule names this path; the `.md` extension is classified as spec by the policy's extension table" + files: 12 + bytes: 49679 + review_required: false + resolution: "Feature ideation and brainstorm packets are planning prose about what the project is deciding, not shipped payload; spec beside openspec/, specs/ and docs/, as the October 6 rehearsal assigned it." + - path: lane + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 87092 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: lane-end + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 155090 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: lane-handoff + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 190970 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: lane-rename + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 17116 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: lane-start + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 289777 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: lane-worktrees + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 309126 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: lanes + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 47924 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: lanes-edit.sh + leg: code + confidence: medium + rule: extension-majority + reason: "no rule names this path; the `.sh` extension is classified as code by the policy's extension table" + files: 1 + bytes: 1139720 + review_required: false + - path: lanes-index + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 126026 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: link-estates + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 21694 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: openRepoTools + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 273347 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: openspec/ + leg: spec + confidence: high + rule: spec-governance + reason: "Requirements, decisions, contracts and governance prose — what the project has DECIDED, as opposed to what it currently runs. `contracts/` is here by the 2026-09-02 ruling even where the code reads it: the code reads across the assembly-root mount, which is what the legs are mounted for." + files: 35 + bytes: 313926 + review_required: false + - path: park + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 60184 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: pyproject.toml + leg: code + confidence: high + rule: code-build-manifests + reason: "A build, package, lint or analysis manifest describes how the implementation is built and measured. `sonar-project.properties` names source and coverage paths, so it follows the sources it names." + files: 1 + bytes: 5230 + review_required: false + - path: repos.tsv + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 2651 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Runtime alias data installed beside the lane commands." + - path: resume + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 79282 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: skills/ + leg: code + confidence: medium + rule: extension-majority + reason: "no rule names this path; the `.md` extension is classified as spec by the policy's extension table" + files: 3 + bytes: 95875 + review_required: false + resolution: "These three skills are installed product payloads; project workflow skills remain local root bootstrap artifacts." + - path: specs/ + leg: spec + confidence: high + rule: spec-governance + reason: "Requirements, decisions, contracts and governance prose — what the project has DECIDED, as opposed to what it currently runs. `contracts/` is here by the 2026-09-02 ruling even where the code reads it: the code reads across the assembly-root mount, which is what the legs are mounted for." + files: 56 + bytes: 908456 + review_required: false + - path: src/ + leg: code + confidence: high + rule: code-source-and-tests + reason: "The implementation, the tests that hold it, and the scripts and images that build and run it. `scripts/` moves whole: a harness that reads `contracts/` from beside it reads them across the root mount afterwards, which is a code change the plan records as a follow-up rather than a reason to split the directory." + files: 3 + bytes: 6343 + review_required: false + - path: status + leg: code + confidence: review + rule: default + reason: "No rule matched and the file extensions did not agree. This is the honest answer, not a failure: the tool has said what it does not know, at the exact path where it does not know it." + files: 1 + bytes: 359720 + review_required: true + question: "Which leg owns this path — spec, code, or the assembly root? Answer by editing `leg:` and writing one line into `resolution:` beside it." + resolution: "Executable product command; keep with its sibling helpers and installation payload in the code repository." + - path: tests/ + leg: code + confidence: high + rule: code-source-and-tests + reason: "The implementation, the tests that hold it, and the scripts and images that build and run it. `scripts/` moves whole: a harness that reads `contracts/` from beside it reads them across the root mount afterwards, which is a code change the plan records as a follow-up rather than a reason to split the directory." + files: 52 + bytes: 4141212 + review_required: false + - path: upstream/ + leg: code + confidence: review + rule: ambiguous-gitmodules + reason: "`.gitmodules` is where a repository registers its submodules. Each registration and the gitlink it names are one fact recorded in two places, and which leg those dependencies belong to is a fact about this repository." + files: 1 + bytes: 0 + review_required: true + question: "When a repository is adopted, a source's own `.gitmodules` goes to the SAME leg as every submodule it registers; `execute` writes the assembly root a fresh one for its two mounts. Which leg owns the submodules, spec or code? Send `.gitmodules` there and every submodule path with it, or drop them all together. A submodule it does not register with a path and a url cannot be kept in a leg at all: drop it, or register it first. Any one submodule may also be dropped on its own; its registration stays behind in that leg, inert. `root` is not an answer for this file or for any submodule, and `adopt-project.py` refuses a plan that gives it, as it does a plan that splits them. This entry holds the submodule(s) `upstream/openRepoShape`: it is asked this question, not classified by its rule `default`." + resolution: "Mounted openRepoShape is the implementation/test dependency; preserve its exact gitlink with the original .gitmodules and dependency pin." + +follow_ups: + - ".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//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 (opensoft/openRepoTools#228)." + +summary: + spec: + files: 108 + bytes: 1694221 + file_share: 0.5400 + byte_share: 0.1808 + code: + files: 86 + bytes: 7604620 + file_share: 0.4300 + byte_share: 0.8118 + root: + files: 6 + bytes: 69263 + file_share: 0.0300 + byte_share: 0.0074 + unresolved: + files: 0 + bytes: 0 + file_share: 0.0000 + byte_share: 0.0000 +planning_status: cutover-record-not-an-approval +execution_authorized: false diff --git a/specs/004-migrate-to-triad/candidate-2026-10-09.md b/specs/004-migrate-to-triad/candidate-2026-10-09.md index 7b63eb6..43ad183 100644 --- a/specs/004-migrate-to-triad/candidate-2026-10-09.md +++ b/specs/004-migrate-to-triad/candidate-2026-10-09.md @@ -51,6 +51,30 @@ main `f87fd5a` only in the implementation it hands over to. `f87fd5a`. Its tree, `d77e80b3`, is `8246983`'s, and `openRepoTools` is blob `7aa697c` at `cddd1f7`, `8246983` and `a74c7fc` alike. So r3 measured the code now on `main`. +*Updated 2026-10-26, in the cutover's final spec reconciliation batch (T015, under +opensoft/openRepoTools#186): the candidate since this record.* This is r2's record, with +r3's in section 9, and it is not refreshed in its sections 2 to 5 form. The candidate of +record at Gate C is rehearsal D's: D's record, `adopter-rehearsal-2026-10-21.md`, gives it +in its section "The candidate (stage 4, v0)". That record is on the evidence branch +`004-migrate-to-triad-rehearsal-d` of opensoft/openRepoTools, at `94f8a3c`, until a +spec-only continuation (T017) carries it into this leg. What the cutover itself built is +in [cutover-as-built-2026-10-26.md](cutover-as-built-2026-10-26.md), beside this record. +The sections below stay as written, as history. + +*Updated 2026-10-26, in the cutover's final spec reconciliation batch (T015, under +opensoft/openRepoTools#186): the opensoft/openRepoTools#180 pointers.* Lines 261, 262, +282, 316 and 380 of this record, as it was at `33ce26d`, name opensoft/openRepoTools#180 +for the row-stamp cases that fail under `tests/run.sh`'s long run root. That issue was +closed with opensoft/openRepoTools#215 (`61a7378`), which moved only `repoA11b`'s tail +case. The cases it left are opensoft/openRepoTools#304's: `repoA-1` and `repoCase-1` +(`tests/test_lane_helpers.sh:1272` and `:8552` at `33ce26d`; rehearsal D's record, P3), +and `repoMIX-1` (`:8645`), which lane 3 found on 2026-10-22 (opensoft/openRepoTools#186 +comment 6342130291). Their fix is the code leg's `1e6f2d1`, merged by +opensoft/openRepoTools-code#1 as `2a057a6d` on 2026-10-26. So read those five lines as +pointers to opensoft/openRepoTools#304. Line 404 is a list of the issues read with `gh`, +and stays as it is. The lines stay as written, as history. Lane 3 named the 18 pointers of +this kind, in four files (opensoft/openRepoTools#186 comment 6332521834). + ## 1. Inputs Every input was read without checking it out in any existing worktree. Patches were @@ -115,6 +139,11 @@ results stand as recorded. The files at those paths are now the regenerated and not results for them. A third code-leg patch, T009's `t009-assembly-caps.patch` (`2dd4aac2…b2bbe5`), goes on after steps 10 and 11 and sets the assembly-root length caps the re-cut needs. +*Noted 2026-10-26 (step 14; lane 3's NIT 2 on opensoft/openRepoTools#299, comment 6317075196):* step 14 +applied the earlier `t010-assembly-exact-pin-job.patch` (`6ee09f00…74670b`), and its result stands as +recorded; the file at that path is now the one regenerated on 2026-10-21 for the runner pin +(`60245cb9…f0f653`), so that result is not a result for it. + What was checked at each step: - **The PR commits are the PR heads.** Every path #190 touches has `b50f197`'s blob after diff --git a/specs/004-migrate-to-triad/cutover-as-built-2026-10-26.md b/specs/004-migrate-to-triad/cutover-as-built-2026-10-26.md new file mode 100644 index 0000000..15f25fb --- /dev/null +++ b/specs/004-migrate-to-triad/cutover-as-built-2026-10-26.md @@ -0,0 +1,292 @@ +# The cutover as built — October 26, 2026 + +**For:** T015 of [tasks.md](tasks.md), under +[opensoft/openRepoTools#186](https://github.com/opensoft/openRepoTools/issues/186). It is the +as-built record of the final spec reconciliation batch, which T015 asks for with "net tested +effects, every amendment disposition, dated departures/as-built record, archived approval +provenance, deferred issues and actual landed code/evidence" (`tasks.md:110–113`). No task is +checked complete by this record, and it approves nothing. +**Writer:** lane openRepoTools-1, 2026-10-26, for the batch that S15 item 8 of the cutover's +runbook lands. +**Sources:** the cutover's private run folder, `cutover-20261026-r6`: its `exits.txt` (through +line 109, `S14 root-head green` at 22:13:08Z), `execute.log` and the S4 to S14 records they +name, `s14-root-head-1` among them. Lane 1's relays on opensoft/openRepoTools#186 (comments +6417706286, 6421077855, 6421955767, 6423405883, 6424440846, 6425830987, 6427399285 and +6428789445), and lane 2's read-only repeat of S12 (6427616680). Brett Heap's words, and their +times, are quoted from lane 1's record of his rulings, by round. +**What it covers:** the cutover through S12, and S14 as it stood at S12's head. +**What it cannot cover:** T015's items 1 to 6, this batch's own merge and the close of its +reconciliation issue, S15's approved bump push, the root-split merge and Gate D all come after +this record lands (section 9). + +## 1. The baseline, against the cutover's + +`openspec/changes/migrate-to-triad/design.md:5–7` and `:44–45`, and `plan.md:18–24`, give the +preliminary baseline. The cutover's is the one Brett Heap approved at Gate C (section 7). + +| | The preliminary baseline | The cutover's | +| --- | --- | --- | +| Source | `main` `daed20957f2dd2f22cca24053bb5bc8636ff6b3f`: 64 tracked paths, 80 commits | `main` `33ce26dffc5286e68f1d29ab5c6458edef0330c0`: 200 tracked paths, 156 commits | +| Standard | openRepoShape `39d5c986fcfac1a160474bfe91c5f1c37fccc72c`, inspected | openRepoShape `adopt-project.py` at `190133d5e704e380c430f87ca9c4e31746de0012` (v1.1.0) | +| Placement | 18 spec, 40 code, six root, none dropped | 108 spec, 86 code, six root, none dropped | +| Follow-ups | 28 | 42 | +| Plan | the change's `adoption-plan.yaml` of that day | FP, generated 2026-10-22, sha256 `94af9924ebbf58aad5b916528e3e2f76e6f588acd0d65cff5efe534fdadaf2d9`, whose published copy is [adoption-plan-cutover-2026-10-26.yaml](adoption-plan-cutover-2026-10-26.yaml) | + +- **The published copy** is S4's: FP's bytes but for its `local_path` line, which reads `.`, + under a seven-line header that names FP's sha256 and Gate C's approval, and with two closing + lines, `planning_status: cutover-record-not-an-approval` and `execution_authorized: false`; + 485 lines, sha256 `538e2521eaaeff8f99e4de7c3af26e016488cb53f1169aacab934a3062e5f66a`. Its + header calls it "FP byte for byte but its local_path line"; the header and the two closing + lines are S4's additions as well. Its `execution_authorized` is `false`, as in every copy S4 + writes: this record says when `execute` ran. S4's own regeneration from the source differed + from FP only in `generated_on` and `local_path`, and its `check` gave `plan ok`, with no + finding, no refusal and one note. +- **The change's `adoption-plan.yaml`** is now run C's rehearsal input (source `837928a`, 120 + paths, 29 follow-ups, openRepoShape `7f84ca4`), as its own header says. It is not the + cutover's plan. + +## 2. What the cutover did, S1 to S12 + +All times are 2026-10-26, UTC, from `exits.txt` unless a relay is named. + +| Step | Time | What it did | +| --- | --- | --- | +| S1 | 13:52:26Z | The approval record and the notice of the hold, opensoft/openRepoTools#186 comment 6417706286, on Brett Heap's start (round 23, 13:44:57Z). `main` was `33ce26d`. | +| S2 to S5 | 16:12:44Z to 16:13:52Z | In the second run folder (section 8, departure 2): S1's register read again (result 0), the clones, identity and tools, the before-setup observation (exit 0), and S4's `decisions`, `plan`, `resolve`, `check`, `publish` and `check-published`, each exit 0. | +| S10's inputs | 16:13:58Z | The legs' and the root's inputs checked against their sums. | +| S6 | 16:15:13Z | The gate record, every line OK (comment 6421077855). Its A2 read found brettheap/new-workstation#62 merged, with six notes. | +| The go word | 16:41:38Z | "go de8fda1a", typed in lane 1's session after Brett Heap chose "Go: start S7 now" (round 25, 16:21:50Z); recorded at 16:42:10Z. | +| S7 | 16:42:24Z to 16:47:03Z | The HOLD on `main`; `execute` once, from 16:43:35Z to 16:44:23Z, exit 0; the HOLD released (comment 6421955767). | +| S7b | 16:48:05Z | The legs' first pushes, read from GitHub's rule suites (section 3). | +| S8 | 16:49:00Z | The root's pinned doctor, on a recursive clone of the split: `COMPLIANT (exit 0)`. | +| S9 | 16:50:37Z | The independent accounting and checks: `RESULT PASS`. | +| S14, raw | 17:00:12Z and 17:52:00Z | The runs on the raw split, recorded as runs on the raw split, not evidence for the cutover (comment 6423405883). | +| S13, acts 1 and 4 | 18:39:51Z to 18:48:37Z | Brett Heap's words for act 1 (SonarCloud bound to `openRepoTools-code`) and act 4: the code leg's `testpypi` and `pypi` environments and its tag ruleset 25903054, read back at 18:40:47Z, then the two PyPI publishers (comment 6424440846). | +| S10, the legs | 18:41:09Z to 18:42:24Z | Rows 1, 2, 3 and 3a pushed to `004-migrate-to-triad-code-follow-ups`, and row 4 to `004-migrate-to-triad-spec-follow-ups`; opensoft/openRepoTools-code#1 and opensoft/openRepoTools-spec#1 opened. | +| S14, code-pr | 19:50:24Z | The code PR's run read green (section 3). | +| S10, the code merge | 19:50:47Z | opensoft/openRepoTools-code#1 merged by merge commit, as `2a057a6d84e58c8acb4bda20d2b7b667b552c3fe` (comment 6425830987). | +| S14, code-main | 21:04:36Z | The merged code leg's push run read green (section 3). | +| S10, the spec merge | 21:04:55Z | opensoft/openRepoTools-spec#1 merged by merge commit, as `3c3816210b912759b350f77c2128e39f628edc39`. | +| S10, the root | 21:05:32Z | Rows 5, 6, 6a and 7 on a fresh clone of the split branch, at `96130bef…`, not pushed. | +| S11 | 21:06:10Z to 21:06:16Z | Rows 8 and 9, the two bumps, each after its `--dry-run`. | +| S12 | 21:06:34Z to 21:09:04Z | Row 10; the local checks; the HOLD (21:07:31Z); the one push of `adopt/three-repo-shape`, a fast-forward from the split to `fe7841b2…` (21:08:12Z); the same checks on GitHub's branch (21:09:00Z); the HOLD released at 21:09:04Z (comment 6427399285). | + +No step from S1 to S12 wrote a STOP or a WAIT. + +## 3. The net tested effects + +**`execute` and its first pushes (S7, S7b).** +- `execute` ran once and exited 0. It created `opensoft/openRepoTools-spec` and + `opensoft/openRepoTools-code`, both public, default branch `main`, and pushed each leg's + `main`: the spec leg at `de756faf8797ea4ee598bf2a9cee84f2b358fa67` (69 commits kept) and the + code leg at `d9e7d568011b339e8d4bb87f3f83f58ec653794a` (145 commits kept). Both equal + rehearsal D's tips (`MATCH`). +- It pushed the split, `f36db81076b9d14d9d03baf4311d9b4e3bbe1234`, to + `adopt/three-repo-shape` of opensoft/openRepoTools and opened its pull request, + opensoft/openRepoTools#344, on `main`. The split's author and committer are Brett Heap, with + N1's address. `main` stayed at `33ce26d`. +- It wrote the shape's five files beside the source's own (`shape/README.md`, + `shape/AGENTS.md`, `shape/CLAUDE.md`, `shape/.gitignore` and `shape/.gitattributes`), + overwriting nothing, and appended to the root's `.gitattributes` one `text eol=lf` line for + each of the 9 pinned copies. +- Its own verification found every source path of `33ce26d` in exactly one place, by blob: + spec 108, code 86, root 6 and drop 0, with 18 new paths. +- The topic `xf-project-openrepotools` is on all three repositories. +- GitHub's rule suites recorded each leg's creation push as `pass` (spec, suite 4729675498 at + 16:43:53Z; code, 4729678569 at 16:44:02Z), and org ruleset 18834180 stayed at its pinned + baseline. + +**The checks of the raw split (S8, S9).** +- S8: `COMPLIANT (exit 0)`. Every row was `ok` but `machine` (`n/a`) and a `note`: neither leg + held `AGENTS.md`, `CLAUDE.md` or `.gitignore` yet. +- S9, on all 200 entries of `33ce26d`: spec 108, code 86 and root 6, none missing, duplicated + or misplaced; 22 assembly additions; the root's `.gitattributes` the source's blob + `3560973e9d45` plus the 9-line block, giving `a9ac338e09f6` (`MATCH`); the nested + openRepoShape at `190133d`, whose pin digest is + `7a66972c7de193c050f77f97bffa13d8543c28d74f61ea210644e65aa3f37912` (`MATCH`); `bootstrap ok`, + `manifest ok` with 3 legs, and `pins ok`, with 11 copied shape files matching; every tree + clean after validate. In the spec leg, openspec 1.6.0 passed all 6 changes, and openspec + 1.2.0 passed 3 and failed `interactive-lane-name-repair`, `migrate-to-triad` and + `release-tags-pypi`. + +**The runs on the raw split (S14, raw), recorded and not judged.** The root's `validate` passed +at the split (run 40361977131). The code leg's push run at `d9e7d568…` (40361975522) failed in +all four jobs, because the leg held no `LICENSE` and no `.gitattributes` yet; row 1 adds both. + +**The follow-ups (S10 to S12),** in the order applied. Every commit's author and committer are +Brett Heap with N1's address; every patch applied with `git apply --check` and +`git am --3way`, exit 0, no hunk rejected; and each patch-id equals its file's. + +| Row | Leg | Follow-up | Commit | Through | +| --- | --- | --- | --- | --- | +| 1 | code | T006 `code-0001`: the leg's own front door, and the LF rule, ignore list and licence it lost when the root kept them | `6314fc8d1cd852b3027c54e172300392b6e3eaeb` | opensoft/openRepoTools-code#1 | +| 2 | code | T010: the regenerated `tests.yml` patch, naming the leg's standalone checkout context | `bc7c8318f2bd01bad49bd2d1a9b508a7f458f98b` | opensoft/openRepoTools-code#1 | +| 3 | code | T009: the assembly root's two length caps, 354 and 529 | `6c53c9ec14f02e81bcdd4a50ecceb7c4cadf66a0` | opensoft/openRepoTools-code#1 | +| 3a | code | opensoft/openRepoTools#304's fix, the tenth follow-up: the row-stamp cases no longer answer by the length of `run.sh`'s `TMPDIR` | `1e6f2d1327712d0c17d51b897cb067781aa5685a` | opensoft/openRepoTools-code#1, merged as `2a057a6d…` | +| 4 | spec | T006 `spec-0001`: the leg's own front door, the LF rule and licence, and the claude-current manual's three test paths re-pointed at the code leg | `be77322ec7ef40cea580e6f046b255b0f8428571` | opensoft/openRepoTools-spec#1, merged as `3c381621…` | +| 5 | root | T006 `assembly-0001`, re-cut: the front door resolves the split's collisions | `ebe3940cee50ec00bd6df422db35825f55f77f5f` | `adopt/three-repo-shape`, opensoft/openRepoTools#344 | +| 6 | root | T010: the exact-pin integration job, `composed.yml` | `ce703eda6146bacdccce98a06b9a1457fcad2a4c` | the same | +| 6a | root | zsh installed in `composed.yml`, on Brett Heap's ruling on Ask 5 | `9e5cca256c66739fe6500f5be1671fa8d7965033` | the same | +| 7 | root | T007 v3: the assembly's `openRepoTools` front door | `96130bef8405ae3995adc768cd963ed4dc570c4a` | the same | +| 8 | root | the spec bump, to `3c381621…`, by `bump-leg.py` | `78f9783e0b6991f00707478a84f729314e3ce0d0` | the same | +| 9 | root | the code bump, to `2a057a6d…`, by `bump-leg.py` | `a057b23832326451ac998ffd6315d081d4b0d50f` | the same | +| 10 | root | the three `shape/*.md` copies deleted, and `CLAUDE.md`'s line that points to `AGENTS-shape.md` | `fe7841b26891cada6858a1da04cfab3b1b53d3e3` | the same | + +- **The legs' merges** are merge commits of S7's tip and the reviewed head, with the head's + tree: the code leg's `196299f14b2c2f5904813afdaf52c1aa103ef38d` and the spec leg's + `b576f694fc158af2494567367a04d73a9baf7f3a`, the two trees S10 requires. Their author is Brett + Heap with N1's address, and their committer is GitHub. No merge setting was changed. +- **The bumps** each changed only its leg's gitlink and pin file, and each carries + `Cutover: opensoft/openRepoTools#186`. The spec pin's tree digest is + `bc2d1813f9c60bc6119d2f724a947276527b46b4bf4c8c8b4068cc6a8eac8089`, rehearsal D's, and the + code pin's is `31123e2d08efe36583e72956ed8b8dbbe4b968c75402b59af5b8952be83ef6d5`. +- **Row 10's** name-status is `M CLAUDE.md` and `D` for the three copies, and `CLAUDE.md`'s + diff is its one added first line. + +**The code leg's runs (S14).** +- `code-pr`, at `1e6f2d1…`, run 40380065869 (18:42:09Z to 19:49:59Z): `guard-launch-mode`, + `tests`, `tests-no-submodule` and `package` each `success`, and `SonarCloud Code Analysis` + passed. `tests-no-submodule` skipped 977: 884 for its own no-submodule reason, 60 for no + zsh, 18 for a file of another root, 9 for composed acceptance, 5 for the built wheel and 1 + for the byte count. `tests` skipped 93. +- `code-main`, at `2a057a6d…`, push run 40390350509 (19:50:42Z to 21:04:13Z): the same four + jobs `success`, with the same skips. + +**The root at S12's head, `fe7841b2…`.** +- `root-check.sh s12`, on a local recursive clone (21:07:13Z) and on GitHub's branch + (21:09:00Z): `bootstrap ok`; `make validate` with `manifest ok` and `pins ok`; the + `composed` workflow's context step exit 0; no tracked file changed after validate; the legs + at S11's targets and the nested openRepoShape at `190133d`; `AGENTS.md` 354 lines and + `README.md` 529. The doctor gave `COMPLIANT (exit 0)`, with one `note`: the spec leg has no + `.gitignore`. +- Lane 2 repeated these checks read-only, on its own recursive clone of GitHub's branch, and + every one passed at `fe7841b2…`; row 10 is its reviewed diff and message byte for byte + (comment 6427616680). + +## 4. S14 at S12's head + +At `fe7841b26891cada6858a1da04cfab3b1b53d3e3`, opensoft/openRepoTools#344's `validate` run, +40401761883, passed. Its `composed` workflow's `exact-pins` job, run 40401761978, passed too +(21:08:08Z to 22:11:59Z): 3003 passed and 6 skipped, in 1:02:10. The 6 skips are the most +that Brett Heap's ruling on Ask 5 leaves, and they are its cases: the five wheel cases of +`tests/test_package.py`, with `OPENREPOTOOLS_TEST_WHEEL` unset, and the byte-count case of +`tests/test_precision_90a_96.py`. S14 `root-head` read both runs green at 22:13:08Z. This is +T015's first look at S12's head: item 1 reads the runs again at the exact head, after this +batch's bump push. SonarCloud's check on opensoft/openRepoTools#344 is red, and no step +reads it (comment 6427399285). + +## 5. The landed code and evidence + +| Repository | Ref | Commit | Tree | State at S12's head | +| --- | --- | --- | --- | --- | +| opensoft/openRepoTools-spec | `main` | `3c3816210b912759b350f77c2128e39f628edc39` | `b576f694fc158af2494567367a04d73a9baf7f3a` | opensoft/openRepoTools-spec#1 merged; this batch lands on it | +| opensoft/openRepoTools-code | `main` | `2a057a6d84e58c8acb4bda20d2b7b667b552c3fe` | `196299f14b2c2f5904813afdaf52c1aa103ef38d` | opensoft/openRepoTools-code#1 merged | +| opensoft/openRepoTools | `adopt/three-repo-shape` | `fe7841b26891cada6858a1da04cfab3b1b53d3e3` | `9245133cfa86aefda40973da1b523d734f0e8552` | opensoft/openRepoTools#344, open on `main`: the split and its seven commits, rows 5 to 10 | +| opensoft/openRepoTools | `main` | `33ce26dffc5286e68f1d29ab5c6458edef0330c0` | | unchanged, under the landing hold until opensoft/openRepoTools#344 merges or is abandoned | +| opensoft/openRepoShape, at `code/upstream/openRepoShape` | gitlink | `190133d5e704e380c430f87ca9c4e31746de0012` (v1.1.0) | `dd0f94e86d8c97bc756335ffb68d3a5fd38c3919` | the pinned standard | + +The rehearsal evidence behind them is the Gate B status walk at rehearsal D, +`gate-b-status-2026-10-22.md`, and D's record, `adopter-rehearsal-2026-10-21.md`, both on the +evidence branch `004-migrate-to-triad-rehearsal-d` of opensoft/openRepoTools (at `b0eb112` and +`94f8a3c`), until a spec-only continuation (T017) carries them into this leg. + +## 6. Every amendment disposition + +Each plan-text amendment that Brett Heap ruled, and where it went. Line numbers are +`33ce26d`'s. + +| Amendment | His ruling | Disposition | +| --- | --- | --- | +| Ask 7(a): the capability spec's installation requirement puts its SHALL first | round 3, 2026-10-22T13:05:08Z | this batch: `openspec/changes/migrate-to-triad/specs/repository-triad-migration/spec.md:45–48` | +| Ask 7(b): "No account move is part of this migration" | round 3 | approved as written: no edit | +| Ask 7(c): the code leg's own `.gitattributes`, added after extraction, and each leg's front-door files | round 2, 2026-10-22T13:01:48Z, "Full amendment (Recommended)" | this batch: `plan.md` § Target placement | +| Ask 7(d): a Linux-only CI, in lane 3's wording | round 3 | this batch: `tasks.md:78–79`, `openspec/changes/migrate-to-triad/design.md:121–126`, `plan.md:127–129` and `:251` | +| Ask 6: the hosted-runner checks move to T015 | round 4, 2026-10-22T13:07:16Z, option 1 | this batch: `tasks.md` T010 | +| Ask 13: the post-cutover one-liner needs api.github.com and `jq` | round 4, "Accept and document it" | not in this batch: a note beside the one-liner in the root's `README.md`, after the root-split merge (round 20) | +| Card 16, option A: feature 005 and opensoft/openRepoTools#97 | round 7, 2026-10-22T14:53:08Z | this batch: `plan.md:89–90` named as overridden | +| Round 20 (1): Gate D's first clause met by receipts; the translations follow the root-split merge | round 20, 2026-10-23T12:24:37Z, "Met by receipts; translate after (Recommended)" | this batch: `plan.md:186–188` and `tasks.md:165–167` named as overridden | +| Round 20 (2): the ruled texts and the dated notes land inside the final batch | round 20, "Inside the final batch (Recommended)" | this batch, with the dated notes that the walk at rehearsal D lists in its section 5, items 1 to 6 | + +## 7. Archived approval provenance + +- **Gate C:** the sentence of 502 words (sha256 + `5883427591c68d43bc9bc60d0dcad47e9252ada84d0a928e14e8f90cd10ea785`), approved by Brett Heap + in lane 1's session on 2026-10-23 at 11:01:55Z (round 16), relayed in + opensoft/openRepoTools#186 comment 6363430219, and quoted byte for byte in S1's post + (6417706286). It names the source, the standard, FP's sha256, the two public legs, the + follow-ups in their order, the work dispositions in the refreshed table from G8's capture + (`dispositions.tsv` v2.1, 181 rows, sha256 + `6d213139882a21e6b48381c8ace5f176443f84f4c1ed3abf4772cbba7d361ccf`), the owner's five acts + and the landing hold. +- **`main` at `33ce26d`:** his "go with option 1", in lane 3's session on 2026-10-26 (comment + 6414151196): `main` reset to `33ce26d` as a one-time exception (section 8, departure 1). +- **The start:** round 23, 2026-10-26T13:44:57Z, "Start now (Recommended)". +- **The second run folder:** round 24, answered by 2026-10-26T14:29:00Z, "Fix S-1 before the go + word (Recommended)", which was his word for a new run folder from S2. +- **The go word:** round 25, "Go: start S7 now" at 16:21:50Z, then "go de8fda1a" typed at + 16:41:38Z, naming the runbook scripts' `SHA256SUMS` digest `de8fda1a…`. +- **Acts 1 and 4:** his words in lane 1's session at 18:39:51Z, "act 1 done: SonarCloud bound to + openRepoTools-code" and "act 4 GitHub done", and at 18:48:22Z, "act 4 PyPI done: both + publishers exist". +- **The legs' merges:** his standing word "merge all when green for all merges thru v1.1.0" + (opensoft/openRepoTools#228 comment 6303614082), which the Gate C sentence names. +- **N1's identity and the extracted history:** round 20, "History keeps its own + (Recommended)". N1 covers only the commits lane 1 writes, the follow-ups, row 10 and the + bumps; the extracted history keeps each source commit's own author and committer (GitHub is + the committer of 131 of the 156 commits at `33ce26d`). + +## 8. Dated departures + +1. **2026-10-26, before S1: `main` reset.** `main` had moved past `33ce26d` to `ee07c0e`. On + Brett Heap's word, lane 3 pushed it back to `33ce26d` with a lease, a one-time exception to + the no-force-push rule, and opensoft/openRepoTools#341 re-lands in v1.2.0 (comment + 6414151196). The push, at 11:05:25Z, is the week's one org bypass suite (4723125513). It came + before S7 began, so S7b records it and does not count it. +2. **2026-10-26, a second run folder, on the ruling of 14:29Z.** On his round 24 word, the + cutover ran from S2, from 16:12Z, in a new run folder, `cutover-20261026-r6`, on the + runbook as placed at R6 (scripts' `SHA256SUMS` + `de8fda1ae1b3593b62240d16c71e6a2c08018cf26efb32945947c6f2e864ae2d`), which fixes lane 4's + S-1 in `s15-merge.sh`. It reuses S1's post, which had named R5's scripts (`c30c515c…`). The + first folder stays as the record of S1 to S5 there. +3. **S7b: `pass`, not `bypass`.** GitHub recorded each leg's creation push, and ruleset + 18834180's `pull_request` rule, as `pass`. The runbook predicted neither form, and S7b + accepts either. +4. **S14, raw: the code leg's first push run red,** for the two causes the runbook expected; row + 1 removes both. +5. **S11: a new code pin digest.** The code pin's tree digest is new against rehearsal D's, + because the code leg holds row 3a. Rows 3a, 6a and 10 were not rehearsed in D. +6. **S8 and S12: the spec leg has no `.gitignore`.** No row adds one, and the doctor's note stays + for the pass after the cutover. A note does not move the verdict. + +## 9. Deferred issues, and what comes after this record + +**Deferred, as the records stand at S12's head:** +- **opensoft/openRepoTools#304** was open on GitHub when this record was written. Its fix is + the code leg's `1e6f2d1`, row 3a, and `exact-pins` becomes a required check only + after the code-leg bump that carries it (act 3). +- **Feature 005 and opensoft/openRepoTools#97** (card 16, option A): 005's bookkeeping closes as + a spec-only change after the cutover, and the 8 open tasks of opensoft/openRepoTools#97 wait + for a later numbered feature. +- **T016's and T017's translations** follow the root-split merge (round 20 (1)). T017 also + carries the walk at rehearsal D and D's record into this leg. +- **Ask 13's note** goes beside the one-liner in the root's `README.md`, after the root-split + merge (round 20 (2)). +- **T3's second case,** a lockstep-consistent pin at code from before + opensoft/openRepoTools#191, stays a named T015 item (the walk at rehearsal D, line 25). +- **opensoft/openRepoTools#341** re-lands in v1.2.0. +- **The outside-consumer texts W6, S1 and B4** are not approved: round 23 asked again, and his + answer was "Not yet — ask me later". +- **The spec leg's `.gitignore`** (section 8, departure 6). + +**Not yet done at S12's head, and not recorded here:** +- Brett Heap's act 2 (each leg's `main` protected) and act 3 (`exact-pins` required on the + root's `main`), in their windows at S12; act 5, v1.1.0 to PyPI, at S16. +- The delivery of the protocol and commands to Eagle through workBenches, from the + workBenches owner, which the Gate C sentence names, against T006's distribution check and + SC-006. +- T015's items 1 to 6, at the real exact assembled head. +- This batch's PR and merge, and the close of its reconciliation issue in + `opensoft/openRepoTools-spec`, which Brett Heap opens. +- S15's approved bump push of the spec leg's new `main` into the root, and the root-split + merge, on his own explicit word, with a reviewed squash subject and body. +- Gate D. diff --git a/specs/004-migrate-to-triad/gate-ab-evidence-2026-10-09.md b/specs/004-migrate-to-triad/gate-ab-evidence-2026-10-09.md index d036224..6a910fa 100644 --- a/specs/004-migrate-to-triad/gate-ab-evidence-2026-10-09.md +++ b/specs/004-migrate-to-triad/gate-ab-evidence-2026-10-09.md @@ -43,6 +43,21 @@ inventory. Section 7 is what Gate B still lacks. real home or the register. - **Gate B is still open.** Section 7 lists what is missing. +*Updated 2026-10-26, in the cutover's final spec reconciliation batch (T015, under +opensoft/openRepoTools#186): the opensoft/openRepoTools#180 pointers.* Lines 436, 520 and +628 of this record, as it was at `33ce26d`, name opensoft/openRepoTools#180 as what +`composed.yml` must settle before it is relied on, because it runs the suite through +`tests/run.sh`, under whose long run root the row-stamp cases fail. That issue was closed +with opensoft/openRepoTools#215 (`61a7378`), which moved only `repoA11b`'s tail case. The +cases it left are opensoft/openRepoTools#304's: `repoA-1` and `repoCase-1` +(`tests/test_lane_helpers.sh:1272` and `:8552` at `33ce26d`; rehearsal D's record, P3), +and `repoMIX-1` (`:8645`), which lane 3 found on 2026-10-22 (opensoft/openRepoTools#186 +comment 6342130291). Their fix is the code leg's `1e6f2d1`, merged by +opensoft/openRepoTools-code#1 as `2a057a6d` on 2026-10-26. So read those three lines as +pointers to opensoft/openRepoTools#304. The lines stay as written, as history. Lane 3 +named the 18 pointers of this kind, in four files (opensoft/openRepoTools#186 comment +6332521834). + ## 1. Restore rehearsal of the source The source is the Gate A backup `prep-20261007T100559Z` (host-local, read-only). The diff --git a/specs/004-migrate-to-triad/gate-b-checklist.md b/specs/004-migrate-to-triad/gate-b-checklist.md index f7d0a06..9c81821 100644 --- a/specs/004-migrate-to-triad/gate-b-checklist.md +++ b/specs/004-migrate-to-triad/gate-b-checklist.md @@ -199,7 +199,7 @@ not the patches these lines require. | # | Requirement (cite) | Evidence that would satisfy it | Status | | --- | --- | --- | --- | | 32 | "Adapt implementation CI and root exact-pin integration checks with explicit compatible checkout context" (tasks.md:77–78). "The assembly exact-pin integration job must refuse absent required contexts" (installer-design.md:97). design.md:121–126. | Reviewed workflow patches for the code leg and for the assembly root. | **NOBODY.** | -| 33 | "preserve current Linux/macOS/Windows/WSL policies, Bash 3.2 parsing and serialized `tests/run.sh` locking" (tasks.md:78–79). | The patched workflows keep every job of `.github/workflows/tests.yml` at c4864ac and delete no assertion. The jobs are `guard-launch-mode`, `tests` and `tests-no-submodule` (ubuntu-latest), `tests-windows` (windows-latest), and `parse-macos` and `tests-macos` (macos-latest), at tests.yml:52, 72, 126, 157, 232 and 285. *2026-10-21: that is the file at c4864ac, where `ubuntu-latest` was Ubuntu 24.04 (CI run 37571444349 on c4864ac: `Image: ubuntu-24.04`). Since #296 the patched file holds four jobs, `guard-launch-mode`, `tests`, `tests-no-submodule` and `package`, all on `ubuntu-24.04`, at lines 90, 113, 173 and 218 (`gate-b-status-2026-10-09.md`, line 33).* | **NOBODY.** | +| 33 | "preserve current Linux/macOS/Windows/WSL policies, Bash 3.2 parsing and serialized `tests/run.sh` locking" (tasks.md:78–79). | The patched workflows keep every job of `.github/workflows/tests.yml` at c4864ac and delete no assertion. The jobs are `guard-launch-mode`, `tests` and `tests-no-submodule` (ubuntu-latest), `tests-windows` (windows-latest), and `parse-macos` and `tests-macos` (macos-latest), at tests.yml:52, 72, 126, 157, 232 and 285. *2026-10-21: that is the file at c4864ac, where `ubuntu-latest` was Ubuntu 24.04 (CI run 37571444349 on c4864ac: `Image: ubuntu-24.04`). As opensoft/openRepoTools#296 leaves it, the patched file holds four jobs (opensoft/openRepoTools#227 had removed the other three), `guard-launch-mode`, `tests`, `tests-no-submodule` and `package`, all on `ubuntu-24.04`, at lines 90, 113, 173 and 218 (`gate-b-status-2026-10-09.md`, line 33). Worded so on 2026-10-26, for lane 3's NIT 1 on opensoft/openRepoTools#299 (comment 6317075196).* | **NOBODY.** | | 34 | "Verify the exact rehearsed composed state passes required checks and the compatibility matrix, recording failures rather than deleting assertions" (tasks.md:80–81): the part that runs on this host. | `tests/run.sh` and the matrix run against the exact rehearsed assembly, spec, code and standard commits ("Composed candidate evidence", data-model.md:15), with failures recorded. | **NOBODY.** | | 35 | The same clause (tasks.md:80–81): the part that needs GitHub-hosted runners (the `tests-windows`, `parse-macos` and `tests-macos` jobs). | Those jobs' results against the exact rehearsed commits. | **BLOCKED on somewhere GitHub-hosted runners can check the rehearsed commits out from (inferred).** The rehearsed legs exist only in disposable local bare remotes. The suite's checkouts take `submodules: true` (tests.yml:7). #186 allows "no real leg repository … before Gate C". T015 later validates "the real exact assembled head using … required platform/CI" (tasks.md:107–108). | diff --git a/specs/004-migrate-to-triad/gate-b-status-2026-10-09.md b/specs/004-migrate-to-triad/gate-b-status-2026-10-09.md index f6eec7a..532115f 100644 --- a/specs/004-migrate-to-triad/gate-b-status-2026-10-09.md +++ b/specs/004-migrate-to-triad/gate-b-status-2026-10-09.md @@ -70,6 +70,92 @@ MET 25 · PARTLY 20 · OPEN 0 · AFTER-GATE-C 1 (they were 27 · 18 · 0 · 1). 32 and 46). - The measurements are lane 1's, in its private prep of 2026-10-19. The rows say what ran. +**Updated 2026-10-26, in the cutover's final spec reconciliation batch (T015, under +opensoft/openRepoTools#186): superseded.** The Gate B status walk at rehearsal D, +`gate-b-status-2026-10-22.md`, supersedes this walk for the 46 checklist lines. It is on +the evidence branch `004-migrate-to-triad-rehearsal-d` of opensoft/openRepoTools, at +`b0eb112`, until a spec-only continuation (T017) carries it into this leg. Its section 1 +gives each line's status and evidence at rehearsal D, and its section 5 lists what this +file owes. The cells below stay as written, as history, and the counts above are this +walk's of 2026-10-19. What that section 5 owes this file follows. Each entry names the +checklist line, and the line of its cell in this file at `33ce26d`, before this block: +- **Line 29, the cell at `:184` (its item 1, a dated note).** The cell predates `aa14de3`: + opensoft/openRepoTools#195 landed as `aa14de3`, with lane 3's LAND at `fb77bed` and on + the delta to `e378871` (PR reviews 5481360555 and 5508055705) and lane 1's delta LAND + (5484079561), and lane 2 confirmed opensoft/openRepoTools#193's item 15 fixed and the + item-4 refusals holding (opensoft/openRepoTools#186 comment 6103529172). Rehearsal D ran + composed (3009 tests) and standalone, whose 33 skips each name their root. The line is + MET WITH NOTE at D. +- **Line 32, the cell at `:187` (its item 2, lane 3's NIT 4 on + opensoft/openRepoTools#299, comment 6317075196).** The cell names two differences + between the regenerated assembly patch's runner comment and + opensoft/openRepoTools#296's (`THIS` for `EVERY`, and no Python 3.9 clause). There is + a third: the inserted ", which this job's suite runs,". The comment is at the patch's + lines 63–65, and the one it follows at lines 55–57 of `.github/workflows/tests.yml` at + `33ce26d`. +- **Line 31, the cell at `:186` (its item 3).** The cell says that about forty other + conditional skips can still pass a composed run and that none fires on `ubuntu-24.04`. + That is stale: there a composed run skips 66 conditional cases, 60 zsh tests, 1 + byte-count test and 5 wheel tests (lane 2, opensoft/openRepoTools#186 comment + 6327803546). Brett Heap ruled on Ask 5 on 2026-10-22 (round 4) that T014 installs zsh + in `composed.yml`, so that the 60 zsh tests run and 6 skips remain, as in rehearsal D's + composed run on a bench that has zsh. The assembly root's `composed.yml` installs it + from the cutover's root follow-up row 6a (`9e5cca2`). The line is MET WITH NOTE at D + either way, on Brett Heap's round 10 ruling ("Accept without job 5"). +- **The opensoft/openRepoTools#180 pointers, the cells and lines at `:187`, `:189`, + `:327`, `:511` and `:640` (its item 4).** They name opensoft/openRepoTools#180 for the + row-stamp cases that fail under `tests/run.sh`'s long run root, the one `composed.yml`'s + suite inherits. That issue was closed with opensoft/openRepoTools#215 (`61a7378`), which + moved only `repoA11b`'s tail case. The cases it left are opensoft/openRepoTools#304's: + `repoA-1` and `repoCase-1` (`tests/test_lane_helpers.sh:1272` and `:8552` at `33ce26d`; + rehearsal D's record, P3), and `repoMIX-1` (`:8645`), which lane 3 found on 2026-10-22 + (opensoft/openRepoTools#186 comment 6342130291). Their fix is the code leg's `1e6f2d1`, + merged by opensoft/openRepoTools-code#1 as `2a057a6d` on 2026-10-26. So read those five + as pointers to opensoft/openRepoTools#304. Lane 3 named the 18 pointers of this kind, in + four files (opensoft/openRepoTools#186 comment 6332521834). +- **The stale cells and lines (its item 5).** Each is stale against sources now on + opensoft/openRepoTools#186 and `main`, and the walk at rehearsal D gives each line's + update in its section 1: + - Line 2 (`:157`): e4 is approved (opensoft/openRepoTools#186 comment 6313886489), and + rehearsal D's record settles opensoft/openRepoTools#193's item 12 for D's bench, which + has no `ensurepip`, so its venv used `--without-pip`. + - Line 12 (`:167`): the cell names `7f84ca4`, and the pinned openRepoShape is now + `190133d`, whose own checks are green. + - Line 17 (`:172`): the cell leads with 342 passed, where lane 3's review of the re-cut + `assembly-0001` cites 374 on q4d (opensoft/openRepoTools#266's NIT 4, PR comment + 6275785285). It also ties the `.gitattributes` hunk to the nine-path block, where the + hunk's only trailing context is `190133d`'s `EOL_BLOCK_HEAD` line, so a later pin + re-checks it (NIT 1). + - Lines 23, 24 and 29 (`:178`, `:179` and `:184`): item 1's notes, in this block and in + `installer-design.md`. + - Line 25 (`:180`): "CHANGES REQUIRED" and "Not landed" are stale. Lane 3 measured that + the T007 v3 patch meets T3's required change (PR review 5481368376 on + opensoft/openRepoTools#196, finding 1) and LANDed the refold (delta review + 5560058266); opensoft/openRepoTools#191 landed as `a74c7fc`, and + opensoft/openRepoTools#196 as `983d8c7`. + - Line 32 (`:187`): items 2 and 4 in this block. The fix for its residual at D, + opensoft/openRepoTools#304, is the code leg's `1e6f2d1`. + - Line 33 (`:188`): this batch restates T010's platform clause, + `openspec/changes/migrate-to-triad/design.md:121–126` and `plan.md:127–129` and `:251` + in lane 3's wording (Ask 7(d)), the wording the cell says the line can then be met on. + - Line 46 (`:201`): each T006–T010 patch now has its review record (the walk at + rehearsal D, its line 46). + - The "not on `main`" remarks in lines 36 (`:191`), 39 (`:194`) and 40 (`:195`): those + records are on `main` since opensoft/openRepoTools#196 landed as `983d8c7`. + - Line 40's count (`:195`), "7 patches" and "eight files now": `patches/` holds nine + patch files, four at its top and five under `patches/t006/` (lane 2's NIT 7, + opensoft/openRepoTools#186 comment 6333755295). + - Section 4(d) (`:502`, `:504`, `:515–516` and `:529`) names `tests-windows`, + `parse-macos` and `tests-macos`, which opensoft/openRepoTools#227 (`aaa7bc8`) removed. + Restated without them, its basis is this: the code these jobs test ran green on hosted + runners at `33ce26d` (run 39614104431), in four jobs, `guard-launch-mode`, `tests`, + `tests-no-submodule` and `package`; and by Brett Heap's ruling on Ask 6 (2026-10-22, + round 4, option 1) the hosted runs of the code leg's `tests.yml` jobs and of the + assembly's `composed.yml` move to T015, before the root adoption merge. + - The API-call count at `:531` and `:611`, 5 per install, is the T007 v2 patch's. The v3 + patch makes 6 api.github.com requests per install, the root 2 and the implementation 4 + (`installer-2026-10-08.md:234`). + **By:** lane openRepoTools-1's reviewer, under [#186](https://github.com/opensoft/openRepoTools/issues/186). It ran read-only everywhere except this file and its own scratch. A first, unpublished pass was made at 13:27Z–13:50Z; section 1 says which statuses moved since. diff --git a/specs/004-migrate-to-triad/installer-design.md b/specs/004-migrate-to-triad/installer-design.md index 4f17478..47b143b 100644 --- a/specs/004-migrate-to-triad/installer-design.md +++ b/specs/004-migrate-to-triad/installer-design.md @@ -65,6 +65,21 @@ artifacts. Derive counts from the lists; source comments with historical counts are not the contract. Hooks stay in the user's existing settings, preserving unrelated entries. No machine-specific config enters a payload archive. +*Refreshed 2026-10-26, at `33ce26d`, the source of rehearsal D and of the cutover, +whose installer is the code leg's `openRepoTools` byte for byte (blob `ca4fc44`; +the Gate B walk at rehearsal D, line 24):* the counts above are `daed209`'s. +`INSTALLABLES` now holds 17 names (`openRepoTools:1292`), `lanes-index` and +`lane-worktrees` having come with opensoft/openRepoTools#164 and +opensoft/openRepoTools#168, and the three skills (`SKILLS`, `:2280`) and three +command files (`COMMANDS`, `:2293`) each still have two destinations, so an +install places 29 files and writes 29 receipt rows. The two hook entries are +merged only once the path both of them call answers `guard` +(`hook_target_answers`, `:2384`; opensoft/openRepoTools#237): twenty-nine +artifacts always, plus the two hook entries once that path answers (`:57–58`). +Rehearsal D measured it: main's and the candidate's `--install` each said "17 of +17 placed", with 29 receipt rows, and both hook entries were merged with the +gate open and neither with it closed. + ## Compatibility acceptance All rows below are pending measured tests in fresh disposable homes/remotes. @@ -88,6 +103,18 @@ They describe coverage for the existing executable tasks, not completion claims. | Missing nested dependency in standalone code | Existing documented test skips remain; composed acceptance requires complete dependencies. | | Linux/macOS Bash 3.2 and Windows/WSL policies | Correct parses/platform gates; no new Bash features or PowerShell implementation. | +*Dated note, 2026-10-26 (the Gate B walk at rehearsal D, line 23):* the last row +of the table above describes the platform jobs as they were before +opensoft/openRepoTools#227 (`aaa7bc8`), which removed `tests-macos`, +`tests-windows` and `parse-macos` on Brett Heap's decision of 2026-10-15: CI runs +on Linux only, and the one bash 3.2 parse is `release.yml`'s macOS install leg. +Two later installer changes are in no part of this design: +opensoft/openRepoTools#237's hook gate, which merges the two hook entries only +once the path they call answers `guard`, and opensoft/openRepoTools#228's pipx +link, beside which `--install` places 16 of the 17 commands, leaves +`openRepoTools` to pipx and writes 28 receipt rows (`openRepoTools:2163` at +`33ce26d`). + Tests and fixtures need explicit **code**, **spec**, **assembly** and **dependency** roots. In particular, `tests/test_repo_hygiene.py` reads the root README/install line and agent guidance, while `tests/test_upstream_pin.py` diff --git a/specs/004-migrate-to-triad/plan.md b/specs/004-migrate-to-triad/plan.md index f0df01f..7e4336a 100644 --- a/specs/004-migrate-to-triad/plan.md +++ b/specs/004-migrate-to-triad/plan.md @@ -23,6 +23,15 @@ paths are resolved: 18 spec, 40 code, six root, zero dropped. There are This is an inspected preliminary baseline; regenerate after planning lands and the actual cutover source is frozen. +*Updated 2026-10-26, in the cutover's final spec reconciliation batch (T015, under +opensoft/openRepoTools#186):* the cutover source was frozen at `main` +`33ce26dffc5286e68f1d29ab5c6458edef0330c0` (200 tracked paths, 156 commits), and the plan +regenerated for it with openRepoShape `190133d5e704e380c430f87ca9c4e31746de0012` (v1.1.0) +places 108 spec, 86 code and six root paths, zero dropped, with 42 follow-ups. Brett Heap +approved it at Gate C. Its [published copy](adoption-plan-cutover-2026-10-26.yaml) and the +[as-built record](cutover-as-built-2026-10-26.md) set this baseline against the cutover's. +The adoption mapping linked above is now run C's rehearsal input, as its own header says. + Main advanced with merged PR #134 and matches the read-only GitHub observation; #61 and #146 remain included. There are six worktrees and six local branches, including this planning checkout and the @@ -56,11 +65,17 @@ reconciliation. Schema/routing/distribution/placement automation is pending. | --- | --- | --- | | Assembly `openRepoTools` | `AGENTS.md`, `CLAUDE.md`, `README.md`, `LICENSE`, `.gitattributes`, `.gitignore`; generated manifest/Makefile/validators and assembly pins | Front door and project coordination across legs. | | Spec `openRepoTools-spec` | `openspec/`, `specs/`, `docs/`; feature 001's retained `ideation/` and restored planning packets | Product requirements, decisions and manual; feature-only paths need separate replay accounting. | -| Code `openRepoTools-code` | All executable tools, `repos.tsv`, `commands/`, `skills/`, `tests/`, implementation CI | Shipped implementation and its installer payload. | +| Code `openRepoTools-code` | All executable tools, `repos.tsv`, `commands/`, `skills/`, `tests/`, implementation CI; its own `.gitattributes`, added after extraction | Shipped implementation and its installer payload. Git never applies the assembly's `.gitattributes` inside a submodule, so the leg carries the LF rule its bash files and byte-for-byte installer checks need. | | Code dependency unit | Original `.gitmodules`, `upstream/openRepoShape`, `contracts/openreposhape-pin.yaml` | Keep module registration, exact gitlink and dependency lock together. | | Code amendment exception | Genuine bounded `features//openspec/` records, deltas and evidence references | Relative changes against an approved spec baseline; explicitly review placement until upstream qualification. No such tracked paths were observed in the current source or retained feature heads. | | Root workflow bootstrap | `.specify/`, project agent links and selected feature pointer | Currently local/ignored; capture config and regenerate shape-aware root scaffolding. | +Extraction gives each original front-door file one owner, the assembly. T006's leg patches then +add new files to the legs: each leg's own `AGENTS.md`, `CLAUDE.md`, `README.md`, `LICENSE` and +`.gitattributes`, and the code leg's `.gitignore`. `spec-0001` also re-points three test paths in +the spec leg's `docs/README-claude-current.md`. These are reviewed changes after byte accounting, +not moved paths, so the adoption mapping does not change. + After byte-preserving extraction, add a root installation entry point that resolves the exact code pin. The original installer implementation moves to code; the root entry point selects and invokes it. Preserve the existing user @@ -86,8 +101,8 @@ Recommended active-work dispositions are proposals, not merge/closure actions: | Work | Proposed treatment | | --- | --- | | `001-separate-swap-ctx-handoff` | Continue from committed, clean head `3c26041`; preserve the complete branch delta, restored rollover/workspace packets and launcher/broker contracts. Migrate to paired `001` worktrees; keep tasks, evidence, roles and activation gates. | -| PR #97 | Preserve its current advanced recovery branch, review history and diagnostic role separately from managed LS authority and PR #121. Carry useful diagnostics under feature 001's service authority without merging unchanged or auto-closing through adoption. | -| PR #121 / feature `005-supervised-legacy-ctx` | Preserve complete staged/unstaged/untracked contents and the full legacy authority decision. Continue paired `005` worktrees for confirmed legacy-only supervised restart; managed/unknown ownership refuses. Keep the existing merge hold and PR #97 ownership separate. The full proposal/decision/specs stay in spec, implementation/tests in code; this authority decision is not a bounded local amendment. | +| PR #97 | **Overridden 2026-10-22: see the note after this table.** Preserve its current advanced recovery branch, review history and diagnostic role separately from managed LS authority and PR #121. Carry useful diagnostics under feature 001's service authority without merging unchanged or auto-closing through adoption. | +| PR #121 / feature `005-supervised-legacy-ctx` | **Overridden 2026-10-22: see the note after this table.** Preserve complete staged/unstaged/untracked contents and the full legacy authority decision. Continue paired `005` worktrees for confirmed legacy-only supervised restart; managed/unknown ownership refuses. Keep the existing merge hold and PR #97 ownership separate. The full proposal/decision/specs stay in spec, implementation/tests in code; this authority decision is not a bounded local amendment. | | PR #146 / `fix/107-pty-driver-bound-and-lane-per-call-cost` | Merged as `82ecebe`; checkout and local branch removed during concurrent cleanup. Included by baseline extraction; do not replay separately. | | PR #134 / `feat/claude-current` | Merged as `daed209`; the retained clean checkout at `11037f0` is preservation history. Resolver/checker, installer, preflight/fencing, timeout tests and manual are included by the regenerated baseline. Do not replay separately or retire the checkout as part of planning. | | PR #61 | Merged as `14641fd`, an ancestor of current main; included by baseline extraction. Do not replay the retired claim-takeover branch separately. | @@ -95,6 +110,17 @@ Recommended active-work dispositions are proposals, not merge/closure actions: | Remote-only preservation refs | `chore/preserve-local-planning-20261003` and `takeover/ort-a9-dirty-snapshot-20260913` remain locally observed remote-tracking refs with no checkout; review as preservation history, not active writers. | | Migration feature `004` | Previous refresh committed at `dda91f1`; existing checkout reused for this update. This full proposal and canonical feature files stay in spec; any genuine bounded implementation amendments belong in code. | +**Overridden, 2026-10-22: the rows for opensoft/openRepoTools#97 and for +opensoft/openRepoTools#121 with feature `005-supervised-legacy-ctx`.** Brett Heap +chose option A of lane 1's card 16 in round 7 of his rulings (answered +2026-10-22T14:53:08Z; relayed in opensoft/openRepoTools#186 comment +6343863633), in his words "Option A (Recommended)": no continuation. Feature +`005-supervised-legacy-ctx`'s bookkeeping closes as a spec-only change after the +cutover, and the 8 open tasks of opensoft/openRepoTools#97's change wait for a +later numbered feature. The two rows, which say to preserve +opensoft/openRepoTools#97's branch and to continue paired `005` worktrees, are +named as overridden and stay as written, as history. + **Gate A:** every preserved object is attributable and restorable; no active writer can silently invalidate capture. Baseline, visibility and work dispositions are ready for review, with any unresolved owner decision explicit. @@ -125,8 +151,9 @@ test-root context, CI layout, agent pointers, docs paths and workflow bootstrap in the rehearsed arrangement. Record their patches and resulting commits so real execution can apply the reviewed changes after source verification. Add leg root guidance without overwriting original root guidance. Preserve -the Bash 3.2 floor and original no-submodule test behavior, while requiring -complete dependencies for composed acceptance. +the Linux-only policy and serialized `tests/run.sh` locking, the bash 3.2 parse +living in `release.yml`'s macOS install leg, and the original no-submodule test +behavior, while requiring complete dependencies for composed acceptance. Operate full proposals from the intended feature spec checkout and bounded amendments from the code feature folder. Verify checkout, branch and root for @@ -185,7 +212,7 @@ pinned shape files. Put `Read AGENTS-shape.md first...` guidance first in root agent instructions and bootstrap shape-aware OpenSpec/Speckit only when both legs exist. Prepare continued-feature translations and disposable workflow checks from Phase 5 in the candidate before the final migration batch; actual -lane rebinding still waits for reviewed cutover. After implementation and verification, reconcile the net tested +lane rebinding still waits for reviewed cutover. *(Overridden 2026-10-23: see the note after this paragraph.)* After implementation and verification, reconcile the net tested effect in one final spec batch: governing specs/contracts/design, dated departures, as-built record, all amendment dispositions, evidence, deferred ideas and the actual landed code commit. Retain superseded/reverted/deferred history while @@ -195,6 +222,18 @@ to land and matching spec/code pins. Close the reconciliation issue after the spec PR lands; the feature landing record tracks the assembly PR. Advance gitlinks, pin digests and workflow SHAs together using the standard bump tool. +**Overridden, 2026-10-23: the sentence above that has continued-feature +translations and disposable workflow checks prepared in the candidate before the +final migration batch** (lines 186 to 188 of this file at `33ce26d`). Brett Heap +chose "Met by receipts; translate after (Recommended)" in round 20 of his +rulings (answered 2026-10-23T12:24:37Z; relayed in opensoft/openRepoTools#186 +comment 6364869132): lane 1's card 15, the work dispositions table v2.1 and P8's +disposable half of T018 meet Gate D's first clause, and the T016 and T017 +translations follow the root-split merge. The sentence is named as overridden, +as card 16's ruling named the two rows of the table above, and stays as +written, as history; lane rebinding still waits for the reviewed cutover. +`tasks.md` names its twin the same way. + **Gate D:** prepared continued-feature receipts and disposable workflow checks are reviewed; final reconciliation and matching spec/code commits are landed; exact assembled commits pass manifest/pin checks, canonical code @@ -248,8 +287,10 @@ and claims are not rewritten to hide a failure. ## Technical context and checks -Implementation remains Bash (macOS 3.2), Python standard-library tooling and -Git/GitHub workflows. Run build/test/CLI work in the project bench, with shared +Implementation remains Bash, Python standard-library tooling and Git/GitHub +workflows, under the Linux-only policy and serialized `tests/run.sh` locking, +the bash 3.2 parse living in `release.yml`'s macOS install leg. Run +build/test/CLI work in the project bench, with shared `tests/run.sh` locking. No real repository is created for a test. The local constitution is an unfilled template; no ratification is inferred. Preserve the existing root rules, standard pin checks and global workflow protocols. diff --git a/specs/004-migrate-to-triad/tasks.md b/specs/004-migrate-to-triad/tasks.md index 2e6ead2..1611c64 100644 --- a/specs/004-migrate-to-triad/tasks.md +++ b/specs/004-migrate-to-triad/tasks.md @@ -75,10 +75,13 @@ integration/preservation evidence and refreshed execution approval. existing upstream pin checks run against code Git identity and required composed checks cannot silently skip absent spec/dependency context. - [ ] T010 [US3] Adapt implementation CI and root exact-pin integration checks - with explicit compatible checkout context; preserve current Linux/macOS/ - Windows/WSL policies, Bash 3.2 parsing and serialized `tests/run.sh` locking. + with explicit compatible checkout context; preserve the Linux-only policy and + serialized `tests/run.sh` locking, the bash 3.2 parse living in `release.yml`'s + macOS install leg. Verify the exact rehearsed composed state passes required checks and the compatibility matrix, recording failures rather than deleting assertions. + Hosted-runner checks that need the real leg repositories run at T015 against + the real exact assembled head. - [ ] T011 [US1] Rehearse restoration/rollback of the local candidate and installed payload using preserved artifacts. Verify user work/jobs/claims survive and no force push, destructive reset or workspace-pointer rewrite @@ -164,11 +167,22 @@ T007–T010 may progress within the rehearsed topology after byte accounting. T011 closes Gate B. T012 requires Gate A/B and is the real-creation approval boundary. T013–T015 precede root adoption merge. Prepare T016–T017 translations and T018 disposable workflow checks in the candidate after legs exist, before -T015's final reconciliation. Actual T018 lane rebinding follows reviewed root +T015's final reconciliation. *(Overridden 2026-10-23: see the note below.)* +Actual T018 lane rebinding follows reviewed root adoption/cutover and safe breakpoints. T019 requires validated retained feature receipts; later behavior changes reopen reconciliation before another completed assembly advancement. +*Overridden, 2026-10-23:* the sentence above that prepares the T016–T017 +translations and T018's disposable workflow checks in the candidate before +T015's final reconciliation (lines 165 to 167 of this file at `33ce26d`). Brett +Heap chose "Met by receipts; translate after (Recommended)" in round 20 of his +rulings (answered 2026-10-23T12:24:37Z; relayed in opensoft/openRepoTools#186 +comment 6364869132): lane 1's card 15, the work dispositions table v2.1 and P8's +disposable half of T018 meet Gate D's first clause, and the T016 and T017 +translations follow the root-split merge. The sentence is named as overridden, +as its twin in `plan.md` is, and stays as written, as history. + ## Requirement coverage | Requirement | Tasks | diff --git a/specs/004-migrate-to-triad/test-roots-and-ci-2026-10-08.md b/specs/004-migrate-to-triad/test-roots-and-ci-2026-10-08.md index 2e1b260..47dde34 100644 --- a/specs/004-migrate-to-triad/test-roots-and-ci-2026-10-08.md +++ b/specs/004-migrate-to-triad/test-roots-and-ci-2026-10-08.md @@ -41,6 +41,20 @@ reproduction of run B into disposable local remotes (adopter `check` and the October 7 receipt — spec `558a12b`, code `6d52162` — and is superseded by run C for everything below. +*Updated 2026-10-26, in the cutover's final spec reconciliation batch (T015, under +opensoft/openRepoTools#186): the opensoft/openRepoTools#180 pointers.* Lines 300, 305, +306, 369 and 477 of this record, as it was at `33ce26d`, name opensoft/openRepoTools#180 +for the row-stamp cases that fail under `tests/run.sh`'s long run root, which `exact-pins` +inherits. That issue was closed with opensoft/openRepoTools#215 (`61a7378`), which moved +only `repoA11b`'s tail case. The cases it left are opensoft/openRepoTools#304's: `repoA-1` +and `repoCase-1` (`tests/test_lane_helpers.sh:1272` and `:8552` at `33ce26d`; rehearsal +D's record, P3), and `repoMIX-1` (`:8645`), which lane 3 found on 2026-10-22 +(opensoft/openRepoTools#186 comment 6342130291). Their fix is the code leg's `1e6f2d1`, +merged by opensoft/openRepoTools-code#1 as `2a057a6d` on 2026-10-26. So read those five +lines as pointers to opensoft/openRepoTools#304. The lines stay as written, as history. +Lane 3 named the 18 pointers of this kind, in four files (opensoft/openRepoTools#186 +comment 6332521834). + ## 1. What the split breaks — measured before the change The suite at run C's code leg `73b04d6` (that is, `main` without PR #190), run