Fix: route Engine development to its runbook from the mechanic - #1047
Merged
Conversation
Claim commit for the Build. Closes #1046. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Name the valid entry lanes in the development runbook, ground the owned-product build in a product's own development runbook read at its merged base, and make the engine-develop-engine route reachable from a mechanic instead of declining outright. The trust model, all seven steps, Done when, and the development invariants are byte-identical, proved by two region digests against base b6c6c2e. Closes #1046. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ility Security-governance found the authority predicate failed OPEN: repo_identity.is_home_repo returns True for any product carrying no engine manifest, so a file planted at the runbook path in an arbitrary owned product would have been read as governing this session's trust model and gates. Reproduced against a throwaway repo. Replaced with a positive slug_eq match on the verified product slug against the recorded home_repository, which fails closed, and recorded the trap inline. Usability found the spanning case buried in another bullet, where a both-repositories ask fell through to the refusal branch; it now has its own bullet. The lane-cannot-be-established path asked for a bare refusal with no way forward; it now names what to ask the operator. Restored the pronoun antecedent ahead of the byte-frozen trust model, and stated that the two runbooks are different axes rather than two copies of one sequence. Spec-conformance found the recorded-sha rationale missing; added. Both region digests still match base b6c6c2e. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Scoped repair re-review nit: the step said 'the engine's recorded home_repository' without saying which manifest that comes from. It is the mechanic's own, never a value read from the product being built — which matters, since the product is the untrusted side of this comparison. Co-Authored-By: Claude Fable 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.
Closes #1046
Purpose
Make the Engine's own development governance reachable from the workshop where Engine development actually starts.
The runbook at
.engine/operations/engine-development.mdcarries the trust model (a non-engineer sole gate-holder who cannot read code, so review is informed consent on evidence rather than code review), the twelve development invariants, and the three frozen check names. It was written as though the only way to work on the Engine were to sit in its home repository. Engine development now normally starts from an engine-mechanic deployment, which cuts an isolated worktree of the home repository and delivers one direct pull request. Every such worktree already contains that runbook — but no operation told a session to read it there, and theengine-develop-engineroute declined outright anywhere but the home repository, so on a mechanic it matched the operator's intent and then dead-ended. Filed as #1046.Impact: The disciplines that govern how the Engine is changed are now reachable from the path used to change it, instead of sitting behind a route that refused.
Scope
Routing prose across three surfaces, plus the two generated indexes that derive from them.
.engine/operations/engine-development.md— the Purpose section becomes a lane block placed below the byte-frozen trust model; the frontmatter title drops its home-repo binding; step 1 gains a lane-confirmation clause that keeps the original step-1 text verbatim as its suffix..engine/operations/owned-product-build.md— one inserted step, fail-closed: verify the base withrev-parse --verifyand refuse if it does not resolve, probe presence withls-treeacross three stated outcomes, read at the resolved commit, and grant governing authority only on a positiverepo_identity.slug_eqmatch..claude/skills/engine-develop-engine/SKILL.md— a lane-neutral description (the trigger text a model matches on), a five-branch body, and a second declaredengine-targetforowned-product-build.md; the Codex twin is regenerated from it..engine/knowledge/graph.jsonand.engine/self-map.md— regenerated, never hand-edited.Change profile — the shape of this pull request at a glance:
Part of #Nline below says it is one slice of a larger effort.This is a description, not a gate — it never blocks a merge. It is here so you can weigh the change by what it touches, not by its line count.
Impact: No code, schema, check, CLI, or manifest field changes; the change is prose plus the indexes that mirror it.
Behaviors
The capabilities this change delivers, each with the test that exercises it.
Two region digests recomputable from git against baseb6c6c2e:sed -n '/^It rests on the **trust model/,/protected-branch merge.$/p' FILE | shasum -a 256yieldsd8329b2d…, andawk '/^## Steps$/{s=1} s && /^2. /{f=1} f' FILE | shasum -a 256yieldsdf8ba629…, identical at base and at head., ``tools.test_build_coordinator_preservation— BO-06's prose anchor 'Codex adapter surfaces' still resolves in its owner file.owned-product-build.mdsurvive the inserted step and the renumbering, including the line break that keeps 'mechanic_build.py worktree' intact. — ``tools.test_build_coordinator— the owned-product phrase-pin assertions at its historical-scenario corpus.tools/self_map.py check` — the Automatic-routes row for `engine-develop-engine` now renders both targets.`,tools/codex_gen.py check— the regenerated Codex twin matches its canonical source.Out of scope
Three things this deliberately does not do, each for a stated reason rather than as deferred work.
boot.pyis untouched, including the mechanic overlay. — The mechanic-only surface was the natural home for this routing and is foreclosed by its Tier-0 budget: the render is 834 characters against a 900 cap, roughly 66 characters of headroom, with its clauses test-pinned including their rationale phrases. The consequence is recorded rather than hidden — in the mechanic lane nothing at session start names this runbook; the owned-product build step is what reaches it. (deferred by Operator decision after being shown the measured headroom.)Impact: The lifecycle, the published route availability, and the boot output are all unchanged, so nothing here alters what an existing deployment receives until it upgrades.
Risk
4 risks, ranked, each with the bound that contains it.
.github/workflows/and.engine/check/, so even deleting this file would produce no finding (the most safety-sensitive edit). Two region digests recomputable from git against a recorded base sha, covering the trust model and everything from step 2 to end of file; the complete before/after diff in this body; and an enumerated discipline inventory handed to two cold reviewers as their checklist. The Purpose framing sentences are the residual the digests do not cover, and are named as lens-only.repo_identity.slug_eqmatch between the verified product slug and thehome_repositoryrecorded in the mechanic's own manifest — never a value read from the product.slug_eqreturns false on any unreadable or mismatched value. The step also records whyis_home_repomust not be used here.mechanic_build.py..engine/uv.lockis absent from the diff. That is not reassurance: it is the reason this body carries digests and a full diff, because the file defining the merge gate produces no automatic signal when it changes.Impact: The most safety-sensitive edit is the authority test in the owned-product step; it was wrong in an earlier revision of this branch and is now fail-closed.
Validation
Green on the final commit: 6,399 tests, the CI suite, both regenerated indexes in sync, and the Codex twin in parity.
a0d45ced3b5f(log sha256:4b0d74567e33e3d14a2273f53862143206f1f5effcd9ea4f5851528575f299a5)a0d45ced3b5f(log sha256:6583ae3c531fc9b0f5fd69df58dcf30489c6ea4fa985a725be73853872078195)guardrail-weakeningcheck cannot pass locally — it fails closed without a pull-request context. It is reported here as not-locally-verified, never as green; it enforces in CI.dependency-review,pr-body-completeness,product-lock-integrity,protection). They enforce when this is proposed for merge.Impact: Mechanical green covers the frozen regions, the pinned phrases, and the indexes; it cannot judge whether the routing prose is right, which is what the reviews and the demonstration are for.
Review
Three plan rounds and one deliverable round across four cold lenses each, plus a scoped re-review of the repaired seam; five blocking findings, all fixed before submission.
git showread the index and return the mutable copy with exit 0 and no stderr).is_home_reporeturns true for any product carrying no engine manifest, so a planted file would have governed. Reproduced against a throwaway repo, then replaced with a fail-closed positive match. Usability found the spanning case buried where a session would fall through to refusal, and a refusal with no next action.PG-1. The one-line description on this route is what decides whether it is offered at all, and it said the work happens in the home repository — so from the mechanic the route would likely never have been picked up. Fixed before any code was written.PG-2. The plan would have had a session read the rules it works under from the same copy it was editing. It now reads the settled version instead. Fixed before any code was written.PG-3. The first attempt at that fix had a hole: if one value was missing the command quietly returned the edited copy anyway. I reproduced it, then made it check first and stop if it cannot. Fixed before any code was written.PG-4. A draft listed which steps of the runbook apply and accidentally left out the step requiring plan review. All steps now apply. Fixed before any code was written.PG-5. The lane test looked at how the repository is configured rather than at where the change lands, which would have sent your workshop-local work into an engine-template worktree.PG-6. I had overstated what was unreachable. Two of the four things I named already reach the mechanic; the corrected, narrower gap is what this change closes.PG-7. I first reported the absence of automatic guarding as reassurance. It is the opposite, and this body now says so plainly.PG-8. My own revision dropped the protection on the trust-model paragraph. There are now two digests, and the first one pins exactly that paragraph.PG-9. Where the route sends a session was left in prose, so the generated maps would have been silently wrong about it. It is now declared as data.PG-10. I had said this takes effect when you merge it. That was wrong: your workshop runs its own installed copy, so it arrives only after a release and an upgrade.PG-11. The routing rule was written into a file that does not exist in deployed copies, where the refusal branch could never be read. The rule now lives in the route.PG-12. The decision about whether another repository's document may set your rules had no actual test behind it. It now has one.DG-1. A reviewer found a real hole. The test I used to decide whether another repository's document may redefine your rules is built to answer yes when it cannot tell — safe for its original job, exactly wrong for this one. I reproduced it, then switched to a test that demands a positive match and refuses otherwise.DG-2. A request touching both repositories fell through to the refusal branch instead of being handled. It now has its own branch.DG-3. Two seven-step lists had to be reconciled by guesswork; the runbook now says they are different axes, not two copies of one sequence.DG-4. The can't-tell-which-lane path told a session to refuse with no way forward. It now names the files and asks you which repository they are in.DG-5. My rewrite weakened a pronoun just above the frozen trust model; fixed from the line above, since the paragraph itself could not be touched.DG-6. The step said to record the base commit but not why it matters; the reason is now stated.PG-1: The one-line description on this route is what decides whether it is offered at all. It said the work happens in the Engine's home repository, so from the mechanic the route would likely never have been picked up - the fix would have looked right and done nothing. The line now names both places. Fixed before any code was written.PG-2: The plan would have had a session read the rules it works under from the same copy it was editing - so a change to those rules would have started governing the very change that made it. It now reads the settled version instead, and says so in words. Fixed before any code was written.PG-3: The first attempt at that fix had a hole: if one value was missing, the command quietly handed back the edited copy anyway, with no error. I reproduced it to be sure. It now checks that value first and stops if it cannot, rather than carrying on. Fixed before any code was written.PG-4: A draft of the plan listed which steps of the runbook apply, and the list accidentally left out the step that requires plan review. A session reading it could have concluded it was allowed to skip that review. All steps now apply. Fixed before any code was written.PG-10: I had said this fix takes effect once you merge it. That was wrong. Your workshop repo runs its own installed copy of these files, so the change reaches it only after a release is cut and the workshop is upgraded to it. The plan and the checks you would run now say so plainly, so you are not expecting a change that has not arrived yet.DG-1: A reviewer found a real hole in my work, and it was the serious kind. The step I wrote decides whether a document found in another repository may redefine the rules your Engine works under. I reused an existing test for that, but that test is deliberately built to answer yes when it cannot tell - safe for its original job, exactly wrong for this one. So a file placed at the right path in almost any product repo would have been obeyed. I reproduced it to be certain, then switched to a test that demands a positive match and refuses otherwise. Fixed before this reached you.bf8a09ec0930, submitteda0d45ced3b5f— 5 files changed, 28 insertions(+), 15 deletions(-)Spec-derived acceptance steps
There is no settled spec criterion governing how a session ENTERS the Engine-development runbook or the lane routing this Build adds, so the plan's own success obligations govern conformance review. The nearest settled criterion — that the engine-mechanic is non-reflexive and delivers a direct pull request into its owned product — is unaffected in its own terms (this Build changes neither the delivery route nor the executable upgrade rule) and is extended in spirit: the plan gate found that reading GOVERNANCE PROSE from an unmerged branch is a reflexivity the record never covered, and this Build closes it by grounding at the merged base. Reconciling the mechanic-side corpus is separately tracked and, by standing decision, is not gated on this Build.
Impact: Five blocking findings were found and fixed before this reached you; the two most serious — a reflexive read of the governance text, and an authority test that failed open — were both defects I introduced and neither would have been caught by any automatic check.
Demonstration
A step you can run yourself that drives the changed surface and can genuinely fail.
In engine-mechanic, after this merges AND a release is cut AND the mechanic is upgraded to it, start a fresh session and say: "Let's work on the Engine's own machinery." Then, in a second fresh session, say: "Update the spec corpus for platform currency."owned-product-build.md, cuts an isolated worktree, and quotes the trust model or a named invariant read at the worktree's base before it plans. The second session treats the work as an ordinary Build in engine-mechanic and does not cut an engine-template worktree.Impact: Run it to watch the change work — an unrun step is a promise, not proof.
Files of interest
The paths that most determine this change.
.engine/operations/owned-product-build.md— Carries the whole safety argument: the fail-closed base resolution, the three-outcome presence probe, and the positive-match authority test that decides whether another repository's document may redefine this session's gates..claude/skills/engine-develop-engine/SKILL.md— The authored home of the lane discriminator, and the only surface present in every deployment — so the refusal branch that protects adopters can only live here..engine/operations/engine-development.md— The governance itself. Read the Purpose diff closely; everything from the trust model down is digest-pinned and unchanged.Impact: Two of the three are prose a session follows; the third is the rulebook the merge gate rests on.
AI involvement
How this change was produced and who decided what.
Impact: Design judgment carries this change; the mechanical evidence bounds only what did not change.
Release-Impact: patch — backward-compatible correction or change to an existing feature