diff --git a/.claude/README.md b/.claude/README.md index f16b63d..19df9b1 100644 --- a/.claude/README.md +++ b/.claude/README.md @@ -16,7 +16,9 @@ workflows, and agents resolve together and `uv run loom` hits this checkout. │ ├── deep-research/ # /deep-research TOPIC — single-question autonomous research │ ├── hyper-research/ # /hyper-research DOC — parallel multi-question meta-research │ ├── map-codebase/ # /map-codebase PATH — explained architecture map of a repo -│ └── loom-expedition/ # /loom-expedition GRAPH — standalone emergent-theory expedition +│ ├── loom-expedition/ # /loom-expedition GRAPH — standalone emergent-theory expedition +│ └── create-loom-gauntlet/ # /create-loom-gauntlet TASK — builder-vs-critic orchestration +│ # prompt; brownfield (mapped repo) or greenfield (new product) ├── workflows/ │ ├── deep-research.js # deterministic orchestration: orient → quality-gated loop → finalize │ ├── hyper-research.js # comprehend → extract questions → parallel deep-research → synthesize diff --git a/.claude/skills/create-loom-gauntlet/SKILL.md b/.claude/skills/create-loom-gauntlet/SKILL.md new file mode 100644 index 0000000..596724e --- /dev/null +++ b/.claude/skills/create-loom-gauntlet/SKILL.md @@ -0,0 +1,216 @@ +--- +name: create-loom-gauntlet +description: Use when the user invokes /create-loom-gauntlet [task], or wants a gauntlet loop, builder-vs-critic orchestration prompt, or autonomous iterate-until-perfect loop — in a repo already mapped by /map-codebase (docs/architecture/map-manifest.json exists), or in a blank/scaffold-only repo where a new product is being built greenfield. Requires The Loom CLI and its FalkorDB store. For an unmapped repo with existing code, run /map-codebase first. +argument-hint: "[task]" +--- + +# Create Loom Gauntlet + +## Overview + +A gauntlet loop (Matt Shumer's pattern) is an orchestration prompt in which builder sub-agents produce artifacts and fresh-context critic sub-agents blind-compare them against a concrete reference, looping on the largest gap until the bar is met or a boundary fires. This skill generates that prompt for repos on the Loom substrate, in one of two modes: + +- **Brownfield** — the repo carries a `/map-codebase` graph. The map replaces grep recon with graph queries, makes part-independence *verified* instead of asserted, arms critics with deterministic budgeted evidence tools, and persists loop state in a Loom ledger so the spin rule and cross-part invalidation are mechanical queries, not the lead agent's recollection. +- **Greenfield** — the repo is blank (or scaffolding only) and the deliverable is a new product. There is nothing to map yet, so independence is established *by construction*: a part 0 freezes the interfaces and writes the acceptance suite before any parallel builder starts, and the run bootstraps its own map with `/map-codebase` once part 0 lands — converging to the brownfield machinery for every later phase. The map describes what is; a new product is what will be — so greenfield builds the "what is" first, then holds it to the same standard. + +The skill is also **capability-aware**: it probes which substrate features the installed Loom has (workspaces, write-receipts, worlds, calibration) and generates the upgraded mechanism where available, the legacy fallback where not. + +Three core principles: + +1. **A gauntlet prompt is a loop with a finish line, not a task list.** If the objective isn't falsifiable or the critics aren't independent, you've written a long prompt, not a gauntlet. +2. **A graph fact beats a grepped fact, but a run command beats both.** The map's structural layer (calls, imports, containment) is deterministic ground truth *about the mapped commit*. Its semantic layer (`claim`/`pattern`/`tension` entities) is LLM-written — leads to verify at their `file:line` anchor, never facts that settle a verdict. Real command output outranks everything. In greenfield this binds from bootstrap onward; before the first map exists, only command output and real diffs count. +3. **A mechanism beats a policy.** A boundary that matters is enforced by something that cannot be talked past — a pre-flight backup, a scoped credential, a watchdog check, a frozen interface contract — with the prompt text as the second line of defense, never the only one. (Learned the hard way: a prompt-only "never touch other graphs" boundary did not stop a sub-agent's `flushall()` cleanup impulse from destroying an entire production store.) + +## Dependency gate — run BEFORE anything else + +Never generate on a guess. In order: + +1. **Store is reachable:** `loom graph-stats` reaches the store — a typed `NOT_FOUND` for a missing default graph still proves reachability; only a connection failure means the store is down. If `loom` isn't on PATH (a blank repo has no venv carrying it), use `uv run --directory loom ...`; if FalkorDB is down, `docker compose up -d falkordb` in the Loom checkout. Unreachable and can't be started → **stop**: both modes need the store — the ledger lives in it. Tell the user what to start, then re-invoke. +2. **Determine the mode** from two observables, and record both in GRAPH FACTS: + - **Map substance:** `docs/architecture/map-manifest.json` exists in the target repo AND `loom graph-stats '{"graph": ""}'` reports `entityCount > 0`. A manifest over an empty graph is NOT a map — treat it as absent. + - **Extractable source:** `git ls-files -- '*.py' '*.ts' '*.tsx' '*.js' '*.go' '*.rs'` (the languages `/map-codebase` extracts) returns files beyond generated scaffolding. + Substance yes → **brownfield**. Substance no + source no → **greenfield**. Substance no + source yes → the repo needs mapping first: map it yourself — announced, not put to a vote; say first that a from-scratch map is tens of minutes and can run to millions of tokens — then run `/map-codebase PATH`, continue in brownfield once it lands, and record it in GRAPH FACTS. This is the gate's default action and it never waits for an answer: a human who is present can interrupt it; an absent one has nothing to decline. **Stop** only if the map fails, or a cost cap the user has already stated (in the invocation, CLAUDE.md, or standing config) forbids that spend — never generate against unmapped existing code; the prompt's contracts would be guesses. (Named-workflow resolution is project-scoped: from any repo other than the Loom checkout, invoke the pipeline as `Workflow({scriptPath: "/.claude/workflows/map-codebase.js", args: {path: ""}})` — record the form that worked.) + A **hybrid** task (a new subsystem inside a mapped repo) runs brownfield and additionally carries the greenfield part-0 obligation for the new subsystem: its internal interfaces are frozen by construction, while its contact points with mapped code are verified by blast-radius like any other part. +3. **Brownfield only — manifest is current:** read `graphName` and `commit` from the manifest; compare `commit` to `git rev-parse HEAD`. If they differ, scope the staleness to the task: `git diff --name-only ..HEAD`. If none of the changed files fall inside the modules the task touches, the map is current *for this task* — proceed, and record the drift in GRAPH FACTS. Otherwise refresh it yourself before recon — same default action as step 2, announced and never waiting for an answer: run `/map-codebase PATH` (incremental — minutes, not the full run) and record the refresh in GRAPH FACTS. **Stop** only if the re-map fails or cannot run — a stale map over the touched modules produces confidently wrong contracts. +4. **Brownfield only — read `docs/architecture/QUERYING.md`** in the target repo — it carries the graph's entity-naming conventions (`file:`, ` ()`, ` purpose`) that every query below needs. (Greenfield: this file doesn't exist yet; the bootstrap writes it, and the generated prompt directs the lead to read it then.) +5. **Probe substrate capabilities** — the generated prompt's machinery depends on which Loom this is. Run `loom begin-session --schema`, `loom what-changed --schema`, `loom resolve-claim --schema`, `loom fork-world --schema`. Each success unlocks the upgraded mechanism (session workspaces, receipt audits, calibrated ledger, world-isolated rehearsals); each failure selects the legacy fallback (prefix discipline, critic re-rehearsal, plain outcome records, scratch graphs). Record the probe results — GRAPH FACTS has a slot for them, and the template's capability-gated blocks are included or replaced accordingly. + +## Process + +1. **Task** = the argument passed to this skill. If absent, ask the user — everything below derives from it. +2. **Recon.** Conventions and verification commands come from CLAUDE.md / README where they exist (cite the files). + - *Brownfield:* graph recon replaces grep recon. For every area the task touches, run and keep the output of: + - `loom explore '{"name": "", "graph": ""}'` — definition, callers, callees, semantic layer, in one budgeted call + - `loom blast-radius '{"name": "", "graph": ""}'` — reverse-dependency reach, grouped by module: the contracts that must not break + - `loom list-entities '{"entityType": "tension", "compact": true, "graph": ""}'` — the repo's recorded risks; keep the ones anchored in touched modules + - the invariant `claim` entities `explore` returns for touched modules — candidate contracts for critics to re-verify + - If the task reaches you as an adjective ("faster", "more robust", "best possible"), derive its number here — from the tensions and invariant claims just listed, the touched modules' failing or absent commands, and any prior integration findings — and state the derivation in DELIVERABLE so no builder re-litigates it. If nothing derivable exists, stop and say so; greenfield's "go back to the user" (step 3) is not this path. + - *Greenfield:* there is no graph and possibly no files — recon is the **product brief**. Extract from the user or the document they point to: the product's observable behaviors, the measurable properties behind every quality adjective ("fast" gains a number before generation), the stack (settle it with the user now if unstated — never inside the prompt), and any named external exemplar. Every claim in the generated prompt still needs a source: the brief, a named exemplar, or a decision recorded in DELIVERABLE — never an adjective. +3. **Pick the reference.** + - *Brownfield:* by query, not familiarity. Query `pattern` entities for modules implementing the pattern the task needs; rank candidates by caller count (`find-callers`) — the primary usage metric. A zero-callers result is inconclusive (call-edge extraction can miss import shapes), never proof a symbol is unused: corroborate — never substitute — with `explore`'s `importedBy` count or a direct read, recording which signal was used and the extraction gap in GRAPH FACTS. A pattern entity's instance list only qualifies a module as a candidate; it never justifies the winner. Prefer exemplars with **zero attached tensions**; when the only domain-correct exemplar carries tensions, assess each tension's relevance to the task and put that assessment in REFERENCE instead of disqualifying the exemplar. The generated prompt must state *why* the exemplar won ("implements X, N callers, no recorded tensions"). If the deliverable is prose/research rather than code and a Loom research graph exists for the topic, that graph is the reference: critics check claim coverage, `contested-claims`, and `needs-evidence` against it. + - *Greenfield:* the reference is **layered**: the product brief (with its measurable properties) is part 0's reference; the acceptance suite and frozen interfaces that part 0 produces are the reference for every later part. A named external exemplar (a repo, a spec with numbers) is recorded as part 0's design input. If nothing measurable can be extracted from the brief, go back to the user — never generate against adjectives. +4. **Decompose and establish independence.** + - *Brownfield:* 3–7 parts; for each, record its touched modules and blast-radius module set. Disjoint sets → the parts may run in parallel (isolated worktrees). Overlapping sets → re-partition, or serialize those parts and record the shared edges as **named seams** for the integration pass. Independence is a query result in the prompt, never an assertion, and a fully serialized chain is a valid verified outcome for a small, vertically integrated task — never fabricate parallel boundaries to look more gauntlet-like. + - *Greenfield:* **part 0 plus 2–6 product parts, part 0 serialized first, always.** Part 0 delivers three things, and its pass criterion names all three: (a) the **interface contract** — types, module boundaries, API shapes — between exactly the parts that will run in parallel (a fully serialized plan shrinks this to nothing; never fabricate parallel boundaries); (b) the **acceptance suite** encoding the brief's measurable properties; (c) a **working toolchain** — by part 0's exit, ``, ``, and `` exist and run clean on the skeleton, because every later pass criterion names them. Later parts are independent **by construction**: each owns modules disjoint under the frozen interfaces, and the interfaces are the named seams. Construction is then *verified*: the first post-bootstrap integration pass runs `blast-radius` on the real map to confirm the constructed disjointness — a violation is a routine integration round whose fix lands in the interface contract. +5. **Classify each part's acceptance shape and prescribe its round-1 artifact.** Cost concentrates where the *criterion* is hard, not where the code is big — a tiny-blast-radius part with a generalization-shaped criterion can burn five rounds while high-centrality parts pass in one. Four shapes; each adds a mandatory element to the builder's FIRST dispatch: + - **Generalization-shaped** ("works on inputs nobody enumerated" — matchers, thresholds, classifiers, heuristics): the builder ships a self-adversarial harness from round 1 — it must invent fresh held-out cases each round, contamination-checked against every corpus and committed test in the repo, and is told explicitly that its known-case results are not evidence. Loop rule for these parts: *the same criterion failing on fresh cases in two consecutive rounds means the mechanism class is wrong — mandatory design change, not another patch.* + - **Enumeration-shaped** ("all X must Y" — overrides of a surface, adapters over an interface, migrations of a set): round 1 must deliver the closed-set classification table (every member of X × its treatment × why safe), and the critic independently *regenerates* the table rather than probing members. Members of X are never discovered one-per-round. (Greenfield's part 0 is enumeration-shaped: the interface table and the brief-property → acceptance-test coverage table are its closed sets.) + - **Measurement-shaped** ("this value is measured, not assumed"): round 1 carries the perturbation obligation — the number must move when its input moves, demonstrated once by the builder and re-verified by the critic. If producing the number touches any paid or metered external resource — regardless of amount — round 1 additionally carries a machinery-and-precondition gate: perturbation demonstrated on a synthetic or mocked stand-in, plus a live re-check that each arm's preconditions still hold, both critic-verified BEFORE any real spend is authorized; the real spend then happens once. + - **Composition-shaped** (consumes or is consumed by another part's feature): covered structurally by named seams; additionally enrolls the pair in the integration pass's behavioral probes (step below). +6. **Assign models by measured complexity** — a stated, repeatable rule, not vibes: parts touching leaf modules with small blast radii and no tensions → haiku builders; typical parts → sonnet; parts touching high-centrality modules, recorded tensions, or generalization-shaped criteria → sonnet builders with opus critics. Greenfield's part 0 always gets an opus critic — interface design is judgment, and a wrong freeze taxes every later part. If every part lands in the same tier under the rule, state the shared justification — don't manufacture differentiation. **Prescribe models only** — the dispatch mechanism honors model choice but not effort levels; if a part deserves extra deliberation, say so in the dispatch prose ("reason longest about X"), not as an unactionable `/high` suffix. **Opus is the hard ceiling: no sub-agent ever runs on Fable/Mythos, regardless of the session's default model — pass the model explicitly on every dispatch.** +7. **Resolve permissions up front** — the generated prompt runs with no human available. Gated actions (deploy, push, migrations, spending) are settled with the user BEFORE generation or written as hard-forbidden. If the task can't succeed without one, stop and ask now — never inside the prompt. +8. **Fill the template.** Every `` becomes repo-specific content; every graph fact comes from a query you actually ran this session; every mode fork resolves to exactly one variant (the generated prompt states its mode once, in GRAPH FACTS, and contains no dangling alternative). Fill command slots with what actually exists (e.g., `build` absorbing typecheck when no lint script exists), stated as such — never invent a command; in greenfield the command slots cite part 0's toolchain obligation instead. When the task's literal wording conflicts with a verified invariant claim, resolve in favor of the invariant, state the decision in DELIVERABLE so no builder re-litigates it, and surface it to the user at delivery. If a section would paste cleanly into another repo, your recon was insufficient — go back to step 2. +9. **Lint the output, then deliver.** Before delivering: (a) re-read the generated prompt end to end for corrupted, interleaved, or truncated lines — a garbled boundary or pass-criterion mis-executes silently; (b) verify every PARTS pass-criterion that quotes the spec resolves verbatim against the spec text; (c) confirm every capability-gated block matches the gate-step-5 probe results; (d) confirm the mode is stated in GRAPH FACTS and no other-mode block survives (greenfield prompts carry the bootstrap step; brownfield prompts carry no part-0 machinery unless the task is hybrid). Then deliver the finished prompt in one fenced markdown block as your final output, preceded by one line noting it must run in an agentic environment that can spawn sub-agents and reach the Loom CLI, and offer to kick it off now. + +## Template + +```markdown +# GAUNTLET: + +Run this as an orchestrated loop with sub-agents. You are the lead agent: you dispatch builders and critics; you never judge your own work. + +## DELIVERABLE + + +## OBJECTIVE — falsifiable +` exits 0 including N new tests covering X; `` clean". Never "improve" or "high quality". Greenfield: the named commands are the ones part 0 must establish — the objective cites them as part 0 obligations, not as pre-existing facts.> + +## REFERENCE — what great looks like, and why it was chosen +, callers, zero recorded tensions". Critics compare output against THIS, side by side, blind where the medium allows.> + + +## REPO FACTS +- Stack & conventions: +- Verify with: `` · `` · `` +- Contracts that must not break: + +## GRAPH FACTS +- Mode: — decided at generation from map substance (`entityCount` = ) and extractable source ( files). +- Codebase graph: `` · describes commit `` · query recipes: `docs/architecture/QUERYING.md` +- No codebase map exists at run start. Reserved map graph name: `codebase-`. **Bootstrap step:** when part 0 passes its comprehensive critic, run `/map-codebase ` — stating the invocation form verified at generation (named-workflow resolution is project-scoped; from a foreign repo use `Workflow({scriptPath: "/.claude/workflows/map-codebase.js", ...})`); then read the generated `docs/architecture/QUERYING.md`, and from that point every brownfield rule in this prompt binds — graph recon for later parts, blast-radius verification of the constructed independence, the critics' graph toolkit. Re-map (incremental) at each phase boundary, before the integration pass. **If `/map-codebase` is unavailable in the run environment or fails, continue without the map — grep recon and full-suite verification; independence remains by-construction; record the gap in the final report. Bootstrap is an upgrade, never a blocker.** +- Substrate capabilities (probed at generation): +- `; drift verified disjoint from this task's modules (`git diff --name-only` showed no overlap)" | if the gate mapped the repo: "map at generation over `` — manifest now ``, and the `entityCount` above is post-map" — omit if neither> +- +- Transport: `loom ''` . Always pass the JSON payload as one single-quoted shell argument — unquoted `[`/`{` are glob-expanded by zsh before loom ever sees them, producing a shell error that masquerades as a CLI failure. +- Precondition at run start: "}'` succeeds | greenfield: `loom graph-stats` reaches the store — a typed NOT_FOUND still proves reachability>. **Degrade rule: if the store is unreachable at any point, fall back to grep recon and full-suite verification and keep going — the run NEVER blocks on the Loom.** The ledger must remain reconstructable from the conversation record alone. +- **Baseline discipline:** structural queries describe the most recently mapped commit — `, the pre-run repo, frozen for this run | greenfield: the bootstrap commit, advanced only by the scheduled re-maps>. Valid for what must not break; never for judging code written after it. New code is judged only by running commands and reading real diffs. +- **Semantic-layer discipline:** `claim` / `tension` / `pattern` entities are LLM-written leads. Verify at their file:line anchor before acting on one. No PASS or FAIL rests on a map entity alone. + +## STORE SAFETY — mechanisms before the first dispatch +- **Pre-flight backup:** before any dispatch, copy the store snapshot aside (`docker cp :/dump.rdb /preflight-dump.rdb`) and record the baseline: `DBSIZE`, `GRAPH.LIST`. Restoring this file is the documented recovery path for the run. +- **Watchdog:** at every phase boundary the lead re-reads DBSIZE/GRAPH.LIST and compares against baseline plus the graphs this run legitimately created. A shrunken store halts all dispatching until diagnosed. On confirmed loss, restore the pre-flight backup first; manual ledger reconstruction (void unresolvable UUIDs, re-map, record the wipe in GRAPH FACTS) is the last resort when no backup survives. +- **Every dispatch to every sub-agent carries this text verbatim:** "NEVER call FLUSHALL, FLUSHDB, SCRIPT FLUSH, CONFIG, or ANY instance-global redis command, from any client or library. Cleanup is ONLY deleting graphs/keys YOU created, verified by a scoped scan of YOUR prefix. If you are unsure whether a cleanup command is scoped, do not run it — leave the debris and report it." +- **Evidence safety:** at each batch/phase close, copy that batch's evidence subtree aside (commit it, or `cp -a` to a location the run never writes) — the copy is the layer that survives; then seal the closed batch's own subdirectory read-only (`chmod -R a-w`) — never the shared parent, so the next batch still writes. The watchdog's phase-boundary check also diffs closed batches against their copies. Every dispatch carries: evidence under the run directory is append-only — never delete or rewrite it; report instead. +- **Workspaces replace prefix discipline:** each builder/critic opens `begin-session` and creates all scratch state inside its namespace; cleanup is one `end-session`; hygiene is verified with `list-sessions`, never redis-cli. Scratch graphs use per-agent prefixes (`-b-`, `-crit-`); each agent deletes only its own prefix and verifies with a scoped scan. + +## PARTS — independence +One builder sub-agent per part. Per part: + +0. Foundation — interface contract between the parts that parallelize; acceptance suite encoding ; working toolchain (`` / `` / `` run clean on the skeleton). **Acceptance shape: enumeration** — the critic independently regenerates the interface table and the property→test coverage table against the brief. Nothing parallelizes until part 0 passes. +1. ; blast-radius set ; DISJOINT | SEAM with part K via — from queries actually run | greenfield: owns under the frozen contract; seams = the interfaces it consumes/exposes>; **acceptance shape: , round-1 artifact: **; scoped tests ``; >; pass when +2. ... +Parts with disjoint sets may run in parallel, each builder in an isolated worktree. Parts sharing a seam run serialized, in the order listed. Every worktree dispatch carries verbatim: "Never run `git stash` here — refs/stash is repo-global, so parallel builders that stash collide and can silently apply each other's WIP. Checkpoint WIP by committing to this worktree's own branch (`git add -A && git commit -m "wip"`, squashed before the PR); `git checkout -- ` only reverts tracked files and is not a stash substitute." + +## MODELS — assigned by measured complexity +Hard ceiling: **Opus**. No sub-agent runs on Fable/Mythos, even if this session's default model is Fable — pass the model explicitly on every dispatch. Effort levels are not dispatchable — where a part deserves extra deliberation, the dispatch prose says so. +- +- Critics on tension-bearing, high-centrality, or generalization-shaped parts: opus — a wrong verdict costs more rounds than the model saves. +- Part 0's critic: opus, always — a wrong interface freeze taxes every later part. + +## LEDGER — loop state lives outside the conversation +At run start create a dedicated graph `gauntlet-`. ` is READ-ONLY for this entire run. | greenfield: No agent writes the map graph `codebase-` directly — it changes only via the `/map-codebase` runs this prompt schedules (bootstrap, phase boundaries).> +- One `claim` entity per part , created **with the lead's dispatch-time confidence and `session: "gauntlet-lead"`** — assertion-time confidence is immutable history, so the ledger doubles as a calibration corpus, initial confidence `{"score": 0.1, "basis": "speculation"}` — confidence is never a bare number; `loom create-entity --schema` shows the shape. +- Every critic verdict is recorded by the lead: PASS → `evidence` entity + `supports` relation to the part claim + `resolve-claim {resolution: confirmed}`; FAIL → a `claim` entity for the specific gap; a gap later shown misdiagnosed → `resolve-claim {resolution: refuted}` on it. +- Every builder round closes with `loom record-outcome` citing the gap claim it addressed: `useful` if the next critic clears that gap, `dead_end` if the same gap survives, `corrected` if the gap was misdiagnosed. +- **Spin check is a query that is actually executed:** before any repeat dispatch, the lead RUNS the outcome-listing query for the gap claim and pastes the result into the dispatch. Two `dead_end`s → strategy change is mandatory. Enforcing this from memory is luck, not design. +- **Invalidation is a query:** if the integration critic contradicts evidence a PASS rested on, every part claim supported by that evidence re-enters the loop (and the part claim's confidence is knocked down with a `changeReason` until repaired). +- **Lead statelessness:** at each phase boundary the lead writes a checkpoint entity (parts passed, open gaps, next dispatch) and exports the same checkpoint as JSON to the run directory — so a successor lead re-enters from a durable record after context loss, compaction, session death, or a store wipe, not from transcript prose. +- The final report includes `loom session-changelog '{"graph": "gauntlet-"}'` and `loom calibration-profile '{"graph": "gauntlet-", "minBucketN": 1}'` — whether the lead's dispatch-time confidences meant anything is itself a measured number the next gauntlet can cite. + +## THE LOOP (per part) +1. Builder builds (in a worktree if parallel), honoring the part's round-1 artifact obligation from PARTS. Builders never grade their own work; for generalization-shaped parts, the builder's known-case results are explicitly not evidence. +2. Critics come in two grades: + - **Comprehensive critic** (round 1, and the exit round of any part that iterated): a fresh sub-agent, no builder context, no builder summaries — inspects the REAL artifact: runs the part's scoped tests ``, reads the full diff itself, renders/screenshots if visual, rehearses the acceptance criteria live. Blind A/B against REFERENCE where possible. For enumeration-shaped parts it independently regenerates the closed-set table. Its graph toolkit : `loom explore` on touched symbols for identical budgeted baseline context, and `find-callers` / `blast-radius` to fact-check builder assertions — subject to both GRAPH FACTS disciplines. + - **Repair-verification critic** (intermediate rounds): receives a "verified facts" preamble from the ledger (what prior rounds established — do not re-litigate), verifies the specific repair against the prior critic's exact transcripts, and regression-spot-checks. Full re-rehearsal happens only at entry and exit, not every round. Exception: a completeness claim — an enumeration table, or any "why-safe"/exhaustiveness assertion in code, comments, or commit messages — is regenerated fresh every round it recurs, never carried forward from a prior transcript or taken from the builder's own annotation. +3. **Critic protocols by claim type** — the required evidence procedure per builder-claim shape: + + | Builder claim | Required protocol | + |---|---| + | "measured, not a constant" | perturbation: edit the input, watch the output move, revert | + | "measured via a paid or metered resource" | mock-first dry run: perturbation on a synthetic stand-in + live re-check of each arm's preconditions, critic-verified before any real spend | + | "isolation/immutability invariant holds" | byte-compare or sha256 before/after | + | "generalizes" | contamination-listed fresh cases the builder never saw, both directions | + | "closed set / exhaustive / why-safe" | the critic regenerates the enumeration from the domain, not the builder's table or prose — every round the claim recurs, not just entry/exit | + | "repaired" | red/green (revert the fix → the new test must fail) + transplant new tests onto pre-repair source | + | "generated, not hand-edited" | regenerate + `git diff --exit-code` | + | any mutation happened | replay the response's `eventIds` via `what-changed` — one read, no dispatch re-read the store state through independent commands | + | always | a conduct-disclosure section: the critic reports its own accidents and near-misses | +4. **Metric integrity:** the critic reads the diff of the verification assets themselves (tests, fixtures, configs). A metric passed by weakening the metric is a FAIL. Commit messages must not overclaim tests or coverage that do not exist. +5. Critic returns PASS, or the single largest meaningful gap. The lead records the verdict in the LEDGER. +6. The gap goes back to the builder; the builder's round closes with its `record-outcome`. Loop. For generalization-shaped parts: two consecutive fresh-case failures of the same criterion → the mechanism class is wrong; the next dispatch mandates a design change, not a patch. +7. A part exits when: PASS, or critic rounds are spent — then mark it BEST-EFFORT, record the last verdict and remaining gap in the ledger and final report, and move on. The run never pauses for a human. + +## EVIDENCE RULES +A claim counts only with the artifact behind it: test output, screenshots, diffs, logs. "Done" from a builder is not evidence. Critics collect their own evidence. Where the store supports receipts, a mutation-shaped builder claim is checked by replaying its `eventIds` BEFORE any critic is dispatched for it — critics are for judgment, not existence checks. Ledger and map entities are evidence *pointers* — the file:line anchor and the command output they point to are the evidence. + +## BOUNDARIES — autonomous, so absolute +This run is fully autonomous: no step waits on human input, approval, or a question. Every decision is resolved by the rules in this prompt; where genuinely ambiguous, the critic's reading of the REFERENCE wins. +- Max critic rounds per part; max rounds total. +- Hard-forbidden — never done, never asked about: ` | greenfield: direct writes to `codebase-` outside the scheduled `/map-codebase` runs>; every instance-global store command (see STORE SAFETY — carried verbatim in every dispatch); . If a part cannot pass without one of these, it exits as BEST-EFFORT with that noted. +- Spin rule: two `dead_end` outcomes on the same gap claim means change strategy, not retry — checked in the ledger before every repeat dispatch. +-