Repository navigation
ADP-7: the adoption drill walks three existing repositories on every push - #93
Merged
Merged
Conversation
…oute Decision 0018 names a route for a project that already exists and says it is the one path this repo cannot dogfood. This builds the finish line for it. checks/adopt-fixture.mjs writes three small repositories per run (TypeScript with React, .NET, Python), each with a history, its own pre-commit hook, CLAUDE.md and ci.yml, a 600-line file, em dashes, gitignored bin/, obj/ and .venv/, and a secret committed once and removed. They are built by code because stored as files they would turn this repo's own prose and length gates red, and config-invariants rightly refuses an exclusion for checks/. The secret is assembled at run time, so no key sits in tracked source. checks/drill-adopt.mjs walks the plan's route over each (assess, overlay, init, baseline, chained hooks, commit) and then measures seven things per repository. A step whose entry file is missing is "not built" and names the package that builds it; a step that fails is red for that package; a fixture that does not build or a step that crashes is a defect of the drill, with its own exit code. Today every fixture stops at assess (ADP-2), which is the expected red. `drill.mjs --adopt` starts it in its own process, because the two modules import each other. The self-test was written first and failed 13 of 13 knockouts against an inspector that checked nothing; with the real one all 27 pass. Traces-to: E-03/F-02/S-01 (ADP-7) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A job of its own, adopt-drill, with the same repository condition as the drill so a project never inherits it live. Its first step runs the self-test, which must stay green; the second walks the route and is red on purpose until phase 5 of the recovery plan, so the job is not a required check. It becomes one when the walk is green. Until then the workflow shows a red cross that blocks no merge: gate and trace decide. The runbook explains how to read the report and its exit codes, and the changelog says what an adopter of this version gets. Traces-to: E-03/F-02/S-01 (ADP-7) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What both drills need moves into checks/drill-core.mjs: where the framework is, how git runs in a throwaway directory, how a fresh copy is unpacked, how the framework is told apart from a project, and begin's first commit. drill-adopt.mjs imports that instead of drill.mjs, so the import cycle is gone and `drill.mjs --adopt` calls the adoption walk directly: one flag parser and one exit path, where there was a child process and a second parser. The fixture module is renamed drill-adopt-fixture.mjs, so the drill family shares one prefix. No behaviour changes; the review lenses asked for this cut. Traces-to: E-03/F-02/S-01 (ADP-7) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The three review lenses found the drill's answers leaking into each other. Now each route step says whether its package has landed (a flag that package flips when it builds the step), and a step not built is reported and skipped instead of stopping the walk, so init and the overlay are walked as soon as they exist rather than only after assess. The flag and the tree are checked against each other in both directions. Exit codes are four: 0 green, 1 something built fails, 2 the drill is broken, 3 only steps not built yet stand in the way. Every step and check names the package that turns it green, reads of the route's output are guarded, so a broken baseline.json or a missing hook is red for its package, and a bad --ref is a defect, not red. The attributions follow the plan: the overlay is REL-1 and REL-4, init is AX-4a, the baseline ADP-3 with AX-4b. The checks bite harder. The governed commit must refuse an ungoverned one, the chained hooks are proven by a staged file the gate refuses, the owner's hook must run on the adoption commit itself, and the plan's B1 adds two checks: a committed assessment report that names where the secret was without repeating it, and a DEBT row per baselined gate. The suppression list is read from config.json's comment ban plus the forms it cannot see, so @ts-nocheck and pylint disables no longer slip through. The owner-action count waits for the commit instead of reading the drill's own table as a result, with a defer: marker on how it is counted. Tools under test run with the drill's git environment, and that environment now drops inherited GIT_* variables and points global and system config at the null device: started from inside another repo's hook, the drill used to commit its fixtures, planted key included, into that repo. The fixtures' ignored build output now holds a file a gate would fire on, which makes the plan's gitignored bin/, obj/ and .venv/ prove something: the gates walk the working tree today and would read them. Each fixture gets its own product directory, hooks resolve the way git resolves them, a failed copy removes its temp directory, and the self-test cleans up after itself; it grew from 27 to 40 tests, and four mutations of the code each turn one of them red. Traces-to: E-03/F-02/S-01 (ADP-7) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The adoption drill's self-test moves into the drill job, which is green unless something breaks, so a broken fixture no longer hides inside a job that is red by design. The adopt-drill job keeps only the walk. Its comment says what to do before it becomes a required check: drop the repository condition, because GitHub reports a job skipped by `if` as a success even for a required check (verified in GitHub's docs on job conditions, 2026-09-27). The runbook stops restating the route, checks and fixtures that the code owns, explains the report's five kinds of line and the four exit codes, and says it is the drill job's tick, not the commit's overall one, that carries the evidence. The changelog no longer claims a project inherits the drill switched off; what keeps its CI job off in a project is the repository condition, and the entry now says so. Traces-to: E-03/F-02/S-01 (ADP-7) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The owner's choice after the review, 2026-09-27. Until the route is built the adoption walk exits 3: only steps not built yet stand in the way, and its log lists each with the package that builds it. The walk step now passes on 3, so the adopt-drill job turns red only when something already built fails (1) or the drill itself breaks (2). A regression of a built step shows as a colour again, and the commit's overall tick stays readable. Checked under bash -e: exit 3 passes the step, exit 1 fails it. The runbook and the changelog say the same; the job stays non-required until the walk exits 0. Traces-to: E-03/F-02/S-01 (ADP-7), owner decision on the review blocker Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The second lens round on PR #93 found that e2117ff deleted the test that pinned "a check whose step was never reached says so instead of passing", and its message did not say so. With that guard switched off, the suite stayed at 40 of 40 while the walk reported suppressions, owner-ci, owner-actions and time as ok on a repository never adopted. The test is back in its current form: behind an unbuilt commit step, all nine checks are "not reached". Beside it, a check that crashes was untested: reading it as FAIL would turn exit 2 into exit 1 unseen. The exit 2 test now asserts it. Red first, in a scratch clone: with the guard replaced by `if (false)` the restored test fails, and with the crash branch removed the exit 2 test fails. Both pass on the drill as it stands; the suite is 41. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 blocker Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sentinel check read the owner's hook count when it ran, after the governed check, whose refused commit fires the owner's pre-commit hook again. So an adoption commit that left the owner's hook out of the chain, the case criterion B3 exists for, could still pass it. The commit step now records the count right after the adoption commit, and the check compares that with the count from just before it. Red first: a new test makes the adoption commit with the owner's hook switched off, then lets the governed check fire it. It failed before this change (the sentinel check passed) and passes now. The suite is 42. Found by the functional lens in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The route's comment, e2117ff's message and the card said each step's built flag is checked against the tree in both directions. That held only for steps with an entry: assess, overlay and init. The baseline step now names the file it already looked for, checks/baseline.json in the repository, so its flag is checked like the others, and its own existence check, which the entry check now always runs first, is gone. The hooks step keeps no entry, because its packages add no file of their own, and the comment says that its flag is the one nothing checks. A new test pins which steps not built lack an entry. Red first: it listed baseline and hooks before this change; it lists hooks now. The walk still exits 3, and baseline reports the file it waits for. Found by all three lenses in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
recordBefore stored the owner's hook directory, which only the hooks step read before e2117ff rewrote it to prove the chain by a refused probe. Nothing has read the field since, so it and its import go. The suite stays at 43. Found by the technical lens in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
drill.mjs imported the adoption walk at the top, so an export broken in drill-adopt.mjs stopped `node checks/drill.mjs` and drill.test.mjs too, while drill-core.mjs said neither drill imports the other's walk. The walk is now imported inside the --adopt branch, and the core's comment says what holds. Shown in a scratch clone with runAdoptDrill renamed: before this change drill.test.mjs failed to load (0 of 1, a SyntaxError on the missing export); after it, 11 of 11 pass. The adoption walk still exits 3. Found by the architecture lens in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The adoption drill counts @ts-expect-error and NOSONAR as inline suppressions because the comment ban in checks/config.json lacks them. That copy had no marker, so it would outlive the day the ban gains them. It now carries a defer: marker whose upgrade-when is that change. Found by the architecture lens in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Criterion 5 puts the self-test in the adopt-drill job. It moved into the drill job after the first review because the adoption job was red by design; since d817f55 that job passes on exit 3, so the reason is gone, and the comment calling the job red by design had become false. In the drill job, a failing adoption self-test also skipped the greenfield walk after it. The self-test is now adopt-drill's first step again, the stale comment is gone, and the runbook and the suite's header say where it runs. The workflow parses, with adopt-drill's steps in this order: checkout, setup-node, the self-test, the walk. Found by all three lenses in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The runbook's opening note said any project inherits the drill and its CI job dead. 26106e9 took the same claim out of the changelog because it is untrue for an adopted project, where a local run walks and goes red (parked in the intake). The note now says what holds: a fresh copy inherits both dead. Found by the architecture lens in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hold Round 3 of the lenses on PR #93 found three wordings the fix got wrong. c29ca51 wrote that a fresh copy inherits the drill dead, but a fresh copy is the snapshot before begin, where the baseline folder exists and the drill walks. The same fact stood three ways (the runbook twice, drill-core.mjs once). All three now say: begin deletes the baseline folder, so a project begun from scratch has nothing to walk; an existing project gets the folder back from begin (its own baseline record), and there a local run walks. Every project inherits the CI job dead. drill-core.mjs said a break in one walk cannot stop the other; that holds one way, a break in the adoption walk cannot stop the greenfield one. drill-adopt.mjs said the hooks packages add no file of their own; ADP-4 and AX-4b do add files, the chaining itself edits the owner's hook, and the comment and the pinning test's title now say that. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 3 minors Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since 77803a5 the baseline step names an entry in the repository, which init writes at run time. A baseline marked built whose file init never wrote was reported as "is gone from the repository, though the step is marked built", which reads as flag drift and invites flipping the flag back. The report now says the file "is not in" its place, for every place, beside the not-built report that says the same. The flag test also covers the repository as an entry's place, first used by 77803a5 and untested until now. Red first: the test failed on the old wording; in a scratch clone, dropping the repository from the places turns it red. The suite stays at 43. Found by the technical and functional lenses in round 3 on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 3 minors Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
drill-adopt.mjs promises exit 2 when the drill itself is broken, but a walk that failed to load or crashed outside its own handling made `drill.mjs --adopt` exit 1, the code for "something built fails". The import and the call now sit in a try/catch that prints DEFECT and exits 2. Shown in a scratch clone: with runAdoptDrill renamed, the walk exited 1 before this change and exits 2 after it, and a syntax error in drill-adopt.mjs exits 2 as well. The real walk still exits 3, and drill.test.mjs stays at 11. The gap predates the lens rounds; found by the functional lens in round 3 on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 3 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a3e6712 made the commit step record the owner's hook count right after the adoption commit, but only the negative case went through the real step: dropping that line, or setting it to the count from before, kept 43 of 43, and the sentinel check would then go red for ADP-4 on a working chain. A positive twin now makes an adoption commit through the real step with the owner's hook on, and the sentinel check passes. Red under both mutations the lens named, in a scratch clone: the line dropped, and the line set to the count from before. The suite is 44. Found by the technical lens in round 3 on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 3 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rding denied Round 4 of the lenses on PR #93 found the fact "when does the drill have nothing to walk" stated twice in the runbook beside the code's own comment, the copy c29ca51 had already shown can drift, and the top note said "the CI job" where both drill jobs carry the condition. The note now says both jobs are dead in every project and points to "Running it", which holds the rule once, with a long line re-wrapped. The wording c190f6f corrected was wrong on main, and AGENTS.md's conflict rule asks for the retired wording on the denylist. It is there now. Red first, in a scratch clone: the old sentence put back into the runbook fails the gate with a denylist finding; no current file matches. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 4 minors Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nned 5db229f pinned the commit step's count after the adoption commit, but not the one before it: every sentinel test started at a count of 0, so dropping the line that records it kept the suite green. In a real walk the hooks step's probe commit can fire the owner's hook before the adoption commit, and without that count a hook run from the probe would pass as one on the adoption commit. The negative twin now starts with one hook run in the sentinel, as the probe can leave it. Red first, in a scratch clone: with the line that records the count before dropped, the test fails; with it, the three sentinel tests pass. The suite stays at 44. Found by the technical lens in round 4 on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 4 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
c73b1cb made `drill.mjs --adopt` exit 2 when the adoption walk cannot load or crashes, but it was a fix without a regression test, against GLOBAL.md's rule, and no test ran the --adopt branch at all. A test now copies drill.mjs and drill-core.mjs into a temporary checks/ beside a drill-adopt.mjs that throws on load, runs --adopt, and expects exit 2 and the DEFECT line. Red first, in a scratch clone: with c29ca51's drill.mjs, before the try/catch, the test fails; with today's it passes. drill.test.mjs holds 12 tests now, so the runbook stops stating the count, which the file itself owns. Found by the technical and functional lenses in round 4 on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 4 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
The second lens round on PR #93 found that e2117ff deleted the test that pinned "a check whose step was never reached says so instead of passing", and its message did not say so. With that guard switched off, the suite stayed at 40 of 40 while the walk reported suppressions, owner-ci, owner-actions and time as ok on a repository never adopted. The test is back in its current form: behind an unbuilt commit step, all nine checks are "not reached". Beside it, a check that crashes was untested: reading it as FAIL would turn exit 2 into exit 1 unseen. The exit 2 test now asserts it. Red first, in a scratch clone: with the guard replaced by `if (false)` the restored test fails, and with the crash branch removed the exit 2 test fails. Both pass on the drill as it stands; the suite is 41. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 blocker Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
The sentinel check read the owner's hook count when it ran, after the governed check, whose refused commit fires the owner's pre-commit hook again. So an adoption commit that left the owner's hook out of the chain, the case criterion B3 exists for, could still pass it. The commit step now records the count right after the adoption commit, and the check compares that with the count from just before it. Red first: a new test makes the adoption commit with the owner's hook switched off, then lets the governed check fire it. It failed before this change (the sentinel check passed) and passes now. The suite is 42. Found by the functional lens in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
The route's comment, e2117ff's message and the card said each step's built flag is checked against the tree in both directions. That held only for steps with an entry: assess, overlay and init. The baseline step now names the file it already looked for, checks/baseline.json in the repository, so its flag is checked like the others, and its own existence check, which the entry check now always runs first, is gone. The hooks step keeps no entry, because its packages add no file of their own, and the comment says that its flag is the one nothing checks. A new test pins which steps not built lack an entry. Red first: it listed baseline and hooks before this change; it lists hooks now. The walk still exits 3, and baseline reports the file it waits for. Found by all three lenses in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
recordBefore stored the owner's hook directory, which only the hooks step read before e2117ff rewrote it to prove the chain by a refused probe. Nothing has read the field since, so it and its import go. The suite stays at 43. Found by the technical lens in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
drill.mjs imported the adoption walk at the top, so an export broken in drill-adopt.mjs stopped `node checks/drill.mjs` and drill.test.mjs too, while drill-core.mjs said neither drill imports the other's walk. The walk is now imported inside the --adopt branch, and the core's comment says what holds. Shown in a scratch clone with runAdoptDrill renamed: before this change drill.test.mjs failed to load (0 of 1, a SyntaxError on the missing export); after it, 11 of 11 pass. The adoption walk still exits 3. Found by the architecture lens in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
The adoption drill counts @ts-expect-error and NOSONAR as inline suppressions because the comment ban in checks/config.json lacks them. That copy had no marker, so it would outlive the day the ban gains them. It now carries a defer: marker whose upgrade-when is that change. Found by the architecture lens in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
Criterion 5 puts the self-test in the adopt-drill job. It moved into the drill job after the first review because the adoption job was red by design; since d817f55 that job passes on exit 3, so the reason is gone, and the comment calling the job red by design had become false. In the drill job, a failing adoption self-test also skipped the greenfield walk after it. The self-test is now adopt-drill's first step again, the stale comment is gone, and the runbook and the suite's header say where it runs. The workflow parses, with adopt-drill's steps in this order: checkout, setup-node, the self-test, the walk. Found by all three lenses in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
The runbook's opening note said any project inherits the drill and its CI job dead. 26106e9 took the same claim out of the changelog because it is untrue for an adopted project, where a local run walks and goes red (parked in the intake). The note now says what holds: a fresh copy inherits both dead. Found by the architecture lens in the second round on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 2 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
…hold Round 3 of the lenses on PR #93 found three wordings the fix got wrong. c29ca51 wrote that a fresh copy inherits the drill dead, but a fresh copy is the snapshot before begin, where the baseline folder exists and the drill walks. The same fact stood three ways (the runbook twice, drill-core.mjs once). All three now say: begin deletes the baseline folder, so a project begun from scratch has nothing to walk; an existing project gets the folder back from begin (its own baseline record), and there a local run walks. Every project inherits the CI job dead. drill-core.mjs said a break in one walk cannot stop the other; that holds one way, a break in the adoption walk cannot stop the greenfield one. drill-adopt.mjs said the hooks packages add no file of their own; ADP-4 and AX-4b do add files, the chaining itself edits the owner's hook, and the comment and the pinning test's title now say that. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 3 minors Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
Since 77803a5 the baseline step names an entry in the repository, which init writes at run time. A baseline marked built whose file init never wrote was reported as "is gone from the repository, though the step is marked built", which reads as flag drift and invites flipping the flag back. The report now says the file "is not in" its place, for every place, beside the not-built report that says the same. The flag test also covers the repository as an entry's place, first used by 77803a5 and untested until now. Red first: the test failed on the old wording; in a scratch clone, dropping the repository from the places turns it red. The suite stays at 43. Found by the technical and functional lenses in round 3 on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 3 minors Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
drill-adopt.mjs promises exit 2 when the drill itself is broken, but a walk that failed to load or crashed outside its own handling made `drill.mjs --adopt` exit 1, the code for "something built fails". The import and the call now sit in a try/catch that prints DEFECT and exits 2. Shown in a scratch clone: with runAdoptDrill renamed, the walk exited 1 before this change and exits 2 after it, and a syntax error in drill-adopt.mjs exits 2 as well. The real walk still exits 3, and drill.test.mjs stays at 11. The gap predates the lens rounds; found by the functional lens in round 3 on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 3 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
a3e6712 made the commit step record the owner's hook count right after the adoption commit, but only the negative case went through the real step: dropping that line, or setting it to the count from before, kept 43 of 43, and the sentinel check would then go red for ADP-4 on a working chain. A positive twin now makes an adoption commit through the real step with the owner's hook on, and the sentinel check passes. Red under both mutations the lens named, in a scratch clone: the line dropped, and the line set to the count from before. The suite is 44. Found by the technical lens in round 3 on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 3 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
…rding denied Round 4 of the lenses on PR #93 found the fact "when does the drill have nothing to walk" stated twice in the runbook beside the code's own comment, the copy c29ca51 had already shown can drift, and the top note said "the CI job" where both drill jobs carry the condition. The note now says both jobs are dead in every project and points to "Running it", which holds the rule once, with a long line re-wrapped. The wording c190f6f corrected was wrong on main, and AGENTS.md's conflict rule asks for the retired wording on the denylist. It is there now. Red first, in a scratch clone: the old sentence put back into the runbook fails the gate with a denylist finding; no current file matches. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 4 minors Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tradebaas
added a commit
that referenced
this pull request
Sep 28, 2026
…nned 5db229f pinned the commit step's count after the adoption commit, but not the one before it: every sentinel test started at a count of 0, so dropping the line that records it kept the suite green. In a real walk the hooks step's probe commit can fire the owner's hook before the adoption commit, and without that count a hook run from the probe would pass as one on the adoption commit. The negative twin now starts with one hook run in the sentinel, as the probe can leave it. Red first, in a scratch clone: with the line that records the count before dropped, the test fails; with it, the three sentinel tests pass. The suite stays at 44. Found by the technical lens in round 4 on PR #93. Traces-to: E-03/F-02/S-01 (ADP-7), lens round 4 minor Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed and why
Phase 0 of the recovery plan, package ADP-7 (story E-03/F-02/S-01): the finish line for adopting Groundwork into an existing repository, built before the route itself. Decision 0018 says the brownfield path is the one this repo cannot dogfood; this is how it gets dogfooded.
node checks/drill.mjs --adoptbuilds three small repositories by code (TypeScript with React, .NET, Python), each with a history, its own pre-commit hook,CLAUDE.mdandci.yml, a 600-line file, em dashes, gitignored build output holding a file a gate would fire on, and a secret committed once and removed. It then walks the route (assess, overlay, init, baseline, chained hooks, commit) and runs nine checks on the adopted repository: the plan's seven plus the assessment report and DEBT rows that criterion B1 names.adopt-drilljob runs the self-test and then the walk, and passes on 3 (the owner's choice after review), so it turns red only when something already built fails or the drill breaks.checks/drill-core.mjsholds what both drills share. Its git environment now drops inheritedGIT_*variables and points global config at the null device: started from inside another repository's hook, the drill used to commit its fixtures into that repository.drill.mjsloads the adoption walk only for--adopt, and a walk that cannot load or crashes exits 2, the drill's own defect.Commits:
c71c3aeandc7b01acare the first build,d1e3719the shared-core refactor,e2117ffand26106e9the first review's fixes,d817f55the owner's CI choice.b418c79toc29ca51,c190f6fto5db229fandf3be8a6tod2a1da2fix what lens rounds 2 to 4 found.Verified by
node checks/drill-adopt.test.mjs: 44/44,node checks/drill.test.mjs: 12/12. Written red first: 13 of 13 knocked-out fixture properties slipped past an inspector that checked nothing. Every later fix went red first or was shown in a scratch clone; each commit message says how.node checks/drill.mjs --adopt: exit 3, every fixture listing assess, overlay, init, baseline and hooks as not built with their packages.node checks/check.mjsgreen, all nineteen suites green,node checks/drill.mjs --require-walkpassed.d2a1da2green in every job (push run 36403255083, PR run 36403260758).bash -e: exits 0 and 3 pass the step, exits 1 and 2 fail it (re-checked by the functional lenses). GitHub's docs confirm a job skipped byifreports success even as a required check, which is noted inci.ymlfor the day this job becomes required.c7b01ac. Round 2 found that the four commits after it had gone unread and refused them on a blocker (a test deleted without mention); rounds 3 to 5 judged each fix in turn. All three approve the current patch,git patch-idd18359eafd86atd2a1da2. The verdicts and every finding are on the story card; two findings older than this PR are parked in the maintainer's intake.🤖 Generated with Claude Code