diff --git a/SKILL.md b/SKILL.md index 9631a68..efbb4cf 100644 --- a/SKILL.md +++ b/SKILL.md @@ -70,6 +70,32 @@ finished when Hands can go straight to the cut. pipeline. - Dispatch the Mind Steward before the first consequential action. +### 0b. Settle identity, lifecycle and authority before any cut is mapped + +Re-cutting is not usually caused by a map that was insufficiently detailed. It +is caused by a question that was answerable on day one and got asked on day +three. In the Eureka pipeline-state campaign every backtrack was one of three +questions, and none of them needed a line of source to answer: + +- **Identity.** The key grammar was redesigned after three patches because ids + had no namespace. Every earlier cut specified behaviour over an unnamed + space, so the same invariant kept reappearing one level up. +- **Lifecycle.** Cut 6d exists because the shape of each document was specified + and its life was not: a subject that is resolved, withdrawn, resolved again, + and transferred to another steward. Sequences had to be retrofitted into + keys that were already landed. +- **Authority.** The repo-owned store died whole in Cut 4 because who owns a + mind was never asked before the store was specified. + +So produce one table before mapping any cut, with a row per persistent kind and +three columns: what names it, what happens to it over time, and who decides. +**No cut is mapped while a cell is empty.** This costs a page and an hour. + +Assemble the operator's forks in the same pass, as one batch. In that campaign +they surfaced across five cuts instead, so rulings kept landing on code that was +already written. Discovering that the operator wants something different is not +waste; discovering it after the code lands is. + ### 1. Imagination maps the cut Brief an Imagination agent to produce the **cut map**: an ordered list of cuts @@ -79,13 +105,26 @@ against the current Body. Each cut carries: - **deletes first**, with exact paths and line counts; - keeps and moves; - adds; -- per-file changes with `file:line` against a named HEAD; +- per-file changes with `file:line` against a named HEAD, **for code that + exists**; - an **authority map** for anything that changes ownership: owner, inputs, outputs, derived state, forbidden writers, shared paths, deletion line; - **verification**: exact builds, tests with the rule each one pins, negative greps, and what only the operator can check; - a subtraction-ledger estimate. +**Spend the detail where the map can be wrong, not where Hands will rewrite it +anyway.** Anchors against existing code earn their length: they say what to +delete and what not to touch. Transcribing the body of code that does not exist +yet does not. A cut section that runs to eight hundred lines against a crate +nobody has written is a 1:1 map, and the only spec complete enough at that scale +is the code itself. Soul catches a wrong function body cheaply; it cannot catch +a missing namespace. So for new code, name the types, the rules that must die +under their own mutation, and the boundaries, then stop. + +Cutting faster means less prose per cut, never more code per cut. Small commits +stay small. + **Subtraction comes from a consumer audit of the public surface,** not from taste: diff --git a/references/briefs.md b/references/briefs.md index 86a0d9b..6721ba5 100644 --- a/references/briefs.md +++ b/references/briefs.md @@ -13,6 +13,32 @@ short form rather than pointing at a long document the agent may skim. --- +## Imagination: settle identity, lifecycle and authority + +Run this once, before any cut is mapped. It answers the questions that cause +re-cuts, and it needs almost no source. + +``` +You are Imagination for . Produce the model page in . Do not +map cuts, do not write code, do not commit; the root agent commits. + +Read and enough of the Body to enumerate the persistent kinds. + +Give one table, a row per persistent kind: +- Identity: what names it. Is the namespace stated? Is the name injective? Can + two different things collide? Is any part of it derived, and from what? +- Lifecycle: what happens to it over time. Created, revised, superseded, + withdrawn, reinstated, transferred, deleted, replayed. For each, what the + record looks like afterwards and what is now in force. +- Authority: who decides. One owner per decision. Name the forbidden writers. + +Then, in one batch, every question only the operator can answer, each with +options and a recommendation, and what depends on the answer. + +An empty cell is the finding. Say so plainly rather than inventing a plausible +value. Report the cells you could not fill and the source you checked. +``` + ## Imagination: map or refresh a cut ``` diff --git a/references/changelog.md b/references/changelog.md index aac512c..9e892f0 100644 --- a/references/changelog.md +++ b/references/changelog.md @@ -2,6 +2,48 @@ Record each change to the skill together with the evidence that motivated it. +## 2026-09-16: front-load the invariant layer, thin the spelling layer + +Evidence: the operator's read of the Eureka pipeline-state campaign, that the +design kept being discovered as the work went, producing re-cutting and +repeated Imagination passes with no good reason for the map to diverge that +far. The campaign's own record agrees, and says which layer was at fault. +Every backtrack was identity, lifecycle or authority, and every one was +answerable before a line of source was read: + +- The repo-owned store was specified before anyone asked who owns a mind, and + died whole in Cut 4: 1,302 lines deleted. +- The key grammar was patched twice and redesigned on the third occurrence, + because ids had no namespace to be specified over. +- Cut 6d retrofitted sequences into landed keys, because each document's shape + was specified and its life was not. +- The operator's forks surfaced across five cuts, so rulings kept landing on + code that was already written. Two of them reversed defaults the agents had + already implemented. + +None of that was a shortfall of `file:line` detail. The maps had plenty: +Cut 10's section ran to roughly eight hundred lines against a crate that did +not exist. The operator named the trap for what it is, a 1:1 map, where the +only sufficient spec is the code. + +- **Added step 0b.** A model table before any cut is mapped, a row per + persistent kind, three columns: what names it, what happens to it over time, + who decides. No cut is mapped while a cell is empty. Operator forks are + assembled in the same pass as one batch. +- **Added the model-page brief** to `briefs.md`, before the cut-mapping brief. + An empty cell is the finding; inventing a plausible value is the failure. +- **Qualified the per-file anchors.** They are required for code that exists, + where they say what to delete and what not to touch. For code that does not + exist, name the types, the boundaries and the rules that must die under their + own mutation, then stop. +- **Stated what cutting faster means:** less prose per cut, never more code per + cut. Small commits stay small. + +Not treated as waste: the operator changing their mind. Learning that the +intent differs is the job. It is only expensive when it is learned after the +code lands, which is an argument for surfacing forks earlier rather than for +mapping deeper. + ## 2026-09-16: the loop was burning tokens on gaps, not defects Evidence: one day of the Eureka pipeline-state and TypeScript QUIC campaigns,