Skip to content

Triad migration evidence of 2026-10-08 and 2026-10-09: test roots and CI patches, installer entry point, restore and rollback, #192's corrections, T018, Gate B status - #196

Open
brettheap wants to merge 52 commits into
mainfrom
004-migrate-to-triad-evidence-3
Open

brettheap wants to merge 52 commits into
mainfrom
004-migrate-to-triad-evidence-3

Conversation

@brettheap

@brettheap brettheap commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Part of #186

Gathers seven finished evidence branches of the triad migration (feature 004-migrate-to-triad) into one pull request on top of main a74c7fc (after #192, #190 and #191). Twelve files, all under specs/004-migrate-to-triad/, and nothing else: nine new documents and patches, and three dated corrections to documents main already has. +3664 / -8 (git diff --shortstat origin/main b50c83c).

This pull request carries no ready label. The candidate record has joined (r2 and r3 are in it).

This pull request adds no host-absolute path: none of its added lines names /workspace/ or /home/. The ones that main already has (consumer-reads-2026-10-07.md, ideation/brainstorm/supervised-context-restart-durable-intent.md, and the hygiene rule that does not match /workspace/) are #193 item 22 (#186 comment 6152761778), for their own pull request.

Input heads carried

Head b50c83c, on main a74c7fc. Every input head below is an ancestor of it (proof (e)).

Branch Head carried Base of its own diff Files
004-migrate-to-triad-ci 22bdb2e (was d28e2cc) ff6f6a7 3 new
004-migrate-to-triad-installer 7428e78 (final; 7668c51 and 3cca1e7 before it) ff6f6a7 2 new
004-migrate-to-triad-rollback-refresh 2e7e55e (slice A's final head), its file superseded by slice B's 837928a 1 new
004-migrate-to-triad-evidence-2-followups 118a2e2 (was 40f26f7; a fast-forward of the previous head 7c08f7e) f87fd5a, then 7c08f7e 3 edited, and slice A's file
004-migrate-to-triad-t018 63bff08 63810dd 1 new
004-migrate-to-triad-gate-b-status ee2e347 (was bfc0814, 3fd81c6) f87fd5a 1 new
004-migrate-to-triad-candidate 8c03f76 (was 16e6ea4, e81100c) 63810dd 1 new

What each branch adds

004-migrate-to-triad-ci (22bdb2e, cut from ff6f6a7): T009 and T010, explicit test roots and the triad's CI. Written by lane 1; three new files.

004-migrate-to-triad-installer (7428e78, cut from ff6f6a7): T007 and T008, the installer payload source and the assembly entry point. Written by lane 1; two new files.

004-migrate-to-triad-rollback-refresh (2e7e55e, on fa44d75, cut from 837928a): T011, the Gate A/B evidence, the restore and rollback rehearsals and the follow-up inventory. The first version was lane 1's; this refresh is lane 2's slice A, which answers lane 3's review of fa44d75 (#186 6082139424, findings F1 to F22). Lane 3 reviewed it as LAND (c1283b5, #186 6089982753); 612ea94 and 2e7e55e take in its notes N1 to N9 (#186 6090048356). One new file, gate-ab-evidence-2026-10-09.md: the source restore from the Gate A backup (90 checks of 90), the rollback of the installed payload in four disposable homes (the copy-back leaves the receipt stale; hooks and settings were not rehearsed), that user work and jobs survive (18 groups of mutating commands wrote only into private scratch), the Gate A/B evidence index, the follow-up patch inventory and what Gate B still lacks. This pull request carries that file from slice B's 118a2e2, which is 2e7e55e's file plus two of slice B's commits.

004-migrate-to-triad-evidence-2-followups (118a2e2; main f87fd5a merged in): dated corrections to #192's and #189's documents, #193 items 8 to 13, and lane 3's findings on them. Lane 2's slice B, announced at #186 6088799627. Lane 3 reviewed 096de93 as LAND as part of this pull request (#186 6092925484); 40f26f7 answered it, and 118a2e2 answers lane 3's 5481348731 items 7, 8 and 9. Each correction is dated and marked in place:

004-migrate-to-triad-t018 (63bff08, on 63810dd): T018's disposable half. One new file, t018-disposable-2026-10-09.md: feature selection, OpenSpec and the estate verbs status, park and resume in a triad fixture (three temporary homes, a network namespace with no route, its own bare remotes), and 11 follow-ups before cutover. It touched no real leg, estate or register, and checks no task complete. Lane 2's verification of it is posted (#186 6103482530): the record holds, with five minor contradictions and findings a to g that the record does not report.

004-migrate-to-triad-candidate (8c03f76, cut from 63810dd): the composed candidate carrying every Gate B follow-up. Written by lane 1; one new file, candidate-2026-10-09.md. It records the inputs, how r2 was built (#190 b50f197, #191 13cc752), its bootstrap and validators, its install compared with today's main (the same 29 files, byte-identical except the implementation), and r2's three suite runs with every failure classified (composed 1411 passed, 5 failed; standalone 1389 passed, 3 failed, 24 skipped; no-submodule 1168 passed, 6 failed, 242 skipped; two candidate defects with owners and four environment classes). Its section 9 is r3, at #191's final head 8246983 with T007 v3: the four install modules green in composed mode (281 passed), F1 gone. At 8c03f76 it carries dated 2026-10-13 lines: #191 landed as a74c7fc with r3's installer blob; what r3 covered and what is still owed (the full composed suite, run once at the frozen source for Gate C); where the answered gap is recorded; and F2's decision (the test gives, implemented in #195 e378871, open and in CI on the merge with a74c7fc).

004-migrate-to-triad-gate-b-status (ee2e347, on f87fd5a): the Gate B status walk. One new file, gate-b-status-2026-10-09.md, by lane 1's reviewer, reconciled line by line with lane 2's independent walk: the 46 checklist lines (the walk's own count: MET 27, PARTLY 18, OPEN 0, AFTER-GATE-C 1), T001 to T019 against the evidence, the Gate C open questions and the blockers to requesting Gate C. Lines 20, 29 and 31 are PARTLY by the walk's own legend, and it carries dated 2026-10-11 and 2026-10-13 lines: #191 landed as a74c7fc, which input heads this pull request carries, and the hold for openRepoShape v1.0.0. It approves nothing and changes no status in tasks.md.

How the branches were folded in (no rebase, no force-push)

Each input adds or edits only its own paths, so no merge and no conflict resolution was needed. For each input, exactly the paths it changed against its own base were taken, with the mode and blob each has in its owning head, into a scratch index of main:

export GIT_INDEX_FILE=<scratch>/idx
git read-tree a74c7fc                                        # main
git update-index --add --cacheinfo <mode>,<blob>,<path>      # twelve times, from git ls-tree <input head> <path>
T=$(git write-tree)
unset GIT_INDEX_FILE
C=$(git commit-tree "$T" -p <previous head> -p <input head> ... -F <message>)
git push origin "${C}:refs/heads/004-migrate-to-triad-evidence-3"   # a fast-forward

The history of this branch, all fast-forwards: 0de8562, e55268a and 7c08f7e took the earlier input heads on top of main f87fd5a. On top of 7c08f7e (through slice B's 118a2e2, itself a fast-forward of it), three commits then moved the branch to main a74c7fc and to the final heads: de0a72d (tree = main plus the twelve owned blobs; parents 118a2e2, a74c7fc, 22bdb2e, 7668c51, 3fd81c6, e81100c), 95cad9e (installer at its final head 7428e78) and b50c83c (candidate 8c03f76 and walk ee2e347, parents 95cad9e, 8c03f76, ee2e347). No input branch was pushed to or moved. An earlier fold onto #192's branch (f3b0222) was never pushed and is superseded.

Proofs, as run against b50c83c. In (a), the one path two inputs touch is slice A's gate-ab-evidence-2026-10-09.md, which slice B edits; its blob is taken from 118a2e2, not 2e7e55e (dated 2026-10-13, the supersede line in (a) and (b)).

### (a) paths touched by two inputs (each input's diff against its own base; slice B = f87fd5a..40f26f7 and 7c08f7e..118a2e2)
rows: 13  unique paths: 12  paths named twice: 1
  twice: gate-ab-evidence-2026-10-09.md  <- slice-A(A) slice-B(M) 
  dated exception 2026-10-13: gate-ab-evidence-2026-10-09.md is slice A's file (created at 2e7e55e) and slice B edits it (7c08f7e..118a2e2). The blob is taken from 118a2e2, not 2e7e55e.
  7c08f7e's blob of it equals 2e7e55e's: 020e15714f9fca3d4ac658cd72d3c3422c4ed01d vs 020e15714f9fca3d4ac658cd72d3c3422c4ed01d
  118a2e2 vs 2e7e55e for it:  1 file changed, 7 insertions(+), 4 deletions(-)  (slice B's commits 17dd54f and 118a2e2 only)
  118a2e2 vs 7c08f7e, name-status:
M	    S/adopter-rehearsal-2026-10-08.md
M	    S/gate-ab-evidence-2026-10-09.md
M	    S/root-guidance-2026-10-08.md

### (b) every path's blob in b50c83c648cadac8d1ad3ee1ca1b4e008e514c81 equals its blob in its owning head
EQUAL 218d5fa025e926d1372f4dbd86859c4e92483b98 slice-B@118a2e2 adopter-rehearsal-2026-10-07.md
EQUAL 2bf0d970980d62a94964843bcef4cb56ffef7833 slice-B@118a2e2 adopter-rehearsal-2026-10-08.md
EQUAL 571122075beade5ad878b21b81d7b6ef42bf7d02 candidate@8c03f76 candidate-2026-10-09.md
EQUAL f6c2809ee6e104651cdf5fcfd0348c67f7fc5d52 slice-B@118a2e2 gate-ab-evidence-2026-10-09.md  (supersedes 2e7e55e's 020e1571)
EQUAL 778278fcf11e98ec25bc27eb69405503fc9b5bf6 gate-b-status@ee2e347 gate-b-status-2026-10-09.md
EQUAL ea63cf295d182b57cbd754200de14b5d091a93bb installer@7428e78 installer-2026-10-08.md
EQUAL 407741b34d519a84546248f928606a1a56a14c5b installer@7428e78 t007-assembly-entry-point.patch
EQUAL 2b51c625b754fbe2c993f1a0f233cb5434d28167 ci@22bdb2e t010-assembly-exact-pin-job.patch
EQUAL 199bcd65c91460eaf23a188cd6c5452c7eefb976 ci@22bdb2e t010-code-leg-tests-workflow.patch
EQUAL c70514e187d89a8dd21b5f2cdfe992e0face716e slice-B@118a2e2 root-guidance-2026-10-08.md
EQUAL 9208f4076ddab0b1a6cfa614a55a37032cd05d32 t018@63bff08 t018-disposable-2026-10-09.md
EQUAL cbc896080746639cf6c3494a30a502a779bfe341 ci@22bdb2e test-roots-and-ci-2026-10-08.md
different: 0

### (c) git diff --name-status origin/main C
M	S/adopter-rehearsal-2026-10-07.md
M	S/adopter-rehearsal-2026-10-08.md
A	S/candidate-2026-10-09.md
A	S/gate-ab-evidence-2026-10-09.md
A	S/gate-b-status-2026-10-09.md
A	S/installer-2026-10-08.md
A	S/patches/t007-assembly-entry-point.patch
A	S/patches/t010-assembly-exact-pin-job.patch
A	S/patches/t010-code-leg-tests-workflow.patch
M	S/root-guidance-2026-10-08.md
A	S/t018-disposable-2026-10-09.md
A	S/test-roots-and-ci-2026-10-08.md
paths of that diff vs the union of the owned paths: IDENTICAL (12 paths)
status letters:       9 A       3 M    outside specs/004-migrate-to-triad/: 0
 12 files changed, 3664 insertions(+), 8 deletions(-)

### (d) merge base with main
origin/main = a74c7fc152967dd11099ce26f12fb7dcb12cba38
merge-base  = a74c7fc152967dd11099ce26f12fb7dcb12cba38

### (e) ancestry: the push to 004-migrate-to-triad-evidence-3 and every input head
is-ancestor 7c08f7e (the PR's current head) C exit=0  (push is a fast-forward)
is-ancestor ci (22bdb2e) C exit=0
is-ancestor installer (7428e78) C exit=0
is-ancestor slice-A (2e7e55e) C exit=0
is-ancestor slice-B (118a2e2) C exit=0
is-ancestor t018 (63bff08) C exit=0
is-ancestor candidate (8c03f76) C exit=0
is-ancestor gate-b-status (ee2e347) C exit=0
is-ancestor main (a74c7fc) C exit=0
parents of C: 95cad9e 8c03f76 ee2e347 

### (f) the step from 7c08f7e: paths whose blob differs, and which of them are #191's (from main)
M	openRepoTools
M	S/adopter-rehearsal-2026-10-08.md
M	S/candidate-2026-10-09.md
M	S/gate-ab-evidence-2026-10-09.md
M	S/gate-b-status-2026-10-09.md
M	S/installer-2026-10-08.md
M	S/root-guidance-2026-10-08.md
M	S/test-roots-and-ci-2026-10-08.md
A	tests/test_install_payload_source.py
M	tests/test_openrepotools_command.py
#191's own paths (f87fd5a..a74c7fc): openRepoTools tests/test_install_payload_source.py tests/test_openrepotools_command.py 
 10 files changed, 3212 insertions(+), 105 deletions(-)

Hygiene: PATH=/usr/bin:$PATH python3 -m pytest tests/test_repo_hygiene.py -q -p no:cacheprovider in a worktree at b50c83c, with HOME, TMPDIR, --basetemp and PYTHONPYCACHEPREFIX in private scratch: 152 passed in 1.23s, exit 0. Host paths, command grep -nE '/workspace/|/home/|/tmp/' over the twelve files: no /workspace/ and no /home/; five /tmp/ lines, none a host path (the ~/.local/state/openRepoTools/tmp/<UTC>-<pid>/ run-root template, a relative …/tmp/qa1-* path, and the shared lock /tmp/openrepotools-pytest.lock). The hygiene test's pattern has no /workspace/ arm, so this was checked by hand. CI on this head is the record.

Lane 3's findings on 7c08f7e, and where each is covered

5481348731 (the fold, T010, T011, #193 records, the walk)

5481348534 (the candidate record)

5481368376 (the installer files)

  • 0 (host path): installer-2026-10-08.md at 7668c51 on. 2 (v3's claim): narrowed, with "What v3 does not close". 3 (T008 table): all 52 tests of the module at the final head, none missing and none extra. 4 (head): 8246983, landed as a74c7fc. 5 (wip_shape_ref): the fallback now covers a source that does not answer and a ref it lacks. 6 (lane 2's open items): a disposition each. 7: "five things", and 5464963807 cited.

Still open

Authority

Nothing here authorizes real conversion. These are records of facts, rehearsals and patches; the plan file says execution_authorized: false, and the tasks in tasks.md stay open. The work is under Brett Heap's words of 2026-10-07, "start the triad migration" (#186), and of 2026-10-09, "usage reset, resume all. read handoff and resume and fan out wide and do as much as possible in parallel". Gate C stays Brett Heap's explicit approval naming the actual revisions. No new rehearsal or plan content is added.

Land by squash. The merge base of this head and main is a74c7fc, so the pull request shows only the twelve files.

🤖 Generated with Claude Code

brettheap and others added 30 commits October 3, 2026 18:45
Preserve the existing OpenSpec and Speckit planning files at Brett Heap’s request during repository cleanup. No migration or adoption is executed.
…and regenerate the adoption plan from it.

Run C repeats runs A and B (which stand) with openRepoShape 7f84ca4 at
the source that exists after #187 (44983ce) and #188 (837928a): fresh
single-branch clone, git transport restricted to local files, gh/curl
refused, disposable local bare remotes. check ok; execute exit 0; spec 65 /
code 49 / root 6 / dropped 0 of 120; independent path/mode/type/oid
comparison with zero missing or duplicate owners; recursive clone,
bootstrap and validators passed; code's nested gitlink 7f84ca4 and the
recomputed digest 3be52767 match its contract. The run B plan's 22
resolutions were reapplied verbatim; the 20 new planning files are spec by
the existing openspec/ and specs/ entries.

adoption-plan.yaml is now the resolved run C plan, labelled as rehearsal
input and not the cutover plan. The arrangement is kept host-local as the
read-only input for T006-T010. Gate B remains open (T006-T011); nothing
here authorizes a real conversion. Private receipt adopter-fix-20261008-1HztL0. Part of #186.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ith two lockstep pin bumps, and the code and spec legs' own front doors, all made against run C's rehearsed split.

Each patch is `git format-patch` output from lane openRepoTools-1's scratch
clones of run C (assembly split 69b8924, spec leg 593250d, code leg
73b04d6) under #186. Re-applied with `git am` onto its
base, each reproduces the pushed tree exactly, and `git diff --check` passes
on every range. assembly-0002 and -0003 are bump-leg.py's commits and pin
the rehearsal's leg hashes; at T014 they are regenerated against the real
legs, not applied. The 2026-10-07 build of the same patches was lost when
/tmp was cleared; this is its rebuild. The write-up follows in
specs/004-migrate-to-triad/root-guidance-2026-10-08.md.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dalone tests workflow and the assembly's exact-pin integration job in its own file.

Checkpoint of the CI evidence for #186. The legs do not exist on GitHub yet
(Gate C), so these are patches against the rehearsed run C arrangement: the
code leg's tests.yml at 73b04d6 (its six jobs and trigger policy kept, the
standalone checkout context named) and a new .github/workflows/composed.yml
for the assembly at 69b8924, its own file because validate.yml is a pinned
shape copy. Both `git apply --check` cleanly against run C. The measurements
and local proofs follow in test-roots-and-ci-2026-10-08.md.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…and composed contract PR #190 answers it with, and the local proofs of both T010 workflow patches.

Measured on the rehearsed run C code leg 73b04d6 in three contexts (mounted
in the assembly, standalone, standalone without the dependency): the same 17
hygiene tests fail on files the split moves out of the code leg, and nothing
else in the measured selectors. PR #190 is red at origin/main in 18 tests and
188 passed with nothing skipped on today's layout; CI green per push. In a
composed candidate pinned with bump-leg.py, the validators pass, the composed
job refuses a missing spec leg (exit 1 at its context step, exit 4 from the
suite), and the composed and standalone leg runs fail only on the code leg's
missing .gitattributes (a T006 finding) and two lane-suite stamp assertions
the long run-root path pushes past the row cut. Hosted runs wait for real
legs (Gate C). Part of #186.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…red links, the leg front doors, the 35-commit provenance correspondence and every bootstrap, validator, OpenSpec and Speckit result, with the assembly patches replaced by leaner ones that respect the root files' length caps.

specs/004-migrate-to-triad/root-guidance-2026-10-08.md records T006 for
#186, rebuilt on run C (split 69b8924, spec 593250d,
code 73b04d6) after the 2026-10-07 build was lost with /tmp. The assembly
patches are replaced: code/tests/test_repo_hygiene.py caps AGENTS.md and
README.md at today's 316 and 486 lines and admits lines only for a rule. So
the root additions shrink to 24 lines each: the shape's pointer line and a
seven-entry map, and the three-repository section with the lockstep-invariant
anchor. The leg patches are unchanged. All five patches re-apply to
identical trees, and `git diff --check` passes. Findings for lane 3, T007,
T009, T010, T014 and T017 are in its section 10. Nothing lands on main from
this task.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… 90 checks pass, no captured ref moved except forward, and a dirty tree rebuilds only with the staged and unstaged diffs the October 7 capture does not take.

First commit of specs/004-migrate-to-triad/gate-ab-evidence-2026-10-09.md for
#186; the installed-payload rollback, the mutation table,
the evidence index and the follow-up inventory follow on this branch.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ption plan supersedes run B's (both are rehearsal input, not the cutover plan); every other file is main's

Lane: openRepoTools-1
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
 squashed its base ff6f6a7 (base pinned at ff6f6a7)

Lane: openRepoTools-1
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ull request

Lane: openRepoTools-1
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…the Gate A/B evidence index and the follow-up patch inventory: both rollbacks return every placed file, mode and hook to main's install, the copy-back leaves the receipt stale, and nothing real was written.

Steps 2-4 of T011 in specs/004-migrate-to-triad/gate-ab-evidence-2026-10-09.md for
#186: four disposable homes (main, the run C candidate
from code/, PR #191 as a payload that differs, and rollback by the Gate A
copies or by reinstalling the restored source), 18 classified write groups
with empty real-repository, real-home and register columns, every evidence
document with who verified it, the seven recorded patches re-applied onto
their rehearsed bases with matching trees, and what Gate B still lacks. The
private receipt ID is rollback-20261009-ILvoVC; its commit follows.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hy the hygiene selector did not run on this document while the two all-files hygiene checks find nothing in it.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er evidence for the triad migration.

The root openRepoTools of the assembly cannot land on main before the split,
because its path is the implementation's, so it is kept here as a
format-patch of the commit made in a clone of run C's rehearsed split; git am
on a fresh clone reproduces its tree. installer-2026-10-08.md records the
arrangement relied on, the pin grammar, the one-liner contract and how it
compares with T006's README sentence, the 15-row matrix with its tests and
red-at-base results, the runs, lane 2's installer rows, and what remains for
T009, T010, T014 and T015. Nothing here authorizes a real conversion.

Part of #186.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…up: its inputs, apply order, commits and trees, its validators, and its install compared with today's main.

The suite runs on the candidate are queued behind the workstation lock and
are recorded in a later commit.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ith both reviews, the .gitattributes decision and the dated follow-ups.

The record stopped at c139e88. Since then e3a76b5 refuses a leg whose git
status cannot be read and keeps .gitattributes in the fixture legs (Copilot
round 1), and dbc6837 adds T006's assembly-root caps and fails a missing lane
manual by name. Readers of the migration plan need four things here that were
not in it: the red and green runs for those commits, the CI counts at the
head, the independent review's LAND, and Copilot round 2's pin-commit gap.
That gap is reproduced here, and validate-pins.py is shown to close it in the
assembly job.

The .gitattributes decision is now stated outright. It agrees with T006's leg
patch and disagrees with plan.md's placement table, which is a follow-up for
the plan's owner. The follow-ups that are not in #190 are listed with their
branch, feat/test-roots-followups. One fixture path is respelled so the
document does not trip the host-absolute-path check if it ever lands.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d on an unguarded manual read, which this record had attributed to two stamp assertions alone.

P3's log shows `ln_doc: unbound variable` at line 6595. That is a defect in
PR #190's own guard, and lane openRepoTools-3's review found it where this
record had missed it. The record now gives the defect, the fix branch
feat/test-roots-manual-guard (b50f197), and the before-and-after proof with
its log hash. It also adds lane 3's review and its two other items to the
dated follow-ups.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e run has finished, the composed run was stopped at about 20% and must be rerun, and the CI numbers it will be compared with.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tus in a triad fixture (#186)

Evidence of 2026-10-09 from the composed candidate (assembly 3bd95a7, spec
9e1d006, code f0af7d9, nested openRepoShape 7f84ca4), copied into fresh bare
remotes and driven from three temporary homes under env -i, a disposable
agent root and workspace record, file-only git and a private network
namespace. Selection resolves the same root and feature directory from the
root and both legs. OpenSpec answers only from the spec leg. park commits and
pushes one WIP per leg and leaves the root and its gitlinks alone. resume
refuses a root that the bootstrap itself dirtied, and silently drops a parked
nested gitlink move. Every refusal is relayed verbatim; nothing was forced.
No task is checked complete.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… squashed this branch's base 71b05cb as 1abee1d (identical tree ef74235), then #190 landed

Part of #186. Base for #193 items 8–13; no file changes of its own.

Lane: openRepoTools-2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #186. Text only, in three Markdown records under
specs/004-migrate-to-triad/. No patch file, plan or YAML is touched.
Every figure was measured again on 2026-10-09.

- adopter-rehearsal-2026-10-08.md
  - Item 8 (review 5464893559 finding 5): one dated block says where the
    records are now, what run C superseded, and that run B's plan stays
    at 63810dd. It records the 2026-10-08 restart that removed runs A
    and B's repositories, and the openspec 1.2.0 observation. openspec
    1.13.1 now exits 0 on 837928a and on 71b05cb.
  - Item 10 (finding 17): `check` reads the clone's local main, not
    HEAD. This plan gives plan-stale, exit 1, against any newer main.
    Reproduced both ways.
  - Item 12 (finding 6): the "no ensurepip" cause is withdrawn. The
    refusal is real, and its cause is not established.
- root-guidance-2026-10-08.md
  - Item 9 (findings 8 and 9): 18 front-door test functions (17 + 1),
    not 17. The command test stays red after code-0001. The "23 in 9"
    total disagrees with its own per-file list (26 in 11), and which is
    right is not established. Also :6, and :195's consumer-reads is on
    main.
  - Item 11 (finding 16): no receipt is cited. The record now says what
    the patches reproduce from public inputs, and which rows exist only
    in the document.
- adopter-rehearsal-2026-10-07.md
  - Item 8: one dated line. The false "On this branch" sentence is in
    this file.

Lane: openRepoTools-2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e it runs any pinned implementation, and the network needs T014 should document.

Lane 3's review of the v2 patch (T3) required the remote path to confirm
the gitlink at the pin's submodule_path before it fetches or runs the
implementation the pin selects. v3 (6acc147 on 69b8924) does that, and git
am on a fresh run C clone reproduces its tree 87782af. The runs table rows
for the round-2 head and CI are still to be added.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
f87fd5a, and correct what lane 3's review and lane 2's receipt check found

Answers lane 3's review of fa44d75 (#186 comment 6082139424) and folds in lane
2's verification of receipt rollback-20261009-ILvoVC (#186 comment 6082370012).
Only specs/004-migrate-to-triad/gate-ab-evidence-2026-10-09.md changes. Every
refreshed passage says Refreshed or Corrected and keeps the 01:1xZ text it
qualifies.

- F11: no stage changed a hook, so the hook rollback is vacuous. The Gate A
  backup holds no settings.json, and RESTORE.md's copy-back restores only
  installed/. 849592b's subject overclaims hooks.
- F15 and F18: sections 4 to 7 re-read origin at 20:29Z-20:37Z, with main at
  f87fd5a after #192 and #190 landed. They now record T007's entry point on
  the installer branch at 51993a4, the candidate at 935f53f, every review
  since 01:13Z, and an inventory that maps each named follow-up to a patch,
  a PR, an owner or a deferral.
- F4-F9, F12-F14, F17, F19, F20, F22 and lane 2's corrections:
  - the restored bundle's identity, and the 90 checks by category against
    #189's 97;
  - the two near-tautological check families, and main's 70 files plus one
    symlink;
  - "live" meaning the shared checkout at 00:44:08Z;
  - 10 installs, not 12, and no placed file added or retired;
  - 076062af and the final snapshot;
  - T010 trees with no earlier record;
  - GIT_OPTIONAL_LOCKS, the copied capture block, and nested repositories
    rather than caches.

Part of #186.

Lane: openRepoTools-2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
c1283b5: the candidate branch's creation sha, the two #190 follow-up branches' creation and first move, and the owner of run C's ninth docs/ file

From lane 3's review (#186 comment 6089982753), N1 to N3, each checked at
its source:
- N1: 004-migrate-to-triad-candidate was created at b21c511 at 01:58:43Z,
  and b21c511 -> 935f53f was pushed at 02:43:24Z (GitHub activity API).
- N2: section 4 gains feat/test-roots-manual-guard, created at b50f197 at
  02:29:44Z, and feat/test-roots-followups' creation at 2064390 at 02:14:37Z
  and its move to 7144eef at 02:31:20Z (activity API; both moves are
  fast-forwards).
- N3: the plan's unnamed ninth docs/ file is tests/test_repo_hygiene.py.
  git grep -l 'docs/' at 837928a gives exactly nine code-leg files, and
  root-guidance-2026-10-08.md:191 routes that one to T009/T010.

Part of #186.

Lane: openRepoTools-2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ollision rows, the dropped-check arithmetic, the copy-back's limits, deleted refs, the refresh's real time, and the verbatim run's public citation

From lane 3's review of c1283b5 (#186 comment 6089982753), each checked at
its source:
- N4: root-guidance-2026-10-08.md:69-76 holds the collision and shape/ rows
  (AGENTS.md is :69; CLAUDE.md, :70, is unchanged), so "resolved in the
  patch", not "merged".
- N5: October 7's verify.log:13 is one check of the 16 per-worktree HEAD
  refs, and main's status check moved to the singles (10-restore.log:160):
  12 - 2 + 1 + 11 = 22 and 85 - 17 = 68.
- N6: the copy-back route restores the 29 files and the receipt only, with
  no settings.json and no hook entry.
- N7: a captured ref moved forward or was deleted with its commit still on
  GitHub; re-checked against ls-remote at 22:05:16Z (15/9/9/0).
- N8: c1283b5 was committed at 20:38:20Z, so the hygiene line and the
  header's refresh window say 20:3xZ.
- N9: the public comment marks as inferred only its conclusion; the
  verbatim run's log is host-local and unpublished, so the record now says
  no public citation exists for the run itself.

Part of #186.

Lane: openRepoTools-2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…TLY 15, OPEN 0, AFTER-GATE-C 1), T001-T019, the Gate C open questions with proposed wording, and a line-by-line reconciliation with lane 2's walk

specs/004-migrate-to-triad/gate-b-status-2026-10-09.md walks
gate-b-checklist.md against origin as fetched at 22:07:06Z and #186's
comments through 22:06:49Z. It approves nothing and changes no task
status.

- Section 1: each line's status, evidence, what remains and owner, and
  which lines moved since lane 1's unpublished first pass.
- Section 2: lane 2's walk, the same path on 004-migrate-to-triad-reads
  @ a7a8e00 (a cross-check that goes into no PR), line by line. It
  differs in substance on 22, 2, 12, 18, 19 and 21. It also answers
  lane 2's review of the first pass (6088829392) item by item.
- Section 3: T001-T019 against the evidence.
- Section 4: questions a-e for Brett, each with text to approve:
  - (a) openspec 1.2.0 fails migrate-to-triad and 1.6.0 passes;
  - (b) "account move";
  - (c) .gitattributes in plan.md against tests/conftest.py on main;
  - (d) hosted CI before the legs exist;
  - (e) e1-e10, including the six-commit openRepoShape drift and the
    post-cutover one-liner's API and jq dependency.
- Section 5: the blockers in dependency order.
- Section 6: the commands.

Private receipts are named by id only, and no host path appears.

Part of #186
Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brettheap and others added 2 commits October 11, 2026 00:16
…o the second triad evidence pull request

Part of #186.

Two inputs moved or arrived after the previous commit (e55268a) took the
others:

  004-migrate-to-triad-candidate             16e6ea4  (cut from 63810dd)  the composed candidate record: specs/004-migrate-to-triad/candidate-2026-10-09.md (1 new file)
  004-migrate-to-triad-evidence-2-followups  40f26f7  (was 096de93)       lane 3's follow-ups on 096de93, a fast-forward of it: the same 3 files, +17/-7

Method, no rebase and no force-push: the tree is e55268a's tree with those four
paths taken, each with the mode and blob it has in its branch head, in a
scratch index (read-tree, update-index --cacheinfo, write-tree). The three
followups paths are replaced by their blobs at 40f26f7; the candidate record is
new. No path is touched by two branches. The commit keeps e55268a, 16e6ea4 and
40f26f7 as parents, so the push is a fast-forward of
004-migrate-to-triad-evidence-3 and neither input branch is pushed to or moved.
Every other input head is unchanged: 004-migrate-to-triad-ci d28e2cc,
-installer 3cca1e7, -rollback-refresh 2e7e55e, -t018 63bff08 and
-gate-b-status bfc0814, on main f87fd5a.

Nothing here authorizes real conversion: these are records and patches, the
tasks stay open, and Gate C stays Brett Heap's explicit approval naming the
actual revisions.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…staller evidence.

Round 1's two fixes and the one finding kept, with the reason; round 2's
body correction and the test that shows the behaviour; and a strict
composed run of the module's composed and local rows with root v3 and the
final head's code leg.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@brettheap brettheap left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Superseded by lane 3 review 5481348731 (same scope, posted 00:33Z). Two runs of lane 3's reviewer overlapped during the lane's move to pyBench, so this scope was posted twice. 5481348731 covers both heads (e55268a, then 7c08f7e) and adds finding 14. Read that one; this text is kept unchanged below.

Independent adversarial review — lane openRepoTools-3: #196's fold, T010/T011/#193 records and Gate B walk @ 7c08f7e (read-only; 2026-10-11T00:21Z)

Verdict: LAND (for this scope). No finding blocks.

  • The fold is exact at both heads. I first read e55268a. #196 moved to 7c08f7e at 00:17:19Z, and this review is of 7c08f7e.
  • Every proof in the new body reproduces.
  • Slice B's fold-ins are now carried (finding 8).

Three things should still be settled before ready:

  • 4: give the T010 record one dated line on #190's and #192's landings. On main it would say that #190 lacks b50f197.
  • 12: walk line 29 is MET, but by the walk's own legend it is PARTLY.
  • 13: the walk says the IN machine path "must be removed" before IN joins this PR, and this PR carries it unchanged.

Scope. Every file except installer-2026-10-08.md, patches/t007-assembly-entry-point.patch and t018-disposable-2026-10-09.md. Other lane-3 reviewers cover those. The candidate record, new at 7c08f7e, got a fold check and spot checks only (finding 17).

How. I worked in a fresh scratch clone of origin.

  • My first scratch directory was removed at about 00:1xZ. I re-cloned at 00:16Z and re-measured every fold fact in the new clone. Last re-fetch: 00:21:24Z.
  • Heads: #196 7c08f7e, main f87fd5a, slice B 40f26f7, candidate 16e6ea4.
  • I also checked GitHub, and #186's comments through 6103618033 (00:10:09Z).
  • Nothing was written anywhere except my scratch.

Short names, the same blobs at e55268a and 7c08f7e unless marked:

  • tr: is test-roots-and-ci-2026-10-08.md.
  • gab: is gate-ab-evidence-2026-10-09.md.
  • gbs: is gate-b-status-2026-10-09.md.
  • cand: is candidate-2026-10-09.md.

The fold

  1. Every proof in the body reproduces, at both heads.
    • (e) Ancestry. These are all ancestors of 7c08f7e (exit 0): d28e2cc, 3cca1e7, 2e7e55e, 40f26f7, 63bff08, bfc0814, 16e6ea4, e55268a and f87fd5a. So are 096de93, 4f773b8 and 0de8562.
    • Parents. 0de8562 has seven. e55268a has 0de8562 and 3cca1e7. 7c08f7e has e55268a, 16e6ea4 and 40f26f7.
    • (a) No shared paths. Each branch's diff against its own base gives 3, 2, 1, 3, 1, 1 and 1 paths: 12 in all, 12 unique, 0 duplicates. The candidate branch changes only cand: since its base 63810dd.
    • (b) Blobs. All 12 blobs at 7c08f7e equal their input head's, and each matches the new body's list. All 11 at e55268a did too.
    • Merge-tree. git merge-tree --write-tree f87fd5a 7c08f7e exits 0 with tree 34502405…, which is 7c08f7e's own tree. It changes 9 paths (A) and 3 (M), all under specs/004-migrate-to-triad/: +3338/−7. At e55268a it was tree 1af6a782…: 8 A, 3 M, +2920/−7.
    • (d) Merge base. It is f87fd5a.
    • (f) The later commits.
      • 0de8562..e55268a changes only the installer document (+15/−5), and the T007 patch is blob 407741b3 at both 4f773b8 and 3cca1e7.
      • e55268a..7c08f7e is the three slice-B paths plus the new cand:: +425/−7.
  2. Nothing is dropped.
    • -ci and -installer are based on ff6f6a7, which is not on main. All 20 of c1bac0d..ff6f6a7's files reached main through #187's squash 44983ce, with the same blobs. Two of them (adoption-plan.yaml and inventory.json) have moved forward on main since.
    • Where any input head differs from main outside its own paths, it is older content that main has since replaced.

T010: tr: and the two patches

  1. Carried byte-identical to d28e2cc: tr: is 7badfa33, the code-leg patch is 199bcd65, and the assembly patch is 2b51c625.
    • Both patch blobs are the same at cc7c7a1 and d28e2cc.
    • The code-leg patch's base e27bc64 is main's tests.yml blob.
  2. [should fix] The record was written before either landing, and on main it says that #190 lacks b50f197.
    • d28e2cc was committed at 2026-10-09T02:31Z. #192 landed at 20:24:58Z (1abee1d) and #190 at 20:26:03Z (f87fd5a).
    • tr:8–10 still gives #190's head as dbc6837.
    • tr:11–13 says "Follow-ups (not in #190): … feat/test-roots-manual-guard, b50f197", and tr:361–362 says "None of them is in #190". tr:387–389 says "unless the coordinator takes it into #190 before the squash".
    • The contradicting source: git diff 1abee1d f87fd5a and git diff c4864ac b50f197 have the same patch-id (cb2c7bf2…). #190 landed exactly b50f197.
    • tr:113–115 asks for #192 to land "with or before #190". It did, but the record never says so. The body (:31) says it; the record does not.
    • Fix: one dated line under Updated. This needs a commit on -ci and a refold.
  3. [low] tr:345–352 overstates lane 3's #190 review. It says 5464931249 "names three things to fix before the squash".
    • That review named one: finding 10, the ln_doc abort, "best made before the squash".
    • Its finding 11, the paired layout, is a "Gate C item". The silent redirect is a "Hazard (non-blocking)".
    • The record's own §9 item 6 dates (2) "before Gate C", so §9 disagrees with itself.
    • The record cites the review id and its LAND on dbc6837 correctly.
  4. [low] Lane 3's review of the T010 patches (6089801221, 21:47Z) came after the record.
    • The record does not mention it. The walk records it, on its lines 32, 33 and 46 (gbs:116, :117, :130) and in its T010 row (gbs:237).
    • The record's own text still points the wrong way on that review's finding 13 (i). tr:265–275 blames the two row-stamp FAILs on "the run-root work of #162/#184", and says CI passes them with a short TMPDIR.
    • The issue is #180 (lane 2's 6072319462; F3/F4 at cand:237–238). composed.yml runs bash code/tests/run.sh -rs (assembly patch :125), so exact-pins inherits it.
    • tr:§8, "What remains for T015", does not list it.

T011: gab: at 2e7e55e against lane 3's N1–N9 (6089982753)

  1. All nine are answered in c1283b5..2e7e55e.

    Note Fixed at How
    N1 gab:439 "created at b21c511 at 01:58:43Z, then b21c511 → 935f53f at 02:43:24Z"
    N2 gab:439, :442, :443 All three missing moves were added.
    N3 gab:524 It names tests/test_repo_hygiene.py. I recounted: git grep -l 'docs/' 837928a, outside docs/, specs/, openspec/, AGENTS.md and README.md, gives exactly 9 files.
    N4 gab:525 :69–76, and "resolved in the patch"
    N5 gab:61–71 It gives verify.log:13 as one check, 22 = 12 − 2 + 1 + 11, and 68 = 85 − 17.
    N6 gab:571–572 "for the 29 files and the receipt only"
    N7 gab:372–373 "or was deleted with its commit still on GitHub"
    N8 gab:6, :681 "20:3xZ"
    N9 gab:159–162 It says that no public citation of the run itself exists.
    • One leftover [low]. gab:436, :443 and :513 still say "no review verdict posted; lane 3's reviewer … has resumed" for the T010 patches and the follow-ups.
    • 2e7e55e was committed at 22:06:08Z, 19 minutes after 6089801221. The header dates the origin read to 20:29–20:30Z, so the record does disclose this. A dated pointer would still help.

Slice B: now carried at 40f26f7

  1. Resolved at 7c08f7e: #196 now carries slice B at 40f26f7.

    • The blobs are 218d5fa0, 863f9ad0 and cbceb661. e55268a carried 096de93's f447de83, acbe2098 and 3c832521.
    • Lane 2 pushed 40f26f7 at 23:55:53Z and asked for this merge (6103529172).

    The delta 096de93..40f26f7 changes 3 files (+17/−7). git diff --check exits 0, and the hygiene regexes find nothing. It answers lane 3's review 6092925484 (LAND):

    • Finding 1, applied at root-guidance:428–431. It names 837928a and adds the #190 sentence. That sentence holds on main:
      • 17 tests read through ROOTS.path_for: doc(), test_repo_hygiene.py:32–36, and test_openrepotools_command.py:1398–1401.
      • test_the_root_carries_the_line_ending_rule reads REPO / ".gitattributes" directly (:2736), so without code-0001 it raises FileNotFoundError.
    • Finding 2, applied at 10-07:189–190 and 10-08:43–47 ("their logs survive only in that receipt", plus the two surviving parents).
    • Finding 3, applied at root-guidance:54–55 (the 85-token census).
    • Nit 4, applied at 10-08:31–34 ("on main in #192's squash 1abee1d").
    • Nit 5 and the 23/26 count are left unchanged, as lane 2 says.
    • Leftover [low]. The next bullet, root-guidance:432, is unchanged: "4 now pass only because they read the leg's own files". Since #190, three of those four skip in a standalone leg, as the new bullet just above it says. Lane 3 had left this as #192's text, but the two bullets now contradict each other back to back.
  2. [low] adopter-rehearsal-2026-10-08.md:53 says "The bench's openspec is now 1.13.1." That depends on the container.

    • On this host at 00:1xZ, which -a openspec gives ~/.npm-global/bin/openspec 1.2.0 first and /usr/bin/openspec 1.6.0.
    • validate migrate-to-triad --strict then exits 1 under 1.2.0 (the SHALL/MUST error) and 0 under 1.6.0. That is exactly the walk's §4 (a).
    • Lane 2 reports 1.13.1 on its own bench (6103482530).
    • Fix: name the host. gbs:266 repeats the general claim ("EF records the bench's openspec as 1.13.1 too").

The Gate B walk (gbs:, bfc0814)

  1. Lane 2's ten corrections (6088829392): 9 applied, 1 declined, and the decline is backed by evidence I confirmed.

    • Item 1 (lines 36 and 37 to PARTLY): applied, gbs:120–121.
    • Item 2 (line 12 to PARTLY): declined at gbs:167 and :204–205, citing #162's CI. I checked every CI fact:
      • At 6fa4e07: tests succeeded at 00:57:08Z, tests-macos at 01:00:51Z and tests-windows at 01:06:45Z.
      • At the merge 7f84ca4: tests succeeded at 01:13:26Z, and Windows and macOS were skipped.
    • Item 3 (line 34 to PARTLY, with the r2 numbers): applied, gbs:118. The numbers equal 6087267593's and cand:23–27.
    • Item 4 (lines 25 and 46): applied, gbs:109, :130.
    • Item 5 (question e1): applied, gbs:48–49, :446–455. It is stale again: see finding 14.
    • Item 6 (line 22's owner): applied, gbs:106.
    • Item 7 (re-cites): applied. There is no "E2:" and no f3b0222. "Land #192" and "fold b50f197" appear only at gbs:212, which says they are gone. Line 39 is MET.
    • Item 8 (CLI versions): applied, gbs:250–253.
    • Item 9 (questions e6, c and b): applied, gbs:486–495, :357–360 (f87fd5a:tests/conftest.py:62–68 says what is quoted) and :327–331.
    • Item 10 (lines 40 and 2): applied. gbs:124 matches 6082139424's finding 18 item for item, and gbs:86 covers line 2.
  2. I spot-checked 17 MET lines, and all hold against origin and GitHub.

    • 1: 6035767825 quotes the words, and visibility: public is at adoption-plan.yaml:39.
    • 3: the plan's source is 837928a, and it has 22 resolution: entries (6072724043 (iv)). Review 5464893559 is LAND.
    • 4: plan ok, and 120 = 65/49/6/0.
    • 6: all 17 refreshed.amendment_path_observations are empty.
    • 9: 6072724043 (iii) and 5464893559 finding 4.
    • 12: as in item 2 above.
    • 13: 837928a is #188.
    • 15: 3be52767… (6072724043 (v)).
    • 16: bootstrap ok.
    • 17: 5464893559 finding 7.
    • 29: LAND 5464931249, LAND 5464938427, and delta LAND 5471080687. Every check on b50f197 is green, tests-macos included.
    • 30: 6072319462 (all 14 test_upstream_pin.py tests pass). That run used run.sh's pytest line, not its census, which gbs:114 discloses. tr:§1 M2 and M3 went through run.sh itself.
    • 31: 6087267593's five exit-4 cases.
    • 33: 6089801221 finding 12.
    • 39: the two receipts are in 6036838832 and 6072724043.
    • 44: both leg repositories return 404 at 00:02Z today.
    • 45: observed_at 2026-10-07T10:09:03Z.
  3. [should fix] Line 29 (gbs:113) should be PARTLY by the walk's own legend. The legend (gbs:73–74) makes a line PARTLY when it "carries an open defect or an open decision". Line 29's own "What remains" lists open items:

    • #193 items 3–7 and 15;
    • item 5, the paired layout: lane 3's #190 finding 11, a "Gate C item", "wanted before Gate C".
    • Also, gbs:541–543 (§5 item 2) lists FU's landing and item 5 as blockers to requesting Gate C.
    • 6089801221 finding 9 adds that the command test still reads the README before its --help half.
    • The follow-ups are now #195 at fb77bed. It is open, and lane 1 asked lane 3 to review it at 23:48Z (6103460962).

    Two weaker cases:

    • Line 31 (gbs:115). The checklist's evidence column is met. But #193 item 15 is a defect in that very refusal, and item 4 is closed only by composed.yml's step order. Make it PARTLY, or say in the legend that MET allows open #193 items. (Lane 2 reports item 15 fixed on #195, 6103529172. That is not on main.)
    • Line 20 (gbs:104) [low]. The "23 in 9" against 26 in 11 count is open. 6092925484 rated it PARTLY.
  4. [should fix] The walk still contradicts the PR on the IN path.

    • gbs:190–191 (§2, lane 2's item 16) says the host-absolute path at installer-2026-10-08.md:13 "must be removed before IN goes into the evidence-3 PR".
    • #196 carries IN with line 13 unchanged, and that line still names the private prep area by absolute path. The new body (:38) says so, and leaves it.
    • HOST_ABSOLUTE_PATH does not match /workspace/…, so CI will not catch it.
    • Fix: either fix the IN line before ready (the installer reviewers own that file), or add a dated note to the walk.
    • The other half of §5 item 4 (gbs:548–552), the candidate record, is met at 7c08f7e.
  5. [low] Some lines are stale since the walk's 22:10Z read. Its header discloses "Anything later is not in this walk". A dated "since" note before ready would keep the Gate B record accurate.

    • Refs read (gbs:31, :35, :38, :39). IN is now 3cca1e7, carried here with the v3 patch. CA is now 16e6ea4, also carried here. #191 has moved three times since 22:07Z, through 6568f08 and cddd1f7, and it is now 8246983 (00:16:56Z). FU is #195 at fb77bed.
    • Slice B (gbs:56, :101, :233). Lane 3's review of it is posted (6092925484, LAND), and 40f26f7 takes it in.
    • T18 (gbs:102–103, :241). Lane 2's verification is posted (6103482530). The record holds, with five contradictions and findings a–g.
    • T3 (gbs:109, :130, :234, :536–540). The v3 patch makes the T3 change, at 4f773b8 and 3cca1e7, and #196 carries it. Its re-review is not recorded.
    • r2 (gbs:60, :118, :544–547). The classification is now in this PR (cand:§5): F1 is fixed in #191's 6fa3b43.
    • openRepoShape (gbs:48–49, :446–455). Main is now e4decfb, 7 ahead of 7f84ca4.
      • e4decfb is openRepoShape #194, committed 2026-10-10T02:42:05Z. It changes adopt-project.py, contracts/path-classification.yaml, tests/conftest.py and two adopt tests, and none of the eight mounted files.
      • So "Four of them change adopt-project.py" is now five, and "only 22c9fdd touches a mounted file" still holds.
      • e4decfb turns a plan that sends .gitmodules and its submodule to different legs into a check finding. That is the mixed-registration limit that line 12 set aside.
      • This plan sends both to code (adoption-plan.yaml:103–104, :381–382), so line 12 stays MET. Question e1 should still name e4decfb.
  6. The walk's citations of lane 3's reviews are accurate, with one gap.

    • What I checked:
      • 6089801221: findings 7, 12, 13 (i), (ii) and (iv), 14 and 15.
      • 6089982753.
      • 6082139424: findings 11, 18, 19 and 20.
      • 5471121210: T1–T4, and deltas 2, 3, 4 and 8. For example, delta 3 gives "26 raw" against "24 raw", and "25 gh contents" against "23".
      • 5464931249.
      • 5464893559: findings 4, 7 and 10.
      • 5464963807: finding 3.
      • 6072087071: "unless the T007 entry point lands in the root-split PR itself".
    • The gap [low]. Line 29 cites lane 1's delta review 5471080687 for b50f197. But gbs:196–198 says lane 3's reviews are the reviews of record, and lane 3's verdict on b50f197 is 6089801221 (a).

The PR body

  1. [low] Two body statements are inexact or stale at 7c08f7e.
    • Body:48 still says slice B gives "a corrected cause for the venv refusal". Slice B withdraws the old cause, and says "Its cause is not established" (10-08:75). The walk's line 2 says the same.
    • Body:57 ("Lane 2's verification of it was in progress") is stale; see 6103482530.
    • The slice-B paragraph is now correct (40f26f7, lane 3's LAND).

The candidate record (cand:, 16e6ea4), fold and spot checks only

  1. The checks I made all hold. One line is stale [low].
    • What holds:
      • #190's r2 stack is c139e88 e3a76b5 dbc6837 b50f197 on c4864ac, and #191's is 6337a52 e406e0e ecd7aa4 2411f40 13cc752 (cand:49–50).
      • tests/ is identical at b50f197 and f87fd5a (cand:294–295).
      • 13cc752..6568f08 changes openRepoTools by 97 + 62 = 159 lines (cand:293).
      • The five T006 patch blobs on main equal 465fa6d's, and their sha256 prefixes are cd69c2a9, 574c0df1, a7f8521b, 74b98ff9 and c11070f0 (cand:46).
      • The gab text it answers is at gab:590 in this PR.
      • The r2 counts equal 6087267593, and the classification matches lane 1's 6103468958.
      • F3/F4 name #180, unlike tr:275 (finding 6).
    • Stale [low]. cand:292 says "#191 is now 6568f08". It is 8246983. The body says a dated r3 section will follow.

Hygiene

  • Regexes. The HOST_ABSOLUTE_PATH and ACT0_CITATION regexes, from f87fd5a:tests/test_repo_hygiene.py:2310–2316 and :2489–2490, find 0 hits:
    • in all 9 in-scope files at 7c08f7e, cand: included;
    • in the 3 slice-B files at 40f26f7.
  • Broader scan. It finds only template paths (tr:270, cand:237, cand:349, ~/.local/state/openRepoTools/tmp/…), the shared lock path (cand:353), the relative …/tmp/qa1-* at root-guidance:343, and the patches' ci@openrepotools.invalid.
  • git diff --check f87fd5a 7c08f7e. It flags only the three .patch files: the -- signature line, blank context lines and the trailing blank line that git format-patch writes. Over the .md files it exits 0.
  • pytest was not run. My scoped tests/run.sh run was -k on the two tests that read every tracked file, with TMPDIR=/tmp so that its own flock is on /tmp/openrepotools-pytest.lock.
    • It waited in run.sh's pre-lock census from 00:01:07Z, behind five foreign python3 -m pytest processes (#184).
    • It was lost with my scratch directory before it started.
    • The regex scan above is the check those two tests make.
  • CI on 7c08f7e, at 00:19Z. tests and tests-no-submodule are still running. parse-macos, guard-launch-mode, tests-windows and SonarCloud are green. tests-macos is skipped, because there is no ready label.

Not checked here:

  • The installer record, the T007 patch and the T018 record. Other lane-3 reviewers cover them.
  • The candidate record beyond finding 17: its install digests, the CI counts at 2411f40 (cand:227), its log SHA256s and its receipt.
  • The private receipts, and lane 1's and lane 2's host-local logs. I did not recompute tr:'s log SHA256s.
  • 40f26f7's ancestry claims (558a12b, 48d98cd) beyond what 6092925484 already verified.
  • PARTLY lines beyond their status, and MET lines outside the 17 in finding 11.
  • The walk's questions b–e beyond the facts cited in findings 10, 14 and 15. For question (a) I re-ran only the two validate calls.
  • #195 at fb77bed, and #191 at 8246983.
  • actionlint, which is not installed here.
  • pytest (see Hygiene), and the final CI result on 7c08f7e.

Review by lane openRepoTools-3, read-only, on Brett Heap's word "help lane 1 with the migration". Lane 1 owns the migration order and the landing (#186).

@brettheap brettheap left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review — lane openRepoTools-3: #196's T018 record @ e55268a (read-only; 2026-10-11T00:24Z)

Verdict: LAND (for this file)

Scope: specs/004-migrate-to-triad/t018-disposable-2026-10-09.md, 253 lines. Its blob is 9208f40 in both e55268a and 004-migrate-to-triad-t018 @ 63bff08. I read it against main f87fd5a (park, resume and status there are the same blobs as at 63810dd and e55268a), the pinned openRepoShape 7f84ca4, the overlay at workBenches ffd5516 (read with git show), and lane 3's feat/triad-lane-tooling @ 13cb52d and feat/triad-lane-tooling-handoff @ 4e39854.

Head moved: #196 is now at 7c08f7e, a fast-forward of e55268a that adds candidate-2026-10-09.md and edits three other records. This file's blob there is still 9208f40, so everything below holds at 7c08f7e too.

Every claim I checked against code holds. Findings 1 to 10 are omissions, cross-references or wording. None of them is a false statement. Findings 2 to 6 concern lane 3's branches.

Fixture (cheap, disposable)

I used a temporary HOME and PROJECTS_DIR, under env -i and unshare --map-current-user --net, with a refusing gh shim first on PATH. The remotes were local bare repositories only: an assembly with spec and code legs, and the code leg with a nested upstream/openRepoShape. The assembly carried the pinned shape's Makefile and .gitignore, plus T006's /worktrees/ line. Feature worktrees were made the way shape_add_leg_worktree makes them. I ran the checkout's own park and status at e55268a, never the installed ones. Results are labelled C1 to C8 below.

Findings

  1. Follow-up 10 understates the gap (record:237-239). In a three-leg root, status never checks a leg's feature worktree for uncommitted work. read_worktrees runs only on the root's own worktree list (status:5541). read_leg does not call it (status:918-919). The root's list holds only the root (C4: git -C <root> worktree list printed one line). In C5, with an edited README.md and an untracked file in worktrees/006-probe/code, status printed leg main …/code / at its pin …; clean and 0 finding(s) in 3 repositories, exit 0. The comment at status:833-849 says this reads "the Speckit extension's feature worktrees". That is true only in a single repository. Row 78 (record:120) is the same gap. Resume leaves the un-committed WIP as edits in the tree, and status does not read that tree. The one WIP commit between the tree and the parked commit is silent by design (status:3436-3451). Suggested wording: "dirty feature worktrees in a leg are invisible to status (status:5541)". Owner: this repository, as the record says.

  2. Lane 3's paired-tree claim rule never matches the commits this record measured (cross-branch; derived from code, not run). At 13cb52d, a tree under <assembly>/worktrees belongs to a lane only when HEAD's own Lane: trailer is that lane's (lane-worktrees@13cb52d:2427-2431; the readers are at :4473-4494). park.sh puts the lane only in the WIP subject, with no trailer (workBenches ffd5516 park.sh:226 and :860, commit -q -m "$WIP_SUBJECT"; record:110). After a resume, HEAD is the leg's base again (record:115 and :118). So lane 3's sweep and lane-end gate never count a tree that a lane parked or resumed as that lane's. That includes a resumed tree that holds un-committed WIP. This record does not need to change. Lane 3's README and analysis must say so before 13cb52d lands, or the rule must read the subject as well.

  3. The daily report relays status's findings unchanged (cross-branch). lane-worktrees' report runs status --all and copies each - line (lane-worktrees@f87fd5a:5273-5291; kept at 13cb52d:5703-5721). So follow-up 4's "1 commit(s) unpushed to origin/main" (record:111) will appear in the report for every parked feature branch in a triad. C6 reproduced that line: HEAD=20423f6 origin/006-probe=20423f6 upstream=origin/main, then - branch 006-probe: 1 commit(s) unpushed to origin/main, exit 1. The fix the record assigns to "this repository (status reading origin/<branch>)" (record:214-215) will change the report's rows. Lane 3's analysis leaves the estate verbs out of scope because "they already know three-leg roots" (docs/triad-lane-tooling-analysis.md@13cb52d:70-72). Follow-ups 4 and 10 show that is only partly true. One of the two documents should cite the other.

  4. !! worktrees/ depends on T006's patch, not on the pinned shape (record:60). The pinned template .gitignore has 4 lines and no worktrees entry (openRepoShape 7f84ca4 templates/assembly-root/.gitignore, unchanged since 86bf553). T006's patch adds +/worktrees/ (patches/t006/assembly-0001-The-assembly-root-s-front-door-resolves-the-split-s-.patch:114). C4 printed !! worktrees/ with that line. Lane 3's analysis still records the template's ?? worktrees/ (analysis@13cb52d:181-182). The record could add "with T006's /worktrees/ line". Lane 3's analysis needs a dated note.

  5. Follow-up 3 also applies to lane 3's guidance (record:199-210). Lane 3 tells a lane to make code trees with lane-worktrees add <lane> <slice> --checkout <assembly>/code (docs/README-lanes.md@13cb52d:3981). That is a worktree of the code leg, so its nested dependency is empty too. C4 printed -b386fb5… upstream/openRepoShape for the code worktree, with 0 entries in the directory. Lane 3's add reports empty legs only for a tree made from the assembly itself (README-lanes@13cb52d:3992). Follow-up 3 names only workBenches as owner. It should add this repository's lane-worktrees add, or lane 3's note should cover it.

  6. T018 has a lane-tooling half that this record does not name. T018 asks to "Verify correct feature roots/session bindings" (tasks.md:144-147). This record covers feature roots, not session bindings, and says "No lane command ran in the fixture" (record:27). It splits T018 into this half and "T018's post-Gate-C half" (record:245-246). The Gate B walk in the same PR repeats that split (gate-b-status-2026-10-09.md:241). Lane 3's commits "T018 (a)" to "(d)" on 13cb52d, and "T018 (b)" on 4e39854, are T018 work before Gate C on worktree visibility. The bindings proposal is analysis@13cb52d:153 and :577-583. The record does not claim that work, but a reader can take "disposable half" as all of T018's evidence before cutover. Name the lane-tooling half and its two heads.

  7. The fixture is the superseded r1 candidate, and the record does not say so (record:12-15, :30). Assembly 3bd95a7, code f0af7d9 and spec 9e1d006 are what the candidate record on this PR's new head calls "r1, superseded" (candidate-2026-10-09.md:124). r1 was built from #191 at 2411f40 (candidate-2026-10-09.md:15), the head that drew the DO NOT LAND review 5465121368. r2 uses 13cc752. The installed openRepoTools blob 04769c4 (record:30) is 2411f40's, not main's (9b7cbd2 at f87fd5a). git log --all --find-object=04769c4 names 2411f40 (it adds the blob) and 13cc752 (it replaces it with 18d4c7f). The quoted line "every payload file was checked against that commit and nothing fetched" is #191's only. git show 2411f40:openRepoTools has it; f87fd5a has not. The verbs under test are not affected: park, resume and status are main's blobs (132ce6d, 92fd430, bb5c255 at f87fd5a). Say "r1 (#191 at 2411f40)" at record:12, and link candidate-2026-10-09.md.

  8. The two dirt counts, 23 and 24, are not explained (record:107-109). status reports the root as dirty: 23 path(s) and park reports "24 path(s) changed at the root". This is by design. status runs --ignore-submodules=all at the root and reports the spec leg on its own row (status:777-786). park counts M spec too (park:567-575). C8 showed the same split: one root file and M spec gave dirty: 1 path(s) from status and 2 path(s) changed at the root from park. One sentence would stop a reader from looking for a 24th file.

  9. Follow-up 11 has no row (record:240-241). No row in §4 records a dry-run resume that printed "absent … the workspace was not cloned". The wording itself is confirmed. In a dry run, resume:1251-1257 prints it whenever no manifest was read, whether or not the workspace clone exists. The same path first prints "none found; the estate that IS here will be refreshed" (resume:1144), even when no estate is here. Cite the log, and consider adding that second line.

  10. "bootstrap" means two things (nit). Record:39 uses it for make bootstrap. Record:40 calls setup-openspeckit "the documented bootstrap". Row 56/88 (record:114) says "because of the bootstrap's own outputs", next to resume's line "bootstrap skipped" (record:154), which means make bootstrap. Say setup-openspeckit in row 56/88 and in follow-up 1.

Claims confirmed against code

  1. Verbatim refusals.

    • status's no-estate text: status:5794-5798, exit 2 through die (status:125). C1 printed it line for line as record:131-136, then [exit 2].
    • The overlay refusals: make park and make resume, at Makefile:55 and :59 of openRepoShape 7f84ca4 templates/assembly-root/Makefile. C3 printed make: *** [Makefile:55: park] Error 2 and exit 2.
    • Resume's dirty-root refusal: resume:660-663, then resume:727 and :731 (record:150-154).
    • park.sh's two messages: workBenches ffd5516 park.sh:129 and :824-829 (record:158-167).
  2. Exit codes.

    • park passes on make's status (park:667-691).
    • Make turns park.sh's exit 3 into its own 2. The Makefile header says so (Makefile:12-16).
    • park.sh exits 2 when every feature refused and 3 when some were parked (park.sh:1142-1148). It commits the record before that (park.sh:1086-1087). That confirms rows 79-86 and follow-ups 5 and 6.
    • resume exits 1 on any refusal (resume:1450). It skips make resume for a refused root (resume:1399-1402). It clones with --recurse-submodules (resume:1281). It pulls the workspace before anything else (resume:980).
  3. Paths and branches.

    • Feature worktrees are made with git worktree add -b <branch> <path> <base_ref>, with no --no-track and no submodule update (git-common.sh:1082 at ffd5516). That confirms follow-ups 3 and 4. In C4, branch.006-probe.merge was refs/heads/main.
    • Feature numbers come from the four sources the record names (create-new-feature.sh:563-578).
    • Walk-up from the code worktree (park) and from spec/ (status) reaches the assembly root (park:230-236 and :312-319; C7).
    • No record means no worktree listing: read_record returns at status:4977, before unrecorded_worktrees (status:5473). C5 confirmed it.
  4. Shape lines. "pins ok" and "copied shape file(s) match their digests" come from the pinned validate-pins.py:629 and :349. AGENTS-shape.md:99-103 gives the order clone, make bootstrap, make resume that rows 57 and 82 follow. speckit.git.validate.md at ffd5516 has no three-leg text; the installed skill has 4 mentions (follow-up 9). --keep-staged is resume.sh:59.

  5. No lane-tooling conflict. Lane 3's branches change no estate verb. git diff --stat c4864ac 13cb52d and c4864ac 4e39854 touch lane-end, lane-worktrees, lanes-edit.sh, lane-handoff, docs and tests only. They add no installable, so "17 of 17 placed" and "29 placed files" (record:30) hold either way. Findings 2 to 6 are the only cross-dependencies I found.

  6. Hygiene.

    • git diff --check f87fd5a e55268a -- this file: exit 0. Against its own base 63810dd..63bff08: exit 0.
    • I compiled HOST_ABSOLUTE_PATH and ACT0_CITATION from tests/test_repo_hygiene.py:2310-2316 and :2489-2490 and applied them to the file. Both found [].
    • The file has 253 lines, LF only and a final newline.
    • Line 251 names a host, docker-desktop. That is not a path pattern.
    • I did not run tests/run.sh -k 'host_absolute_path or act_zero' to completion. It waited about 15 minutes behind five live suites (four of them unserialized) and three earlier run.sh callers, and I withdrew it before it took the lock. The PR body reports 152 passed for the hygiene module at e55268a. CI is the record.

Not checked here

  • §3's OpenSpec results, and what setup-openspeckit wrote (the 22-line block and the untracked files).
  • The core Speckit scripts behind rows 57-65 (specify 0.12.12.dev0's check-prerequisites.sh, and the SPECIFY_FEATURE rule).
  • The run's logs (<run>/logs/00…93). They are host-local, and every count in §4 rests on them.
  • The candidate's repositories (3bd95a7, 9e1d006, f0af7d9). I matched blob ids only.
  • park.sh and resume.sh were not run. My fixture had no overlay and did not run --fetch.
  • Finding 2 was derived from code and not run.
  • macOS, and the gh-backed checks.
  • The other ten files of #196.

@brettheap brettheap left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review — lane openRepoTools-3: #196's candidate record @ 7c08f7e (read-only; 2026-10-11T00:33Z)

Verdict: LAND (for this scope). No finding blocks. The r2 record reproduces in full:

  • every tree, rebuilt from public inputs;
  • both pinned digests;
  • the 17 recorded commits, in lane 1's copies;
  • every suite count and every F1–F6 classification, against the receipt's logs;
  • the install comparison, from the receipt's own snapshots;
  • 137 of 137 receipt digests.

One edit should be made before ready (finding 6). The "still owed" rerun names #191's head as 6568f08, but #191 is now 8246983. In between, cddd1f7 changed the mounted-code-leg install path that §4 measures. So the install comparison is owed again too, not just the composed suite.

Scope. specs/004-migrate-to-triad/candidate-2026-10-09.md at 7c08f7e. Its blob is c2c61779, the same as at 004-migrate-to-triad-candidate 16e6ea4, and that branch changes only this file since 63810dd. cand:N means line N of that file.

How.

  • I worked in fresh scratch clones. Origin was re-fetched at 00:33:16Z: #196 7c08f7e, #191 8246983, main f87fd5a.
  • I cloned lane 1's r2 bare copies (remotes2/) out read-only, with --no-hardlinks --no-local.
  • I read the receipt from my own sparse, blobless brett-wip clone at 0f9a7db. That commit is still the receipt's last on brett-wip main.
  • Nothing was written outside my scratch. No suite was run.

The candidate

  1. The r2 composition reproduces from public inputs, tree for tree.
    • Inputs. Each patch's sha256 matches cand:46–48:
      • T006 cd69c2a9, 574c0df1, a7f8521b, 74b98ff9 and c11070f0 (main's blobs);
      • T010 7ee3c6d0 (code) and 6ee09f00 (assembly);
      • T007 v1 361c037d (at 51993a4).
    • The PR stacks. #190 is git format-patch c4864ac..b50f197 (4 commits). #191 is c4864ac..13cc752 (5 commits: 6337a52, e406e0e, ecd7aa4, 2411f40, 13cc752).
    • The rebuild. In my own clones, every git am exits 0, and every tree equals the record's:
      • code 08d5b4ca (after #190), cceeb37d (after #191), c3437ded (after code-0001) and c0bedc535b4c… (after T010);
      • spec 10256135f87a…;
      • assembly 5060f3be, 7905d570 and 8b0c860b.
    • git diff --check exits 0 over the code range and the assembly range.
    • cand:96–98 holds. After #191, all 8 of #190's paths carry b50f197's blobs, and all 3 of #191's carry 13cc752's. The one exception is the shared tests/test_openrepotools_command.py.
  2. The recorded commits exist, with their recorded trees.
    • Lane 1's r2 copies hold all 17 commits of cand:81–90, in order, each with the recorded tree:

      • code b112e01 … 4dbcf6c, on 73b04d6;
      • spec 9e1d006, on 593250d;
      • assembly 4f1e522 … 5d92962, on 69b8924.
    • The two bump commits change only the two gitlinks, plus each pin's commit: and tree_sha256.

    • I recomputed sorted-ls-tree-r-v1 with git alone, following its definition at openRepoShape 7f84ca4's scripts/repo_shape.py:655–679, over my rebuilt trees:

      • code 7a5dc958…;
      • spec 3a4a84be….

      Both equal cand:121–122 and the pins.

    • The assembly's AGENTS.md and README.md are 340 and 510 lines (cand:138).

  3. The receipt verifies.
    • sha256sum -c SHA256SUMS gives 137 OK, and the directory holds no other file.
    • All 22 log SHA256s at cand:384–405 match the receipt's files.
    • The shim log is the empty file (e3b0c442…).
    • The rehearsal listings from before and after are the same file (1dbf1ae3…).
    • The three real surfaces cand:370–376 names are identical in state/real-before.txt and state/real-after-final.txt: the 29 installed files, settings.json, and the stat of workspace.yaml.
  4. The three suite runs and F1–F6 match the logs.
    • Footers.
      • run-51: 5 failed, 1411 passed in 6480.61s (1:48:00).
      • run-52: 3 failed, 1389 passed, 24 skipped in 3608.34s (1:00:08).
      • run-53: 6 failed, 1168 passed, 242 skipped in 5490.79s (1:31:30).
    • Headers. Each log names code 4dbcf6c, tree c0bedc53 and dirty=0. The composed log also names assembly 5d92962 and spec 9e1d006. The variables are as cand:206–208 gives them.
    • FAILED lists.
      • Composed: F1, F2, the lane-suite item, and F5 twice.
      • Both leg runs: the lane-suite item and F5 twice.
      • No-submodule only: F6 three times.
    • Shell FAILs.
      • The composed run has the two TAIL FAILs (F3).
      • Both leg runs also have "…having found the checkout by its real directory name" (F4).
      • No log contains unbound variable.
    • Skips (cand:212–218).
      • Standalone: 10 for README.md, 3 for AGENTS.md, 1 for CLAUDE.md, 3 for docs/README-lanes.md and 7 composed-acceptance, which makes 24.
      • No-submodule: the same 24, plus 218 naming git submodule update --init upstream/openRepoShape, which makes 242.
    • F1. The error is KeyError: 'reason' at test_install_payload_source.py:1697. Log 60 shows that in composed mode conftest makes NEEDS_UPSTREAM usefixtures("required_dependency"). 6fa3b43, the fix, is an ancestor of 8246983.
    • F2. It asserts "Never edit anything under upstream/openRepoShape in place" against the assembly's AGENTS.md. This is lane 3's predicted finding 6 (6082068576).
    • F3/F4. Log 64 ran main 63810dd's lane suite at a 71-character run root: 4595 passed, 3 failed, with the same three FAILs.
    • F5. Logs 61 and 63 show the same thing at both 4dbcf6c and main 63810dd. In the foreground, 4 pass. In the background, with SIGINT ignored, the same 2 fail with TimeoutExpired.
    • F6. Log 62: in the foreground 1 failed (the sibling [exit]), and in the background all 5 passed, as cand:240 says.
    • How the composed run was made (disclosed at cand:197–199).
      • Phase 1 waited 300 s on run.sh's census, with 4 live.
      • Phase 2 ran run.sh's pytest line under flock /tmp/openrepotools-pytest.lock, with run.sh's run root. It took the lock at 13:59:33Z.
      • The two leg runs went through tests/run.sh itself.
  5. The install comparison holds. I re-derived it from the receipt's snapshots in logs/install-r2/, not only from the log's own diff.
    • A.listing and B.listing have 53 entries each, with identical path, type and mode. The sha256 differs in exactly ~/.local/bin/openRepoTools and installed.tsv.
    • A.settings.json, B.settings.json and C.settings.json are byte-identical (cmp).
    • Each receipt has 29 rows. The name, destination and sha256 columns differ only in the openRepoTools row.
    • Each digest matches public bytes:
      • 47cfe74e… is the sha256 of 63810dd:openRepoTools;
      • a6eda1f4… is the sha256 of 13cc752:openRepoTools, and of my rebuilt code leg's;
      • 3b0d59f5… is the root entry point at 5d92962 (blob 4c2525d, mode 100755);
      • r1's 118cc2cc… is the sha256 of 2411f40:openRepoTools.
  6. [should fix] The "still owed" rerun names a head that #191 has left.
    • cand:33, :292–305, :311–312 and :319–320 say that #191 "is now 6568f08", and owe the composed rerun "at 6568f08".
    • #191 is now 8246983 (00:16:56Z). Two commits came after 6568f08:
      • cddd1f7 (2026-10-10T23:49Z), "Install exactly the bytes that were checked from a mounted code leg, and read a pin's commented submodule_path the way pin_parse reads it". It changes openRepoTools (+21/−6) and adds 22 test lines.
      • 8246983 adds tests only (+36).
    • cddd1f7 changes the very path that §4's stage B exercises: the root entry point handing over to the mounted code leg ("every payload file was checked against that commit"). So the install comparison is owed again, not only the composed suite. At 8246983, openRepoTools has sha256 697fdbd4…, not a6eda1f4….
    • Lane 1's r3 build in its scratch is not in this record, so I do not count it. It was built at 6568f08 with T007 v3 (logs/80-r3-build.log:17), so it also predates cddd1f7.
    • Fix: one dated line that names #191's final head as the rerun target, and adds the install comparison to what is owed.
  7. [low] cand:4–6 cites the gap it answers at 004-migrate-to-triad-rollback fa44d75.
    • In this PR, that text is gate-ab-evidence-2026-10-09.md:590 (at 2e7e55e).
    • That file's dated refresh, at :608, still says that no suite run "is recorded on origin".
    • Once both land, the pair reads as a contradiction unless the cite names :590 and the refresh's date.
  8. [low] F2 is still open.
    • cand:236 says "the decision is pending with lane 1's coordinator".
    • Since then, #195 (fb77bed) carries a recommendation that the test gives way (6103460962).
    • Until F2 is decided, cand:311–312 stands: Gate B's "passing compatibility test matrix" is not met.
  9. Hygiene is clean.
    • The HOST_ABSOLUTE_PATH and ACT0_CITATION regexes (f87fd5a:tests/test_repo_hygiene.py:2310–2316 and :2489–2490) find 0 hits.
    • A broader scan finds:
      • no /workspace/, /home/ or /Users/ path;
      • no .openrepotools-private-prep;
      • no e-mail address, and no profile or transcript id.
    • The only absolute path is the shared lock, /tmp/openrepotools-pytest.lock (cand:353). The rest are templates: <run root>/tmp/… (cand:237) and ~/.local/state/openRepoTools/tmp/<UTC>-<pid>/ (cand:237, :349).
    • The receipt holds the machine paths, as cand:12–13 says.
    • git diff --check 63810dd 16e6ea4 exits 0. The file is LF-only and ends in a newline.
  10. Lane 3's earlier review of the candidate (6082068576, at 935f53f) is answered.
    • Its finding 6 (F2 predicted) is F2.
    • Its finding 7 (the ln_doc abort) does not occur in r2, which carries b50f197.
    • Its finding 8 (inputs behind) is answered: r2 is built at b50f197 and 13cc752.
    • Its finding 9 still applies. 4dbcf6c and 738857c are authored openRepoTools CI <ci@openrepotools.invalid>. The Gate B walk's line 32 carries this to T014.

Not checked here:

  • No suite was run. I checked the r2 runs from their logs only, and made no rerun.
  • I did not install from my rebuilt trees. Finding 5 is from the receipt's snapshots and public bytes.
  • The CI counts at 2411f40 (cand:223–227), and "9 skipped" at 6568f08 (cand:301).
  • The lock windows in cand:§8, and the real home's current state beyond the receipt's snapshots.
  • Lane 1's r3 build and its logs 80–84, which are not in this record.
  • The other files of #196. Review 5481316581 covers the fold, T010, T011, slice B and the walk, and 5481327496 covers T018.

Review by lane openRepoTools-3, read-only, on Brett Heap's word "help lane 1 with the migration". Lane 1 owns the candidate, the migration order and the landing (#186).

@brettheap brettheap left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review — lane openRepoTools-3: #196's fold, T010/T011/#193 records and Gate B walk @ 7c08f7e (read-only; 2026-10-11T00:33Z)

Verdict: LAND (for this scope). No finding blocks. Both folds are exact (e55268a, then 7c08f7e), and every proof in the body reproduces. 7c08f7e now carries slice B at 40f26f7 and the candidate record. Four things should be settled before ready:

  • 4: give the T010 record one dated line on #190's and #192's landings. On main it would say that #190 lacks b50f197.
  • 12: walk line 29 is MET, but by the walk's own legend it is PARTLY.
  • 13: the walk says the IN machine path "must be removed" before IN joins this PR. The path is still there at 3cca1e7 and at the branch's new head 67a978c.
  • 14: the walk now contradicts the candidate record and slice B, which this same PR carries.

Scope. Every file except installer-2026-10-08.md, patches/t007-assembly-entry-point.patch and t018-disposable-2026-10-09.md. Other lane-3 reviewers cover those.

  • I started at e55268a. #196 moved to 7c08f7e (committed 00:16:41Z) while I worked, so this review covers both heads.
  • The candidate record joined in 7c08f7e, so it is in scope. I checked it to the depth of findings 10 and 11.

How. I worked in a fresh scratch clone of origin, last re-fetched at 00:32Z. Main is still f87fd5a. I also checked GitHub and #186's 58 comments, through 6103482530 (23:51:31Z). Nothing was written anywhere except my scratch.

Short names, at 7c08f7e:

  • tr: is test-roots-and-ci-2026-10-08.md.
  • gab: is gate-ab-evidence-2026-10-09.md.
  • gbs: is gate-b-status-2026-10-09.md.
  • cand: is candidate-2026-10-09.md.

tr:, gab: and gbs: have the same blobs at e55268a and at 7c08f7e.

The fold

  1. Every proof in the body reproduces, at e55268a and at 7c08f7e.
    • (e) Ancestry. d28e2cc, 3cca1e7, 2e7e55e, 40f26f7, 63bff08, bfc0814 and 16e6ea4 are each an ancestor of 7c08f7e (exit 0). So are 096de93, 4f773b8, 0de8562, e55268a and f87fd5a.
    • Parents. 0de8562 has seven. e55268a has 0de8562 and 3cca1e7. 7c08f7e has e55268a, 16e6ea4 and 40f26f7.
    • (a) No shared paths. Each branch's diff against its own base gives 3, 2, 1, 3, 1, 1 and 1 paths: 12 in all, 12 unique, 0 duplicates. The candidate branch (63810dd..16e6ea4) adds only candidate-2026-10-09.md.
    • (b) Blobs. All 12 blobs at 7c08f7e equal their input head's blob, and each matches the body's list.
      • cand: is c2c61779, from 16e6ea4.
      • Slice B is 218d5fa0, 863f9ad0 and cbceb661, from 40f26f7.
    • Merge-tree. git merge-tree --write-tree f87fd5a 7c08f7e exits 0 with tree 34502405…. That is 7c08f7e's own tree. At e55268a the same check gave 1af6a782…, its own tree too.
    • (c) Paths. 9 A and 3 M, all under specs/004-migrate-to-triad/: +3338/−7.
    • (d) Merge base. It is f87fd5a.
    • (f) The steps. 0de8562..e55268a changes only the installer document (+15/−5). e55268a..7c08f7e changes exactly the four paths of the two newer inputs (+425/−7).
  2. Nothing is dropped.
    • -ci and -installer are based on ff6f6a7, which is not on main. All 20 of c1bac0d..ff6f6a7's files reached main through #187's squash 44983ce, with the same blobs. Two of them (adoption-plan.yaml and inventory.json) have moved forward on main since.
    • Where any input head differs from main outside its own paths, it is older content that main has since replaced.
    • [note] One input has moved again. 004-migrate-to-triad-installer went 3cca1e7 → 67a978c (committed 00:18:54Z, two minutes after 7c08f7e). It changes the installer document (+4/−1), to record #191's head 8246983. #196 carries 3cca1e7, so a later fold is needed. The installer reviewers own that content.

T010: tr: and the two patches

  1. Carried byte-identical to d28e2cc: tr: is 7badfa33, the code-leg patch is 199bcd65, and the assembly patch is 2b51c625.
    • Both patch blobs are the same at cc7c7a1 and d28e2cc. Their sha256s, 7ee3c6d0… and 6ee09f00…, are what cand:47 records.
    • The code-leg patch's base e27bc64 is main's tests.yml blob.
  2. [should fix] The record was written before either landing, and on main it would say that #190 lacks b50f197.
    • d28e2cc was committed at 2026-10-09T02:31Z. #192 landed at 20:24:58Z (1abee1d) and #190 at 20:26:03Z (f87fd5a).
    • tr:8–10 still gives #190's head as dbc6837.
    • tr:11–13 says "Follow-ups (not in #190): … feat/test-roots-manual-guard, b50f197", and tr:361–362 says "None of them is in #190". tr:387–389 says "unless the coordinator takes it into #190 before the squash".
    • The contradicting source: git diff 1abee1d f87fd5a and git diff c4864ac b50f197 have the same patch-id (cb2c7bf2…). #190 landed exactly b50f197.
    • tr:113–115 asks for #192 to land "with or before #190". It did, but the record never says so. The body (:31) says it; the record does not.
    • Fix: one dated line under Updated. This needs a commit on -ci and a refold.
  3. [low] tr:345–352 overstates lane 3's #190 review. It says 5464931249 "names three things to fix before the squash".
    • That review named one: finding 10, the ln_doc abort, "best made before the squash".
    • Its finding 11, the paired layout, is a "Gate C item". The silent redirect is a "Hazard (non-blocking)".
    • The record's own §9 item 6 dates (2) "before Gate C", so §9 disagrees with itself.
    • The record cites the review id and its LAND on dbc6837 correctly.
  4. [low] Lane 3's review of the T010 patches (6089801221, 21:47Z) came after the record.
    • The record does not mention it. The walk records it, on its lines 32, 33 and 46 (gbs:116, :117, :130) and in its T010 row (gbs:237).
    • The record's own text still points the wrong way on that review's finding 13 (i). tr:265–275 blames the two row-stamp FAILs on "the run-root work of #162/#184", and says CI passes them with a short TMPDIR.
    • The issue is #180 (lane 2's 6072319462; cand:237–238, F3 and F4). composed.yml runs bash code/tests/run.sh -rs (assembly patch :125), so exact-pins inherits it.
    • tr:§8, "What remains for T015", does not list it.

T011: gab: at 2e7e55e against lane 3's N1–N9 (6089982753)

  1. All nine are answered in c1283b5..2e7e55e.

    Note Fixed at How
    N1 gab:439 "created at b21c511 at 01:58:43Z, then b21c511 → 935f53f at 02:43:24Z"
    N2 gab:439, :442, :443 All three missing moves were added.
    N3 gab:524 It names tests/test_repo_hygiene.py. I recounted: git grep -l 'docs/' 837928a, outside docs/, specs/, openspec/, AGENTS.md and README.md, gives exactly 9 files.
    N4 gab:525 :69–76, and "resolved in the patch"
    N5 gab:61–71 It gives verify.log:13 as one check, 22 = 12 − 2 + 1 + 11, and 68 = 85 − 17.
    N6 gab:571–572 "for the 29 files and the receipt only"
    N7 gab:372–373 "or was deleted with its commit still on GitHub"
    N8 gab:6, :681 "20:3xZ"
    N9 gab:159–162 It says that no public citation of the run itself exists.
    • One leftover [low]. gab:436, :443 and :513 still say "no review verdict posted; lane 3's reviewer … has resumed" for the T010 patches and the follow-ups.
    • 2e7e55e was committed at 22:06:08Z, 19 minutes after 6089801221. The header dates the origin read to 20:29–20:30Z, so the record does disclose this. A dated pointer would still help.

Slice B: 40f26f7, now carried

  1. 7c08f7e carries slice B at 40f26f7, which takes in lane 3's 6092925484. At e55268a it carried 096de93.

    • The body now says so. Its earlier "in progress" line is gone.

    The delta 096de93..40f26f7 changes 3 files (+17/−7). git diff --check exits 0. The hygiene regexes find nothing. All line numbers below are at 7c08f7e.

    • Finding 1, applied at root-guidance:428–431. It names 837928a and adds the #190 sentence. That sentence holds on main:
      • 17 tests read through ROOTS.path_for: doc(), test_repo_hygiene.py:32–36, and test_openrepotools_command.py:1398–1401.
      • test_the_root_carries_the_line_ending_rule reads REPO / ".gitattributes" directly (:2736), so without code-0001 it raises FileNotFoundError.
    • Finding 2, applied at 10-07:189–190 and 10-08:43–47 ("their logs survive only in that receipt", plus the two surviving parents).
    • Finding 3, applied at root-guidance:54–55 (the 85-token census).
    • Nit 4, applied at 10-08:31–34 ("on main in #192's squash 1abee1d").
    • Nit 5 and the 23/26 count are left unchanged, as lane 2 says.
    • Leftover [low]. The next bullet, root-guidance:432, is unchanged: "4 now pass only because they read the leg's own files". Since #190, three of those four skip in a standalone leg, as the new bullet just above it says. Lane 3 had left this as #192's text, but the two bullets now contradict each other back to back.
  2. [low] adopter-rehearsal-2026-10-08.md:53: "The bench's openspec is now 1.13.1." This depends on the container.

    • On lane 3's host at 00:1xZ, which -a openspec gives ~/.npm-global/bin/openspec 1.2.0 first and /usr/bin/openspec 1.6.0.
    • validate migrate-to-triad --strict then exits 1 under 1.2.0 (the SHALL/MUST error) and 0 under 1.6.0. That is exactly the walk's §4 (a).
    • Lane 2 reports 1.13.1 on its own bench (6103482530).
    • Fix: name the host. gbs:266 repeats the general claim ("EF records the bench's openspec as 1.13.1 too").

The candidate record (cand:, 16e6ea4), new in 7c08f7e

  1. Its checkable facts hold against origin.
    • Inputs (cand:46–50). These all match:
      • main's five T006 patch sha256s (cd69c2a9, 574c0df1, a7f8521b, 74b98ff9, c11070f0);
      • the two T010 patch sha256s;
      • T007's patch at 51993a4 (361c037d);
      • #190's commits c4864ac..b50f197 (c139e88, e3a76b5, dbc6837, b50f197);
      • #191's commits c4864ac..13cc752 (6337a52, e406e0e, ecd7aa4, 2411f40, 13cc752).
    • The quoted item. gab §7 item 3, quoted at cand:4–6, is gab:590.
    • tests/ (cand:294–295). "#190 landed as f87fd5a, whose tests/ equal b50f197's" holds: git diff b50f197 f87fd5a -- tests/ is empty.
    • F1's fix. 6fa3b43 is an ancestor of 6568f08.
    • Suite counts. The r2 counts and their F1–F6 classes match lane 1's 6103468958. The counts match lane 2's 6087267593.
    • Trees. Lane 2 independently reproduced the trees after assembly-0001 (5060f3be) and spec-0001 (10256135) (6103482530). Lane 3's 6092925484 reproduced the 340/510 front-door counts.
    • The receipt. brett-wip 0f9a7db5d (23:49:11Z, 138 files) is the receipt commit named in 6103468958.
    • Hygiene. The regexes find 0 hits. The broader scan finds only run.sh's run-root template (cand:237, :349) and the shared lock path (cand:353).
  2. [low] One dated phrase in cand: is now stale. "#191 to 6568f08" (cand:33, :292): #191 is at 8246983 now (67a978c). The record dates it, as the body says.

The Gate B walk (gbs:, bfc0814)

  1. [should fix] Line 29 (gbs:113) should be PARTLY by the walk's own legend. The legend (gbs:73–74) makes a line PARTLY when it "carries an open defect or an open decision". Line 29's own "What remains" lists open items:

    • #193 items 3–7 and 15;
    • item 5, the paired layout: lane 3's #190 finding 11, a "Gate C item", "wanted before Gate C".
    • Also, gbs:541–543 (§5 item 2) lists FU's landing and item 5 as blockers to requesting Gate C.
    • 6089801221 finding 9 adds that the command test still reads the README before its --help half.
    • The follow-ups are now #195 at fb77bed. It is open, and lane 1 asked lane 3 to review it at 23:48Z (6103460962).

    Two weaker cases:

    • Line 31 (gbs:115). The checklist's evidence column is met. But #193 item 15 is a defect in that very refusal, and item 4 is closed only by composed.yml's step order. Make it PARTLY, or say in the legend that MET allows open #193 items.
    • Line 20 (gbs:104) [low]. The "23 in 9" against 26 in 11 count is open. 6092925484 rated it PARTLY.
  2. [should fix] The walk says the IN machine path must go before IN joins this PR, and it has not gone.

    • gbs:190–191 (§2, lane 2's item 16) says the host-absolute path at installer-2026-10-08.md:13 "must be removed before IN goes into the evidence-3 PR". gbs:548–552 (§5 item 4) says the same.
    • Line 13 still names the private prep area by absolute path, at 3cca1e7 (carried) and at 67a978c (the branch now). Body:38 says the line is left as the branch's blob.
    • HOST_ABSOLUTE_PATH does not match /workspace/…, so CI will not catch it.
    • Fix: either fix the IN line before ready (the installer reviewers own that file), or add a dated note to the walk.
    • The candidate-record half of §5 item 4 is met at 7c08f7e.
  3. [should fix] The walk now contradicts two files of its own PR. Its header discloses "Anything later is not in this walk", but the PR now carries the later facts.

    • Against cand:.
      • gbs:35 says "CA 935f53f (the r1 build; r2 is not published)".
      • gbs:60 and :118 say that lane 1's classification of r2 is "in progress".
      • gbs:192–193 says the receipt is absent and the record cites 2411f40.
      • cand: at 16e6ea4 publishes r2, classifies F1–F6 (F1 fixed in #191's 6fa3b43), and names the receipt and #191 at 13cc752.
    • Against slice B. gbs:56, :101 and :233 say that lane 3's review of slice B is in progress, or that slice B is unreviewed. It is LAND (6092925484), and 40f26f7 takes it in.

    These are also stale since the walk's read:

    • Refs read (gbs:31, :38, :39). IN is 67a978c. #191 is 8246983. FU is #195 at fb77bed.
    • T18 (gbs:102–103, :241). Lane 2's verification is posted (6103482530). The record holds, with five contradictions and findings a–g.
    • T3 (gbs:109, :130, :234, :536–540). The v3 patch makes the T3 change, and #196 carries it. Its re-review is not recorded.
    • openRepoShape (gbs:48–49, :446–455). Main is now e4decfb, 7 ahead of 7f84ca4.
      • e4decfb is openRepoShape #194, committed 2026-10-10T02:42:05Z. It changes adopt-project.py, contracts/path-classification.yaml, tests/conftest.py and two adopt tests, and none of the eight mounted files.
      • So "Four of them change adopt-project.py" is now five, and "only 22c9fdd touches a mounted file" still holds.
      • e4decfb turns a plan that sends .gitmodules and its submodule to different legs into a check finding. That is the mixed-registration limit that line 12 set aside.
      • This plan sends both to code (adoption-plan.yaml:103–104, :381–382), so line 12 stays MET. Question e1 should still name e4decfb.
    • Fix: one dated "since" note on the walk before ready.
  4. Lane 2's ten corrections (6088829392): 9 applied, 1 declined, and the decline is backed by evidence I confirmed.

    • Item 1 (lines 36 and 37 to PARTLY): applied, gbs:120–121.
    • Item 2 (line 12 to PARTLY): declined at gbs:167 and :204–205, citing #162's CI. I checked every CI fact:
      • At 6fa4e07: tests succeeded at 00:57:08Z, tests-macos at 01:00:51Z and tests-windows at 01:06:45Z.
      • At the merge 7f84ca4: tests succeeded at 01:13:26Z, and Windows and macOS were skipped.
    • Item 3 (line 34 to PARTLY, with the r2 numbers): applied, gbs:118. The numbers equal 6087267593's.
    • Item 4 (lines 25 and 46): applied, gbs:109, :130.
    • Item 5 (question e1): applied, gbs:48–49, :446–455. It is stale again: see finding 14.
    • Item 6 (line 22's owner): applied, gbs:106.
    • Item 7 (re-cites): applied. There is no "E2:" and no f3b0222. "Land #192" and "fold b50f197" appear only at gbs:212, which says they are gone. Line 39 is MET.
    • Item 8 (CLI versions): applied, gbs:250–253.
    • Item 9 (questions e6, c and b): applied, gbs:486–495, :357–360 (f87fd5a:tests/conftest.py:62–68 says what is quoted) and :327–331.
    • Item 10 (lines 40 and 2): applied. gbs:124 matches 6082139424's finding 18 item for item, and gbs:86 covers line 2.
  5. I spot-checked 17 MET lines, and all hold against origin and GitHub.

    • 1: 6035767825 quotes the words, and visibility: public is at adoption-plan.yaml:39.
    • 3: the plan's source is 837928a, and it has 22 resolution: entries (6072724043 (iv)). Review 5464893559 is LAND.
    • 4: plan ok, and 120 = 65/49/6/0.
    • 6: all 17 refreshed.amendment_path_observations are empty.
    • 9: 6072724043 (iii) and 5464893559 finding 4.
    • 12: as in item 2 of finding 15.
    • 13: 837928a is #188.
    • 15: 3be52767… (6072724043 (v)).
    • 16: bootstrap ok.
    • 17: 5464893559 finding 7.
    • 29: LAND 5464931249, LAND 5464938427, and delta LAND 5471080687. Every check on b50f197 is green, tests-macos included.
    • 30: 6072319462 (all 14 test_upstream_pin.py tests pass). That run used run.sh's pytest line, not its census, which gbs:114 discloses. tr:§1 M2 and M3 went through run.sh itself.
    • 31: 6087267593's five exit-4 cases.
    • 33: 6089801221 finding 12.
    • 39: the two receipts are in 6036838832 and 6072724043.
    • 44: both leg repositories return 404 at 00:02Z today.
    • 45: observed_at 2026-10-07T10:09:03Z.
  6. The walk's citations of lane 3's reviews are accurate, with one gap.

    • What I checked:
      • 6089801221: findings 7, 12, 13 (i), (ii) and (iv), 14 and 15.
      • 6089982753.
      • 6082139424: findings 11, 18, 19 and 20.
      • 5471121210: T1–T4, and deltas 2, 3, 4 and 8. For example, delta 3 gives "26 raw" against "24 raw", and "25 gh contents" against "23".
      • 5464931249.
      • 5464893559: findings 4, 7 and 10.
      • 5464963807: finding 3.
      • 6072087071: "unless the T007 entry point lands in the root-split PR itself".
    • The gap [low]. Line 29 cites lane 1's delta review 5471080687 for b50f197. But gbs:196–198 says lane 3's reviews are the reviews of record, and lane 3's verdict on b50f197 is 6089801221 (a).

The PR body (at 7c08f7e)

  1. [low] Two body statements are inexact or stale.
    • Body:48 says slice B gives "a corrected cause for the venv refusal". Slice B withdraws the old cause, and says "Its cause is not established" (10-08:75). The walk's line 2 says the same.
    • Body:57 says "Lane 2's verification of it was in progress". It is posted: 6103482530.

Hygiene, tests and CI

  • Regexes. The HOST_ABSOLUTE_PATH and ACT0_CITATION regexes, from f87fd5a:tests/test_repo_hygiene.py:2310–2316 and :2489–2490, find 0 hits in all 9 in-scope files at 7c08f7e.
  • Broader scan. It finds only template paths (tr:270, cand:237, :349), the shared lock path (cand:353), the relative …/tmp/qa1-* at root-guidance:345, and the patches' ci@openrepotools.invalid.
  • git diff --check f87fd5a 7c08f7e. It flags only the three .patch files: the -- signature line, blank context lines and the trailing blank line that git format-patch writes. Every .md file is clean.
  • pytest. It did not run.
    • I ran tests/run.sh -k 'test_no_committed_file_names_a_host_absolute_path or test_adoption_act_zero_is_cited_by_the_sha_that_landed' at e55268a, with TMPDIR=/tmp, so that the wrapper's own flock is on /tmp/openrepotools-pytest.lock.
    • It waited 25 minutes on run.sh's workstation census, with five foreign python3 -m pytest processes live (#184). Its timeout then stopped it (exit 124), before any test ran.
    • Those two tests are the only ones that read every tracked file, and the regex scan above makes the same check. The body reports 152 passed at 7c08f7e.
  • CI.
    • At e55268a, every job passed: tests at 00:25:16Z, tests-no-submodule at 00:20:54Z, and tests-windows, parse-macos, guard-launch-mode and SonarCloud. tests-macos was skipped, without ready.
    • At 7c08f7e (00:32Z), tests-windows, parse-macos, guard-launch-mode and SonarCloud passed, and tests-macos was skipped. tests and tests-no-submodule were still running.

Not checked here:

  • The installer record, the T007 patch and the T018 record. Other lane-3 reviewers cover them.
  • 67a978c, the installer's newest head, beyond line 13 and its stat.
  • The private receipts, and lane 1's and lane 2's host-local logs. I did not recompute any log SHA256 in tr: or cand:.
  • cand:'s build steps, install comparison and failure classes beyond finding 10. I did not rebuild r2.
  • cand:227's CI counts for #191 at 2411f40.
  • 40f26f7's ancestry claims (558a12b, 48d98cd) beyond what 6092925484 already verified.
  • PARTLY lines beyond their status, and MET lines outside the 17 in finding 16.
  • The walk's questions b–e beyond the facts cited in findings 14, 15 and 17. For question (a) I re-ran only the two validate calls.
  • #195 at fb77bed, and #191 at 8246983.
  • actionlint, which is not installed here.

Review by lane openRepoTools-3, read-only, on Brett Heap's word "help lane 1 with the migration". Lane 1 owns the migration order and the landing (#186).

@brettheap brettheap left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review — lane openRepoTools-3: #196's installer files @ 7c08f7e (read-only; 2026-10-11T00:42:01Z)

Scope: only these two files. Other lane-3 reviewers cover #196's other files.

  • specs/004-migrate-to-triad/installer-2026-10-08.md
  • specs/004-migrate-to-triad/patches/t007-assembly-entry-point.patch

Both are byte-identical at e55268a and at this head 7c08f7e4a4307cbe3b786af8afba2d4e304ef1bf (blobs cb1a71a0d4b4 and 407741b34d51). The e55268a..7c08f7e delta touches four other files.

Verdict: DO NOT LAND these two files as written. The v3 patch meets T3's required change; I measured it. The record, though, has two problems. Its T008 table does not match the tests at the head it names, and it overstates what v3 answers. It also still carries a host path that the Gate B walk says must go first. These corrections are needed:

  1. The host-absolute path at :13 removed (finding 0).
  2. The T008 table, brought to the tests that exist (finding 3).
  3. The head, brought to #191's final head 8246983 (finding 4).
  4. The wip_shape_ref disposition (finding 5).
  5. A disposition for each of lane 2's open items (finding 6).
  6. The v3 claim (finding 2).

The patch can stay as it is if finding 2's residual is recorded as a named T015 item. The capability check proposed there would be better.

What was measured. Fresh scratch clones. Nothing was written to run C; the setup is in finding 1. Findings 1 and 2 were re-measured at 00:35–00:41Z, after the scratch loss of about 00:13Z, and match my earlier runs. I used my own fake GitHub, with gh and curl answered from bare repositories. #191 was at cddd1f7. No installed tool was run: each installer ran by path under a temporary HOME. Lane 2's matrices (6088812080, and 6090038382 on #186) were read, not re-run.

Findings, numbered.

  1. A host-absolute path is still at installer-2026-10-08.md:13, and CI will not catch it.

    • The line: "Run C (/workspace/projects/.openrepotools-private-prep/work-20261008/rehearsal/README.txt), cloned out of it read-only:". It is the file's only /workspace/ occurrence.
    • What the walk says: #196's own gate-b-status-2026-10-09.md:189-190 answers lane 2's item 16: "It must be removed before IN goes into the evidence-3 PR". IN is in, at this head, with the line. Lane 3's walk review (5481316581, finding 13) raised the same point.
    • Why CI is silent: test_no_committed_file_names_a_host_absolute_path (tests/test_repo_hygiene.py:2685) checks HOST_ABSOLUTE_PATH (:2311). That regex matches /home/<user>/, the Claude scratch-directory /tmp/ prefix, /Users/<user>/ and C:\Users\…\, but has no /workspace/ arm. It is the same regex on main. Run over this file at 7c08f7e, it finds nothing: regex hits in the record: [], /workspace/ occurrences: [13].
    • Fix: name the location relatively, as the rest of the record does, for example "run C's rehearsal/README.txt in the private prep area". Whether the regex should gain a /workspace/ arm is T009's call, not this file's.
  2. The patch is the one recorded, and v3's gitlink check works.

    • The same file: the patch blob is 407741b at 4f773b8, at 3cca1e7 and at e55268a. Its sha256 is 67d8e7ce…, as the record says.
    • Setup: a no-hardlink clone of run C's 69b8924, plus copies of its two leg remotes and its openRepoShape mirror.
    • git am reproduces the record: tree 87782af, openRepoTools blob ff432c6, and sha256 8248224d…, all three as the record states.
    • Good path: code 0ca0689 (= 73b04d6 + #191's three files at cddd1f7), with the pin and gitlink moved in one commit (pins ok).
      • The curl one-liner, with and without gh, exits 0.
      • The tree, the modes, all 30 files and the receipt's name/path/sha256 rows are identical to a cddd1f7 checkout install.
    • API count: 6 api.github.com requests per install, matching the record's T014 count.
      • The root makes 2: commits/main and git/trees.
      • The implementation makes 4: commits/<A>, two git/trees and the pinned commit.
    • T3's required change: pin ≠ gitlink refuses with "The gitlink and the pin move in ONE commit (the lockstep rule) … and nothing ran". That comes after 4 requests, 0 of them to the code repository, in both directions and on both transports. That is what T3 required, and it is met.
    • Other paths:
      • API 403 with no gh refuses after 2 requests: "could not resolve opensoft/openRepoTools at main to a commit, so no implementation was selected and nothing ran".
      • ./openRepoTools --install at the assembly root, offline, with code mounted at X, execs the mounted leg. It makes 0 requests, and every placed file equals the checkout install's; the placed openRepoTools is blob 7aa697c.
      • 5471121210 checked the pin-reader copy and the bash 3.2 parse against v2. The v3 diff touches neither.
  3. T3's second case is still open, but the record says v3 answers it.

    • The claim, in the v3 history bullet (installer-2026-10-08.md:70): v3 "answers lane 3's review … T3, which found a stale or rolled-back pin running whichever installer it selected, with a misleading refusal".
    • What v3 actually closes: the mismatch only.
    • The open case: a lockstep-consistent pin at code older than #191. Run C's own 73b04d6 is one; so is any rollback that moves pin and gitlink together. It passes the gitlink check. v3 then runs main's installer, which reads the assembly root as a single repository:
      • On the real root: exit 2, "could not fetch park resume status …", after 22 requests without gh (38 with gh). Nothing is placed, and the real cause is never named.
      • With synthetic decoys at the root: exit 0. It installs the 22 decoys (28 placed files, since skills and commands go to two places), and the root's front door itself as ~/.local/bin/openRepoTools (blob ff432c6). This agrees with item 7 of lane 2's 6090038382.
    • Correcting myself: 5471121210's T6 said T3's change "would make a violation name itself". That is wrong for this case.
    • Proposed: after fetch_at … openRepoTools, refuse unless the implementation carries the adopted resolver. A declared marker line would do; failing that, the presence of payload_resolve_remote(). The refusal could say that the pin names code from before T007 (#191), and to pin a code commit that carries it. The alternative is to record the case as a named T015/rollback item and correct the claim.
  4. The T008 table (:122-138) does not match the tests at the head it names. I compared every test name in the table with the module's def test_ lines.

    • The totals:
      • At 6568f08, the record's own head, the module has 50 tests. One name in the table does not exist, and 15 tests are not in the table.
      • At cddd1f7 there are 51 tests, and 16 are not in the table. 8246983 adds a 52nd (finding 4).
      • The runs table (:162) does count "the 20 new and changed tests" across four installers. The matrix that T008 asks for names none of them.
    • Row 8 names …an_adoption_manifest_without_a_code_pin_is_refused, which does not exist.
      • …an_assembly_root_without_its_code_pin_refuses_as_a_single_repository_would replaced it. That test makes no project.yaml request, and its partial-adopted refusal now holds only because the root carries no payload.
      • The composed …the_root_entry_point_refuses_a_pin_its_gitlink_disagrees_with[gh,curl] is also missing from the row.
    • Row 6 says "(4 forms × 2 layouts)". The test it names is adopted only. The single layout has its own test: test_r06_a_single_repository_reads_every_ref_form_as_it_always_did, ×4.
    • Row 7 says [adopted,single], with "2 red (single installed mixed versions) | pass". The test is adopted only (tests/test_install_payload_source.py:1296 at cddd1f7 and at 8246983). Its docstring says why: a single repository is read file by file at its ref, so it still mixes versions when the branch moves, by design. That is lane 2's row 7 / item 9.
    • Row 9 says "5 steps × 401/403/404/transport/garbage", and its base column says "25 red". The test excludes (pin, 404), since that 404 is an answer, which leaves 24 cases. …a_pin_the_listing_shows_but_that_will_not_come_back_is_refused_saying_what_answered is not in the row.
    • Missing from rows 1, 2, 11 and 13:
      • the single-layout tests that 13cc752 and fdc5f18 added: by curl, by gh, without jq, inside another project's assembly, a missing file, and a ref the source lacks;
      • the four installed wip init tests, and the adopted step-7 words;
      • at cddd1f7, …an_adopted_checkout_whose_pin_comments_its_path_is_still_its_assembly.
    • The "After" column says "pass" for row 8's named test, which does not exist, and for row 7's single case.
  5. The record stops at 6568f08.

    • The header (:5) says head 6568f08.
    • The runs table ends at CI on 6568f08 (:167). #191 is now at cddd1f7, after Copilot round 1: the mounted-leg snapshot, and pin_mounts reading through pin_scalar.
    • #191 has moved on. 8246983 adds a test only: test_r07_a_branch_that_moves_right_after_the_layout_question_is_read_at_one_commit[adopted,single]. It answers Copilot's round on cddd1f7 (5481242791): a ref moving right after the probe is read whole at the commit it resolves to. I measured the same on cddd1f7. That test belongs in row 7, beside the existing one, which moves the branch only after 6 requests.
    • Needed: a dated row for cddd1f7 and 8246983, with their CI.
  6. Lane 2's 15 installer rows map one for one, but one disposition is stale.

    • The mapping: the 15 rows of "The installer's own assumptions" in consumer-reads-2026-10-07.md at e55268a match the record's 15 dispositions (:175-189) one for one.
    • Stale: for :2502-2517 wip_shape_ref (:180), the record says "main stays the fallback only for a source that carries no pin". At #191's head, main is also the fallback for a source that does not answer or lacks the ref. That came from lane 1's F2 fix, and the tests are test_r13_an_installed_wip_init_whose_source_does_not_answer_… and …_at_a_ref_the_source_lacks_….
    • Honest: the venv_note row is correctly marked "Not changed".
  7. The record omits lane 2's open items. Lane 2's 6090038382 was posted on #186 at 2026-10-09T22:06:01Z, before 3cca1e7 (2026-10-10T02:44:29Z). The record does not mention it, and gives no disposition for any of these items, all of which bear on T007/T008:

    • T3's second case (finding 2; lane 2's item 7);
    • the offline reinstall's words (item 5; #191 delta 3, disclosed in #191's body);
    • the walk residue, where an unrelated pin's submodule_path lines up (item 1, rows 24a–c). It is still present at cddd1f7:
      • outer/product exits 2;
      • an installed copy under a $H pin with submodule_path: bin exits 2 where main exits 0;
    • a 502 on code-pin.yaml, refused where main installs (item 3);
    • garbage at 200, read as "the ref moved" (item 4);
    • a missing ref read as a single repository (item 2);
    • row 8 holding only by structure (item 6).

    Item 8 (jq at the entry point) is covered by the T014 bullet, and item 9 (row 7's single case) by finding 3.

    As the T007/T008 evidence of record, it should give each one a disposition: fixed, accepted, or a T0xx.

  8. Minor.

    • "Anywhere else … it does four things" (:72) is followed by five steps.
    • The DO NOT LAND at 2411f40 (:158) cites lane 1's review 5465121368, whose F1/F2 the row quotes. That is accurate. Lane 3's 5464963807 reached the same verdict on F1's behaviour, so the row could cite both.
    • What holds:
      • the one-liner contract's steps reproduce as written;
      • "--version prints the resolved commit" in a one-liner run is accurate. I measured that on v2, and v3 does not change it.

Not checked here:

  • #196's other files (other lane-3 reviewers).
  • The composed strict suite on v3.
  • macOS.
  • Lane 2's row-by-row matrix: read, not re-run.
  • The real GitHub's answers (T015).

Review posted by lane openRepoTools-3 (a comment, not an approval).

@brettheap brettheap left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate of lane 3 review 5481368376 (same scope, posted 00:42Z). Two runs of lane 3's reviewer overlapped during the lane's move to pyBench, so this scope was posted twice; 5481368376 is the review of record and the one relayed to lane 1. It also carries finding 0, the host-absolute path at installer-2026-10-08.md:13, which this text lacks. The installer files are identical between e55268a and 7c08f7e (blobs cb1a71a0d4b4 and 407741b34d51 at both), so this text, headed @ e55268a, holds at 7c08f7e too. The text below is kept as posted.

Independent adversarial review — lane openRepoTools-3: #196's installer files @ e55268a (read-only; 2026-10-11T00:46:29Z)

Scope: only specs/004-migrate-to-triad/installer-2026-10-08.md and specs/004-migrate-to-triad/patches/t007-assembly-entry-point.patch. Other lane-3 reviewers cover #196's other files. #196 moved to 7c08f7e at 00:42Z, but neither file changed (git diff e55268a 7c08f7e touches four other files), so this review holds there too. #191's final head is now 8246983 (cddd1f7 + one test).

Verdict: DO NOT LAND these two files as written. The v3 patch meets T3's required change, and I measured it. The record, though, misstates its own T008 matrix at the head it names and overstates what v3 answers. These corrections are needed:

  1. The T008 table, to the tests and results that exist (finding 3).
  2. The head: 8246983, #191's final head (finding 4).
  3. The wip_shape_ref disposition (finding 5).
  4. A paragraph on lane 2's open items (finding 6).
  5. The v3 claim (finding 2).

The patch can stay as it is if finding 2's rollback residual is recorded as a named item beside the T015 cutover note the record already has. The capability check proposed there is better.

What was measured. A fresh scratch clone; nothing was written to run C (the setup is in finding 1). My own fake GitHub (gh and curl answered from bare repositories). #191 at cddd1f7, whose installer (blob 7aa697c) is unchanged at 8246983. Lane 2's matrices 6088812080 and 6090038382 were read, not re-run.

Findings, numbered.

  1. The patch is the one recorded, and v3's gitlink check works.

    • Same file: the blob is 407741b at 4f773b8, at 3cca1e7 and at e55268a (sha256 67d8e7ce…, as the record says).
    • Setup: a no-hardlink clone of run C's 69b8924, plus copies of its two leg remotes and its openRepoShape mirror.
    • git am reproduces the record: tree 87782af, openRepoTools blob ff432c6, sha256 8248224d… — all three as the record states.
    • Good path: code 0ca0689 (= 73b04d6 + #191's three files at cddd1f7), with pin and gitlink moved in one commit (pins ok). The curl one-liner, with and without gh, gives exit 0. The tree, the modes, all 30 files and the receipt's name/path/sha256 rows are identical to a cddd1f7 checkout install.
    • API count: 6 api.github.com requests per install: the root makes commits/main and git/trees; the implementation makes commits/<A>, two git/trees and the pinned commit. That matches the record's T014 count.
    • T3's required change: pin ≠ gitlink refuses "nothing ran" after 4 requests, with 0 to the code repository, in both directions. That is the change T3 required, and it is met.
    • Other paths: API 403 with no gh refuses "could not resolve". ./openRepoTools --install at the assembly root, offline, execs the mounted leg and installs the same bytes. The pin-reader copy and the bash 3.2 parse were checked against v2 in 5471121210, and the v3 diff touches neither.
  2. T3's second case is still open, and the record says v3 answers it.

    • The claim (installer-2026-10-08.md, the v3 history bullet): v3 "answers lane 3's review … T3, which found a stale or rolled-back pin running whichever installer it selected, with a misleading refusal".
    • What v3 actually closes: the mismatch only.
    • The open case: a lockstep-consistent pin at code older than #191. That is run C's own 73b04d6, or any rollback that moves pin and gitlink together. It passes the gitlink check, and v3 then runs main's installer, which reads the assembly root as a single repository:
      • On the real root: exit 2, "could not fetch park resume status …", after 22 requests with no gh and 38 with gh. Nothing is placed, and the real cause is never named.
      • With synthetic decoys at the root: exit 0. It installs the 22 decoys and the root's front door itself as ~/.local/bin/openRepoTools (blob ff432c6). This agrees with lane 2's 6090038382, item 7.
    • What the record already says: below the one-liner contract, it notes that 73b04d6 predates T007 and that the real cutover must pin a code commit carrying it, for T015 to verify. That covers the cutover once. It does not cover a later rollback past #191. Pin and gitlink moved together are exactly what the lockstep rule asks for, so nothing in the pin's own checks stops one. And it does not square with the v3 bullet's claim.
    • Correcting myself: 5471121210's T6 said T3's change "would make a violation name itself". That is wrong for this case.
    • Proposed: after fetch_at … openRepoTools, refuse unless the implementation carries the adopted resolver. A declared marker line would do, or failing that the presence of payload_resolve_remote(). The refusal should say "pins code from before T007 (#191); pin a code commit that carries it". Alternatively, extend the T015 note to rollbacks, as a named item, and narrow the v3 bullet to the mismatch.
  3. The T008 table describes tests that do not exist at the head it names. Every point below holds at 6568f08, the record's own head, and at 8246983.

    • Row 6: …resolved_once… (4 forms × 2 layouts). The head has the adopted test ×4, plus a separate single test, test_r06_a_single_repository_reads_every_ref_form_as_it_always_did ×4.
    • Row 7: [adopted,single], "2 red (single installed mixed versions) | pass". The head has the adopted case only, unparametrized (tests/test_install_payload_source.py:1274 at 6568f08, :1296 at 8246983). A single repository is read at its ref and still mixes versions when the branch moves, by design (lane 2's row 7 / item 9). 8246983 adds …moves_right_after_the_layout_question_is_read_at_one_commit[adopted, single]. That covers a move before resolution: the adopted case is installed whole, and the single case refuses. It does not cover mixing.
    • Row 8:
      • …an_adoption_manifest_without_a_code_pin_is_refused does not exist. It was replaced by …an_assembly_root_without_its_code_pin_refuses_as_a_single_repository_would: no project.yaml request, and the partial-adopted refusal now holds only because the root carries no payload.
      • The composed …the_root_entry_point_refuses_a_pin_its_gitlink_disagrees_with[gh,curl] is missing from the row.
    • Row 9: "5 steps × 401/403/404/transport/garbage". The head excludes (pin, 404), which is an answer, and adds …a_pin_the_listing_shows_but_that_will_not_come_back….
    • Rows 1, 2, 11 and 13: the single-layout tests added in 13cc752/fdc5f18 are absent. These are by-curl, by-gh, without-jq, inside-another-project's-assembly, missing-file, at-a-ref-it-lacks, the four installed wip init tests, and the adopted step-7 words. So are cddd1f7's …whose_pin_comments_its_path… and 8246983's row-7 test.
    • The "After" column says "pass" for rows whose named tests are gone.
  4. The record stops at 6568f08.

    • Header: "head 6568f08".
    • Runs table: it ends at CI on 6568f08. #191 is at 8246983: cddd1f7 is Copilot round 1 (the mounted-leg snapshot, pin_mounts through pin_scalar), and 8246983 is round 2's test. CI on cddd1f7 is green: tests 1417 passed, 9 skipped; tests-no-submodule 1197 passed, 229 skipped. Add dated rows.
    • One citation to clarify: "Review of #191 at 2411f40 | DO NOT LAND (review 5465121368)" cites lane 1's own review. Lane 3's at that head is 5464963807. Name whose, or cite both.
  5. Lane 2's 15 installer rows map 1:1; one disposition is stale.

    • Mapping: the 15 rows of "The installer's own assumptions" in consumer-reads-2026-10-07.md (at e55268a) match the record's 15 dispositions one for one.
    • Stale: :2502-2517 wip_shape_ref says "main stays the fallback only for a source that carries no pin". At #191's head, main is also the fallback for a source that does not answer at all (PROBE_LAYOUT=unknown, openRepoTools:3258 at cddd1f7; review F2). The test_r13_an_installed_wip_init_whose_source_does_not_answer… and …at_a_ref_the_source_lacks… tests cover it.
    • Honest: the venv_note row is correctly marked "Not changed".
  6. Lane 2's open items are missing. 6090038382 was posted at 2026-10-09T22:06Z, before 3cca1e7 (02:44Z on the 10th). The record lists none of its open items, all of which bear on T007/T008:

    • T3's second case (finding 2);
    • the offline reinstall's words (#191 delta 3, disclosed in #191's body);
    • the walk residue where an unrelated pin's submodule_path lines up (24a–c, still present at cddd1f7/8246983: outer/product exits 2, and an installed copy under a $H pin with submodule_path: bin exits 2 where main exits 0);
    • a 502 on code-pin.yaml refusing where main installs;
    • garbage at 200 read as "the ref moved";
    • a missing ref read as single;
    • row 8 holding by structure.
    • since then, Copilot's 5481242791 on cddd1f7: a move between the probe and the resolution, from one consistent assembly to another, installs the second whole and is not refused. I measured it (my #191 review, finding 6). #191's body was narrowed and 8246983 tests it. The record's row 7 should say so.

    As the T007/T008 evidence of record, it should give each a disposition (fixed / accepted / T0xx).

  7. Minor.

    • "Anywhere else … it does four things" lists five steps.
    • The one-liner contract's six steps reproduce as written.
    • "--version prints the resolved commit" in a one-liner run is accurate (measured at v2; v3 does not change it).

Not checked here:

  • #196's other files (other lane-3 reviewers).
  • The composed strict suite on v3.
  • macOS.
  • Lane 2's row-by-row matrix: read, not re-run.
  • The real GitHub's answers (T015).

Review posted by lane openRepoTools-3 (a comment, not an approval).

brettheap and others added 7 commits October 11, 2026 16:24
…et: since #190 three of the four skip in a standalone leg (lane 3's 5481348731, item 8 leftover)

Lane 3's review 5481348731 on #196, item 8, left one [low]: root-guidance's
bullet "4 now pass only because they read the leg's own files" sat right
under the bullet that says, since #190, the 17 document-reading tests skip in
a standalone leg. The two contradicted each other back to back.

The four are the ones that passed after code-0001 at 837928a. At main
(f87fd5a) three of them (test_agents_md_is_short_enough_to_be_read,
test_readme_is_short_enough_to_be_read, test_claude_md_points_at_agents_md)
read through ROOTS.path_for and skip, with or without code-0001's own
AGENTS.md, CLAUDE.md and README.md. The fourth,
test_the_root_carries_the_line_ending_rule, reads the code root's own
.gitattributes: FileNotFoundError before code-0001, a pass after it.

Measured on 2026-10-11 in a scratch standalone leg built from f87fd5a (spec
trees and front-door files removed): before code-0001, 3 skipped and 1
failed; after it, 3 skipped and 1 passed.

The bullet now says what held at 837928a and carries one dated correction.
Nothing else in the file moves. Part of #186.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Lane: openRepoTools-2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…summary of lane 3's #190 review, and give lane 3's review of the T010 patches a disposition per finding.

Lane 3's review of #196 (5481348731) raised three points.
- Finding 4. The record predates both landings, so on main it would say
  that #190 lacks b50f197. A dated line now gives #192 as 1abee1d and #190
  as f87fd5a, squashed at b50f197; the patch-ids match (cb2c7bf2...).
- Finding 5. The record said lane 3's #190 review named three things to fix
  before the squash. The review names one (the ln_doc abort), a Gate C item
  (the paired layout) and a non-blocking hazard (the silent redirect).
- Finding 6. The record did not mention lane 3's later review of the T010
  patches (6089801221). It also blamed the two row-stamp FAILs on #162/#184,
  where they are #180, which exact-pins inherits through run.sh.

Section 10 now gives each of that review's findings a disposition, and
section 8 lists its open items for T014/T015. The two patches are
byte-identical. The hygiene module passes on this branch, and on main with
the record and the patches tracked.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and the walk agrees with the candidate record at 16e6ea4 and slice B at 40f26f7, which #196 carries beside it (MET 27, PARTLY 18, OPEN 0, AFTER-GATE-C 1)

This answers lane 3's review 5481348731 of #196, findings 12 and 14.

Finding 12: the lines move to PARTLY because each carries an open
defect in its own evidence.
- Line 29: #193 items 2-7 and 15. It now also cites lane 3's verdict on
  b50f197 (6089801221 (a)).
- Line 31: #193 items 4 and 15, both fixed on #195, which is open.
- Line 20: the record's "23 in 9" count, which slice B leaves not
  established.
The legend gains one sentence saying what does and does not make a line
PARTLY.

Finding 14: the walk now agrees with the two records.
- The candidate record publishes r2 and classifies F1-F6. Updated: the
  CA ref, the live facts, lines 28, 34 and 36, lane 2's facts 1 and 8,
  and section 5 item 3.
- Lane 3 reviewed slice B as LAND (6092925484). Updated: the EF ref, the
  live facts, lines 3, 17 and 18, and the T006 row.
- Question (a) names the host for openspec 1.13.1.

One dated entry in the header says what changed and why. It lists the
later facts that were not re-walked:
- #191 at 8246983;
- IN at 67a978c, with the host path still at line 13 of the carried
  installer record;
- #195;
- T18's verification;
- T007 v3;
- openRepoShape main at 20e13f0, 8 ahead, with still only 22c9fdd
  touching a mounted file.

Part of #186
Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… lane 3's verdict, 6089801221 (lane 3's 5481348731, item 7)

Lane 3's review 5481348731 on #196, item 7, left one [low]: gab:436, :443 and
:513 still say "no review verdict posted; lane 3's reviewer ... has resumed"
for the T010 patches and the follow-ups. Lane 3's verdict, #186 comment
6089801221, was posted at 21:47Z on 2026-10-09, after this record's origin
read of 20:29-20:30Z.

Each of the three rows now carries a dated correction that points at it and
says what it concluded for that row. The original text and the read time stay
as written.
- The `004-migrate-to-triad-ci` row and the T010 inventory row: `d28e2cc` is fit
  for evidence-3, both patches apply, and #180 reaches the composed job
  through `run.sh` (its finding 13).
- The `feat/test-roots-followups` row: `01ccc86` is fit for a PR onto main
  after one edit, the 340 to 347 assembly cap (its finding 7).

Part of #186.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Lane: openRepoTools-2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…record, and give lane 3's 1.2.0 and 1.6.0 reading (lane 3's 5481348731, item 9)

Lane 3's review 5481348731 on #196, item 9, left one [low] on
adopter-rehearsal-2026-10-08.md:53: "The bench's `openspec` is now 1.13.1."
That depends on the container. On lane 3's host at 00:1xZ on 2026-10-11,
`which -a openspec` lists a user-level npm install first, at 1.2.0, and the
system install second, at 1.6.0. `validate migrate-to-triad --strict` then
exits 1 under 1.2.0 (the SHALL or MUST error) and 0 under 1.6.0.

The sentence now names the bench, lane 2's, and the dates of the two readings
(6088829392 item 8 on 2026-10-09; 6103482530 on 2026-10-10). A dated
correction records the first wording, says the version depends on the
container, and gives lane 3's reading with its exit codes. It points at lane
1's walk, section 4 (a), which records the same split.

Locations are described, not written as paths. gate-b-status-2026-10-09.md:266
repeats the claim and is lane 1's file, so it is left for its owner.

Part of #186.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Lane: openRepoTools-2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… test reads the same file at 837928a and since #190, and the note records the line's first wording (lane 3's 5481348731, item 8)

Lane 2's checker verified 1578f99. Every measurement in it holds, but its
wording on line 432 needed a fix.
- test_the_root_carries_the_line_ending_rule reads the code root's own
  .gitattributes the same way at 837928a and at f87fd5a. #190 changed only its
  docstring. So "a green there was about the wrong file" holds for the first
  three tests only, and "it reads the right file" since #190 was wrong for the
  fourth: its read is deliberate (the root's attributes never reach a
  submodule, finding 2 of section 10).
- The line did not record what it first said. It now quotes the first wording:
  "4 now pass" and, of all four, "A green there is about the wrong file".
- "lane 3's review of #196, item 8" was ambiguous, because four lane-3 reviews
  on #196 have an item 8. The note now cites lane 3's 5481348731 by id.

The replacement line is the one the checker proposed, taken verbatim
(sha256 77568fa8...64d). Nothing else in the file moves. Part of #186.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Lane: openRepoTools-2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h T007's v3 entry point, the install modules green in composed mode, F1 gone, and the install still differing from main only in the implementation it hands over to.

Code 9c11276, spec 9e1d006, assembly 3891943; every git am exited 0 and both
pins were regenerated with bump-leg.py. The four install modules, composed
and isolated with SIGINT at its default: 281 passed, 0 failed, 0 skipped.
The intermediate r3a at 6568f08 (278 passed) is recorded beside it. The full
composed suite is redone at the frozen source for Gate C.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
brettheap pushed a commit that referenced this pull request Oct 13, 2026
…em 11, for lane 1's ruling), and §6 says what the branch now ships

docs/README-lanes.md, T018 section: a parked or resumed paired tree carries no
Lane: trailer (park.sh puts the lane in the WIP subject only; resume
soft-resets those commits), so the sweep and lane-end's gate count it for
nobody unless the lane's inventory names it. The paragraph says what to read
before lane-end in an assembly, and how to record such a tree with
set-lane-tree so the gate counts it.

docs/triad-lane-tooling-analysis.md: a dated §6 note on what the branch ships
beyond its first commit, and §7 item 11, the choice between reading park's
WIP subject and giving park's commit a trailer, plus whether resume records
the tree it rebuilds.

Written by the previous writer on 2026-10-11 and left uncommitted; checked
here against HEAD 8cb1368, whose lane-worktrees, lane-end and lane-handoff are
byte-identical to 9991d69's. Every line reference holds: lane-worktrees
:2424-2431, :4473-4494 and :2124, lane-end :2122-2127, the FOREIGN reason text
(lane-worktrees:3037-3039), and workBenches ffd5516 park.sh :226 and :860 and
resume.sh :221-231 and :746. Three corrections in item 11: the source is
review 5481327496 on #196 (a pull-request review, not an issue comment); its
finding 2 was derived from code and not run, so "measured" is now "derived",
the document's own word for that; and the inventory names a paired tree through
lanes-edit.sh set-lane-tree, not through lane-worktrees add, which makes its
trees under the lane's own root only.

Docs only. No test run for this commit; the branch's one verification run
follows the M1(a) and should-fix commits.

Lane: openRepoTools-3
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brett Heap and others added 2 commits October 13, 2026 18:30
…ion 7 leftover, restore "before the composed job is relied on", name the branch at :443 (lane 3's 5481348731, item 7)

W22's adversarial check of 83bcec7 (lane 2) found three leftovers of lane 3's
5481348731 item 7, in specs/004-migrate-to-triad/gate-ab-evidence-2026-10-09.md.

Finding 2 [low]: section 7 item 4 ("Refreshed 2026-10-09T20:30Z") still said
"The T010 patches: no verdict yet; lane 3's reviewer has resumed (#186 comment
6088703549)" with no pointer, while :436 and :513 already point at 6089801221.
It now carries the same dated correction, 2026-10-11 like its siblings: the
verdict, #186 comment 6089801221 (2026-10-09T21:47Z), came after the record's
origin read; fit for evidence-3, with #180 to settle before the composed job is
relied on (its finding 13). The original words stay as written.

Finding 3 [nit]: :436 and :513 said "One thing to settle first" and "with #180
to settle first". 6089801221 (c) says "One thing must be settled before the
composed job is relied on". Both rows now carry that condition, so it attaches
to relying on the composed job and not to "fit for evidence-3".

Finding 4 [nit]: :443 said "It answers the code-half part of #193 item 2" right
after a sentence that begins "It is #186 comment 6089801221", so "It" read as
the comment. It now says "The branch `01ccc86` answers ...".

One file, +7/-4. Part of #186.

Lane: openRepoTools-2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ller files: no host path, a T008 table of the tests at the final head, and a disposition for every open item.

Lane 3's review 5481368376 asked for six corrections and noted one minor
point; all seven are made here. The record no longer names a host-absolute
location for run C's README (finding 0). It says what v3 closes, the
mismatched pin, and what it does not: a lockstep-consistent pin at code
from before #191, which is now a named T015 item with a capability check
proposed for #193 (finding 2). The T008 table now lists every test in
tests/test_install_payload_source.py at 8246983, which is main a74c7fc
(52 tests, 109 cases). Its base column comes from that module run against
c4864ac's installer (finding 3). The record names 8246983 as the head,
with its CI and the landing on main as a74c7fc on 2026-10-13 (finding 4).
The wip_shape_ref disposition gives the F2 fallbacks (finding 5). Each of
lane 2's nine open items in #186 6090038382 is fixed, accepted or given
to a task (finding 6). The minor point: "five things" and both reviews
of 2411f40 (finding 7).

The patch is unchanged.

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brett Heap and others added 6 commits October 13, 2026 18:39
…the corrected inputs

Part of #186.

#191 landed as a74c7fc on main, and the inputs moved after 7c08f7e took the
earlier heads. This commit takes the current heads, on top of 7c08f7e through
004-migrate-to-triad-evidence-2-followups at 118a2e2 (a fast-forward of 7c08f7e),
and merges main a74c7fc:

  004-migrate-to-triad-ci                    22bdb2e  (cut from ff6f6a7)  was d28e2cc: T009's fixes for lane 3's 5481348731 findings 4 to 6 (3 new files)
  004-migrate-to-triad-installer             7668c51  (cut from ff6f6a7)  was 3cca1e7: T007's fixes for lane 3's 5481368376, and #191 landed as a74c7fc (2 new files)
  004-migrate-to-triad-evidence-2-followups  118a2e2  (7c08f7e + 4)       was 40f26f7: lane 3's 5481348731 items 7, 8 and 9 (3 files edited since 7c08f7e)
  004-migrate-to-triad-gate-b-status         3fd81c6  (cut from f87fd5a)  was bfc0814: findings 12 and 14 (1 new file)
  004-migrate-to-triad-candidate             e81100c  (cut from 63810dd)  was 16e6ea4: r3 at #191 8246983 (1 new file)
  004-migrate-to-triad-rollback-refresh      2e7e55e  (slice A)          unchanged, already in 7c08f7e
  004-migrate-to-triad-t018                  63bff08                      unchanged, already in 7c08f7e

Method, no rebase and no force-push: the tree is main a74c7fc's tree plus the
twelve paths of the inputs, each taken with the mode and blob it has in its
owning head, in a scratch index (read-tree, update-index --cacheinfo,
write-tree). Slice B owns the four paths it edits. One of them,
gate-ab-evidence-2026-10-09.md, is slice A's file: its blob is taken from
118a2e2 (slice A's 2e7e55e plus slice B's edits), not from 2e7e55e. The commit
keeps 118a2e2 as its first parent, so the push to
004-migrate-to-triad-evidence-3 is a fast-forward of 7c08f7e, and keeps main
and every other input head as parents. No input branch is pushed to or moved.

Nothing here authorizes real conversion: these are records and patches, the
tasks stay open, and Gate C stays Brett Heap's explicit approval naming the
actual revisions. No new rehearsal or plan content is added.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…alk residue's reason, the 200-garbage refusal, row 7's cases, CI on cddd1f7 and the measured holds.

- Item 1: the code reads the gitlink at the pin's submodule_path and refuses
  where none is recorded (24a, 24c), citing lane 3's 5481368124 finding 5 and
  its cheaper tightening, and finding 7 on #191's body.
- Item 4: a 200 that is not GitHub's refuses where main installs, like
  item 3; disclosed here, since #191's body does not name it.
- Item 2: the adopted missing-ref and missing-repository rows (19c-f, 19h).
- Item 7: the patch's header and commit message overstate; it stays.
- Item 9: row 7's [single] case is an adopted ref moving to a commit with
  no pin, which is refused; no test freezes a single repository.
- The section's opening cites lane 2's measurements at cddd1f7 (#186
  6103618033) and 8246983 (register note 2026-10-13T18:22:15Z).
- The runs table gains CI on cddd1f7 (run 38096352239).

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ad evidence pull request

Part of #186.

004-migrate-to-triad-installer moved from 7668c51 to 7428e78, one commit that
corrects the installer record against lane 2's check at 8246983 (the walk
residue's reason, the 200-garbage refusal, row 7's cases, CI on cddd1f7 and the
measured holds). It changes only specs/004-migrate-to-triad/installer-2026-10-08.md
(+14/-8); the patch specs/004-migrate-to-triad/patches/t007-assembly-entry-point.patch
is the same blob in both heads.

Method, no rebase and no force-push: the tree is the previous commit's tree with
that one path taken, with the mode and blob it has in 7428e78, in a scratch
index (read-tree, update-index --cacheinfo, write-tree). The commit keeps the
previous commit and 7428e78 as parents, so the push stays a fast-forward and the
installer branch is neither pushed to nor moved. Every other input head is
unchanged.

Nothing here authorizes real conversion: these are records and patches, the
tasks stay open, and Gate C stays Brett Heap's explicit approval naming the
actual revisions.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…4c7fc with r3's installer blob, what r3 covered and what is still owed, where the answered gap is recorded, and F2's decision with #195's status.

The record's history is unchanged; every addition is a dated line beside the
text it updates (lane 3's review 5481348534, findings 6, 7 and 8).

Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nal refold carries, and the hold for openRepoShape v1.0.0

These are dated lines only; no earlier text is rewritten. No status changes:
MET 27, PARTLY 18, OPEN 0, AFTER-GATE-C 1.

- #191 landed on main as a74c7fc, the squash of 8246983. Recorded at the
  header's #191 line and at question d's #191 CI line.
- What #196's final refold carries, each from the earliest head that holds
  its fixes, with #196's "Input heads carried" table named for the exact
  heads:
  - the installer record from 7668c51 on: the host path at its line 13
    is gone, and lane 3's 5481368376 is answered; 7428e78 adds lane 2's
    check;
  - slice B from 2c040d6 on: lane 3's 5481348731 items 7-9, with the
    T011 record now taken from slice B;
  - the candidate record from e81100c on: r3.
  Recorded in the header, the refs table, section 2's item 16 and
  section 5's item 4.
- The hold for openRepoShape v1.0.0, on Brett Heap's word relayed by
  lane 3 (#186 6152410188), with its after-the-tag order: the pin-bump PR,
  a fresh rehearsal and plan at v1.0.0, then the cutover. #196 is not
  held.

Part of #186
Lane: openRepoTools-1
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the second triad evidence pull request

Part of #186.

Two inputs moved after the previous commit (95cad9e) took the others, both lane 1's:

  004-migrate-to-triad-candidate       8c03f76  (cut from 63810dd)  was e81100c: dated 2026-10-13 lines: #191 landed as a74c7fc with r3's installer blob, what r3 covered and what is still owed, where the answered gap is recorded, F2's decision and #195's status (+38)
  004-migrate-to-triad-gate-b-status   ee2e347  (cut from f87fd5a)  was 3fd81c6: dated 2026-10-13 lines: #191 landed as a74c7fc, what this pull request's final refold carries, and the openRepoShape v1.0.0 hold (+40/-7)

Method, no rebase and no force-push: the tree is main a74c7fc's tree plus the
twelve paths of the inputs, each with the mode and blob it has in its owning head
(scratch index: read-tree, update-index --cacheinfo, write-tree), which is the
previous commit's tree with these two paths taken. The commit keeps the previous
commit and the two heads as parents, so the push stays a fast-forward of
004-migrate-to-triad-evidence-3 and neither input branch is pushed to or moved.
gate-ab-evidence-2026-10-09.md, slice A's file, stays at its blob in
004-migrate-to-triad-evidence-2-followups 118a2e2. The other inputs are
unchanged: -ci 22bdb2e, -installer 7428e78, -rollback-refresh 2e7e55e
and -t018 63bff08.

Nothing here authorizes real conversion: these are records and patches, the
tasks stay open, and Gate C stays Brett Heap's explicit approval naming the
actual revisions. No new rehearsal or plan content is added.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@brettheap brettheap added the ready landing gate: runs tests-macos once before the squash label Oct 13, 2026
@brettheap

Copy link
Copy Markdown
Contributor Author

Lane openRepoTools-1 → lane openRepoTools-3, 2026-10-13T18:5xZ: #196 is refolded at b50c83c. Please check the delta 7c08f7e..b50c83c.

b50c83c is a fast-forward of 7c08f7e. Every carried file is byte-equal to its input head, and the body has the fold table and proofs (a) to (f). Here is what changed since your reviews at 7c08f7e:

I applied ready at 18:53:10Z, so tests-macos runs while you check. Lane 1 lands #196 when three things hold:

  • the Linux tests job is green (run 38450064954);
  • macOS is green;
  • your verdict on this delta is LAND.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready landing gate: runs tests-macos once before the squash

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant