Claude GitHub Copilot Skill

mold

Turn a high-leverage design decision into an approved spec through grounded dialogue. Use it when a leverage trigger fires (auth, irreversible effects, concurrency, contracts, destructive ops, a new slice, a cross-slice dependency, an invariant gap) or when the user asks for a sp

LLM Mart · 0 points · 9 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download paulnsorensen-easy-cheese-skills_mold-39444e8.zip · 3262 KB
Part of paulnsorensen/easy-cheese — 14 skills

Install

skills CLI npx skills add https://github.com/paulnsorensen/easy-cheese/tree/main/skills/mold
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install paulnsorensen-easy-cheese@llmmart
Git git clone https://github.com/paulnsorensen/easy-cheese.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole paulnsorensen/easy-cheese collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

/mold

Ceremony scales to the job. The Bounds pass picks one of three tiers from references/tiers.md: Quick writes a one-confirm mini-spec, Light runs only the dialogue modes the open forks need, and Full runs the whole Flow below. /cheese's tier-1 escalation enters mini-spec mode with no confirm; see ## Agent-invoked mini-spec mode.

Flow

  1. Bounds pass — open the Goal / Decided / Asking / [AGENT-DECIDED] ledger with the goal pinned as one sentence; only an explicit user fork changes it. Split it into G-n clauses (references/handshake.md § Goal coverage). Map every input's goals and non-goals as one [AGENT-DECIDED] line; ask the user only when the goal is genuinely unknown or a leverage trigger fires. Run the shape check, then announce the tier with its reason (references/tiers.md). Quick exits here: one fast confirm, then ## Agent-invoked mini-spec mode. Upgrade the tier whenever the evidence changes; never downgrade silently.
  2. Route — choose the secondary mode from references/modes.md, announce it, and correct false premises first.
  3. Dialogue — consequential forks are the user's to pick. A fork is consequential per the leverage line in ../age/references/voice.md. Every other fork is [AGENT-DECIDED]. Supply options, trade-offs, and evidence before you ask. Ground each critical claim through code, the Validate Cycle, or a Prototype Cycle. Resolve every contradiction. Render the decision map after three consecutive fork questions, or on request.
  4. Sketch — For work across modules or with a new public interface, run references/shape-check.md. Bind identity and role nouns to code referents. Record the Placement block; no bodies.
  5. Plan for approval — run the fresh-context fork-coherence taste test with python3 skills/mold/scripts/mold.pyz taste-test and persist its digest-bound pass; a failure reopens only named forks, and the third failed verdict stops. Light with one expected curd stops here: no planner; finalize the bounded spec with python3 skills/mold/scripts/mold.pyz finalize and retain its canonical HandoffPointer. Otherwise dispatch a typed PlannerRequest, validate its PlannerResultWriterView (one retry, then stop before the handshake), normalize on the host, and persist only the typed PlannerResult and CurdPlan. Present the plan's semantic curds and waves at the handshake. See references/curdle.md § "Pre-approval typed planner dispatch".
  6. Two-key handshake — Before extraction, the user and agent must agree to the draft spec and displayed typed plan. The user provides an explicit verb. The agent performs a coherence self-check. Neither key changes nor disappears. See references/handshake.md.
  7. Curdle — Resolve the durable spec path with SPEC=$(python3 skills/mold/scripts/mold.pyz artifact-path specs <slug>). Phase one writes the local artifact and write-ahead prepared state before any external call. It writes the approved spec at "$SPEC". It also writes the host-validated PlannerResult and CurdPlan. It also writes local issue drafts and the session's non-obvious decisions as durable ADRs. Phase two publishes approved follow-ups. Retain the prepared recovery state when an external capability is unavailable or publication fails. Phase two reconciles their state and references into the durable spec before any handoff. The resolved spec path is internal; Cook receives only the finalizer's canonical HandoffPointer.
  8. Finalize and hand off — after reconciliation, run python3 skills/mold/scripts/mold.pyz curd-count, then finalize through ## Handoff. Full and Light both hand that pointer to Cook. Dispatch only the user's non-stop selection.

Portability: rules. Slash commands are host renderings, not the control model.

Follow-up candidates

Every non-goal and explicit dialogue deferral becomes a [FOLLOW-UP?] follow-up candidate. Dispose of the set before the two-key handshake; details: references/handshake.md § Follow-up disposition.

Modes

Mode Use when Goal
Explore The idea is vague Identify the real problem and pain point
Ground A file, bug, or existing doc is named Verify facts against evidence
Shape The goal is known but approach is open Compare viable options (Do Nothing always included)
Sketch Interfaces or module boundaries matter Lock responsibilities and seams
Grill A favoured approach needs stress-testing Steelman each item, then put every design-changing call to the user as a fork
Diagnose A symptom, failure, or trace is supplied Build a Loop → reproduce → hypothesize → confirm root cause

Modes: references/modes.md. Evals: references/evals.md. Canvas: review-canvas.md.

Agent-invoked mini-spec mode

/cheese's tier-1 escalation calls /mold after the call site passes all cook fast-path checks, and the Quick tier enters the same mode after its one confirm. It produces a spec without design dialogue. This mode skips the rest of the Flow above. Derive a slug. Write the mini-spec. Parse its declared gate applicability. Finalize through ## Handoff and return its canonical HandoffPointer to Cook. Append --hard when the user passed it.

The two-key handshake does not run in this mode. The agent-introduced-scope check still runs implicitly. Every distinguishing noun must come from the user's input or tier-2 /culture//briesearch synthesis. Never add one silently.

Full procedure, the mini-spec schema, and the ## Provenance rules: references/mini-spec-mode.md.

Preferred tools and fallbacks

Call source-code search, read, and edit backends according to code-intelligence-routing.md. Shape checks use semantic caller search plus dependency context; procedure: references/shape-check.md.

Mold-specific tools beyond source-code routing:

Need Prefer Fallback
External validation /briesearch with Context7/Tavily user docs, repo docs, or note as unverified
Wiki grounding (Ground entry + decision points; scope per references/grounding.md § When to probe) mcp__hallouminate__list_corpora + mcp__hallouminate__ground on repo:<repo>:wiki record hallouminate: absent in the ledger, proceed on code evidence, and cap at speculating when design rationale is central

The grounding record precedes the first structured question: the ledger holds a probe result — citations or hallouminate: absent — first. Mark each unsupported claim [?] until settled.

Sub-agent context gate

/mold owns the dialogue, contradictions, and approval state. Do not delegate these items. Delegate evidence-heavy code work to a fresh-context explorer and external research to a researcher. Shape uses an explorer digest as input. Record parent-context exploration as a degraded path. See references/context-budget.md for budgets and checkpoints.

Gate graph

python3 skills/mold/scripts/mold.pyz gate-graph --render dot|svg|png|mermaid renders one gate model. Image targets use Mermaid when Graphviz is unavailable. Tests keep gate nodes aligned with the handshake checklist. See references/gate-graph.md.

Gate applicability and Test Contracts

Every Mold-produced spec carries a provenance marker in frontmatter:

source: mold-handshake | agent-mini-spec

Every spec declares gate_applicability:

gate_applicability:
  disposition: red-required | not-applicable
  work_class: behavior | docs-only | refactor-only | test-only | appearance-only
  ui_surface: browser | non-browser | not-applicable

ui_surface is required on the Mold production path: browser means every Test Contract names an existing browser/E2E interface and outer seam, non-browser is explicit and never inferred from prose, and not-applicable is required for closed non-behavior classes including appearance-only. red-required requires behavior plus a complete ## Test Contracts table with one executable red row; not-applicable requires a closed class, a reason, and no contracts. Mold never infers applicability. Row-level rules: references/curdle.md § Test Contracts.

Fork taste gate

python3 skills/mold/scripts/mold.pyz taste-test binds the verdict to draft SHA256 and each settled fork. Stale, partial, or blocked verdicts fail; a failure reopens only named forks, with two rounds. Approved red-required specs pass unchanged metadata and the published pointer to /cook --auto.

Each fork appears in Approach, Interface sketches, Acceptance, plus Test Contracts for red-required; none in not-applicable specs. Do not rename sections. Tag reflecting lines with fork id and run taste-test --precheck before dispatch. goal must survive verbatim in Problem statement (goal-drift); each G-n clause carries an Acceptance or disposition tag (goal-coverage). See references/curdle.md § Spec template and references/gate-graph.md.

Approval gate

Curdle requires the two-key handshake. It requires an explicit user verb: curdle or ship it. It also requires the agent's coherence self-check. Present the validated typed CurdPlan's N curds / M waves with the final approval request in Flow step 5; on Light's single-curd path there is no plan, so present the spec alone and mark the plan boxes n/a. See references/handshake.md for the checklist, mandatory gates, and override semantics.

Before the handshake, print the narrowing delta (taste-test --coverage), then present the scope audit table once. One confirm approves the defaults; only leverage rows and unresolved bindings need a verb, and curdle anyway waives neither. See references/handshake.md.

If any gate is unmet, propose the smallest next question, evidence check, or planner correction. Do the same if the typed plan remains invalid after one retry. Write artifacts only after both keys pass.

--hard

Mold never runs the metacognitive check. Plate alone runs it at the verified-artifacts boundary. Mold appends --hard to every Cook command that it emits when the user passed the flag. Cure forwards the same flag to Plate. See ../hard-cheese/references/composition.md.

Handoff

Pipeline: culture → [mold] → cook → press → age → cure → plate

After Curdle's phase two finishes, run python3 skills/mold/scripts/mold.pyz curd-count for the blast-radius digest. Finalize with python3 skills/mold/scripts/mold.pyz finalize and keep its consumer-valid canonical HandoffPointer path; finalize does not require curd-count first. Prompt through the shared handoff gate (policy). Approved red-required behavior recommends handing the canonical HandoffPointer to /cook --auto. Keep the applicability, contract, and taste metadata unchanged. Append --hard when the user passed it. Never pre-select.

The digest's mode is orientation, not a skill. Render the fixed blast-radius menu from decomposable, candidate_curds, verdict, and mode; see references/handoff-menus.md.

Rules

  • Dialogue first; artifacts are the by-product.
  • Tiered lettered options. Consequential forks use A/B/C/D choices via the question transport at ../cheese/references/ask-user-question.md. Never decide them silently. Everything below the leverage line is [AGENT-DECIDED] by default: make the call, log a one-line vetoable alternative in the ledger, and do not ask. A fork is valid only after its depth was contributed in-dialogue first. Precede every structured question with visible prose that weighs the fork and the evidence. Keep one open picker.
  • Altitude tag. Every Asking fork names the acceptance criterion, public seam, or non-goal it moves. A fork that moves none, or that sits below the leverage line, is [AGENT-DECIDED] or a follow-up candidate, never a user question.
  • Decision ledger. Each round prints Goal / Decided / Asking / [AGENT-DECIDED], the goal verbatim. Curdle persists consequential decisions to ADRs and minor ones to the spec. The taste verdict names every settled consequential entry exactly once.
  • Decision map and fork-round cap. Stop after three consecutive fork rounds that add no new evidence, or three consecutive forks that fail the altitude tag, or when the user requests a decision map. Show completed forks, remaining forks, and a ready or blocked verdict. A fourth round requires new grounding, a delegated digest, or a /wheypoint checkpoint. The map shows ledger state. It does not create an artifact.
  • Do not implement code.
  • Do not write production files before the approval gate.
  • Do not silently settle uncertain claims.
  • Apply the shared voice kernel at ../age/references/voice.md. Correct false premises. Mark each critical claim's confidence as certain | speculating | don't know. Steelman before you dismiss. Put consequential forks to the user; depth informs the question, never replaces it.

The schema entanglement behind curdle's spec-template and cook's writer views is phase registry × schema catalog × models per transition. The generated ../cheese/references/schema-intertwine.md documents it.

Agent resolution

Resolve delegates through ../cheese/references/agent-resolution.md.

Work Preferred types Permissions/isolation Minimum power Effort Fallback
Explore the codebase explorer read-only, fresh-context default medium compatible explorer, then general
Research external constraints researcher read-only, fresh-context default medium compatible researcher, then general
Plan for approval planner, general read-only, fresh-context powerful high compatible planner, then general

The canonical mold spec or mini-spec carries the shared agent_resolution block. Commands: references/commands.md.

Files (easy-cheese)
  • references
    • adr.md 3.9 KB
      # ADRs — durable design rationale
      
      Mold records the non-obvious decisions of a session as Architecture Decision
      Records (ADRs). The approved spec and its ADRs are **durable** project records:
      the spec keeps the implementation contract, while ADRs preserve the rationale a
      future session would otherwise re-derive. Write them at Curdle, after the two-key
      handshake, in phase one's local atomic write.
      
      ## What earns an ADR
      
      One ADR per decision a future reader would otherwise have to reverse-engineer:
      
      - a chosen approach over a real alternative (the trade-off, not the obvious pick);
      - a constraint discovered mid-dialogue (a Prototype Cycle answer that changed the
        design; a `[CONFLICT]` the codebase forced);
      - anything tagged a Decision in the spec that has a substantive rationale.
      
      Do **not** write an ADR for a forced move with no alternative, or for a detail the
      spec body already states plainly.
      
      ## Decision ledger
      
      Mold's per-round decision ledger (`Decided / Asking / [AGENT-DECIDED]`, see
      `../SKILL.md` § Rules) persists **here at curdle**: each consequential decision
      (per the leverage line in `../../age/references/voice.md`) earns an ADR — it is exactly the kind of decision a future reader would
      otherwise reverse-engineer. `[AGENT-DECIDED]` calls ride the spec's one-line
      decision-log (`curdle.md` § Spec template) with their vetoable alternative,
      never a full ADR; the ledger keeps no separate file (ADR-004).
      
      ## Resolution — where ADRs land (portable, never hardcoded)
      
      Mold runs in arbitrary repos. The corpus is resolved **dynamically at curdle**,
      never hardcoded — there is no `easy-cheese:wiki` baked into a runtime path.
      
      ```pseudocode
      adr_target():
        # 1. Probe for a hallouminate wiki at the CONSUMER's root repo.
        #    Shape-match the corpus, never exact-match a placeholder — the repo name is
        #    dynamic (the bundle command uses the same shape-match).
        corpus = first(c for c in hallouminate.list_corpora()
                       if c.startswith("repo:") and c.endswith(":wiki"))   # dynamic; their repo, not ours
        if corpus:
          return ("hallouminate", corpus)        # searchable, cross-session
        # 2. Fall back to a tracked file path everywhere else.
        return ("file", "docs/adr/<slug>-NNN.md")  # tracked in the consumer's repo
      ```
      
      - **hallouminate present:** write each ADR into the consumer's
        `repo:<their-repo>:wiki` corpus via `add_markdown`. The corpus is shape-matched
        from `list_corpora`, never a literal — that is the portability invariant.
      - **hallouminate absent:** write `docs/adr/<slug>-NNN.md` (tracked), emit a **loud
        one-line note** that the ADR went to a file rather than the wiki (never a silent
        degrade — see `curdle.md` § Atomic write), and recommend installing hallouminate
        so future rationale becomes searchable.
      - **probe shape varies by harness** `[?]`: if `list_corpora` is unreachable, fall
        back to the tracked file path and say so — never block curdle on the probe.
      
      The spec path follows the separate artifact resolver contract and remains in its
      durable project corpus; ADR target resolution does not make the approved spec
      transient.
      
      ## ADR format
      
      Mirror the spec's own `## ADRs` section shape (this very spec uses it):
      
      ```markdown
      ### ADR-NNN: <one-line decision title>  [status: accepted]
      - **Context:** <what made this a real decision; the forces in play>
      - **Decision:** <what we chose>
      - **Alternatives:** <the rejected options and why>
      - **Consequences:** <what this buys and what it costs later>
      ```
      
      Numbering is per-slug (`<slug>-001`, `-002`, …) on the file fallback; in the wiki,
      prefix the page slug the same way so the series stays grouped.
      
      ## Timing
      
      ADRs are a phase-one Curdle by-product. Write them **after** both handshake keys
      pass, in the same local atomic step as the durable spec and before any external
      follow-up publication. They never substitute for the spec's own `## Decisions`
      line: the ADR is the long form; the Decisions bullet is the index entry.
      
    • commands.md 1.5 KB
      # `/mold` bundle commands
      
      `scripts/render_generated_regions.py` generates this file from the static `COMMANDS` manifest in `src/easy_cheese/skills/mold/commands.py`. Do not edit this file. Run each command as `python3 skills/mold/scripts/mold.pyz <command> [args...]`. Each command returns an integer exit status. Pass `--help` to a command for its arguments and output format. Keep worked examples in the skill instructions.
      
      | Command | Purpose | Subcommands |
      | --- | --- | --- |
      | `approve` | Record the user's literal approval response as a retained MoldCookApproval |  |
      | `artifact-path` | Resolve the durable or transient artifact path for a phase and slug |  |
      | `curd-count` | Count candidate curds in a spec and recommend the next skill |  |
      | `domain-model-target` | Resolve the domain-model store from explicit Hallouminate probe results |  |
      | `finalize` | Finalize a Mold spec and publish only a consumer-valid handoff |  |
      | `gate-graph` | Render the gate state machine as dot, svg, png, or mermaid |  |
      | `normalize-planner` | Materialize a planner writer envelope into a canonical PlannerResult |  |
      | `render-html` | Render a markdown report into one self-contained offline HTML file |  |
      | `review` | Serve and manage the local Mold review canvas |  |
      | `taste-test` | Run the applicability, contract, and fork-coherence taste gate; --precheck runs the lexical pre-check on the draft without a verdict |  |
      | `validate-spec` | Check a spec against the current Mold specification requirements |  |
      
    • context-budget.md 4.5 KB
      # Context budget
      
      A long Mold dialogue can reduce model recall and coherence. This risk increases near 120,000 to 140,000 tokens. Mold controls this risk in three ways. It delegates heavy work, limits active orchestration, and recommends a checkpoint when the context grows. Delegation is the most reliable control. See ADR-003.
      
      ## Delegate heavy work by default
      
      Use the sub-agent context gate for heavy work. Resolve the read-only role through `../../cheese/references/agent-resolution.md`. Select the exact specialist first. Then select a compatible specialist. Use a constrained general worker with `degraded: true` only when no specialist is available. Work in the parent context only when dispatch is unavailable.
      
      - **Research:** Delegate deep `/briesearch` work to a `researcher`. Deep work uses at least three document fetches or two search angles.
      - **Shape check:** Delegate wide analysis to an `explorer`. Wide analysis includes more than five symbols or a large caller graph.
      - **Prototype Cycle:** Always run the temporary build in an `explorer`. See `prototype-cycle.md`.
      - **Diagnose:** Delegate large logs and traces to an `explorer`. Keep only the concise root-cause hypothesis in the parent context.
      
      The sub-agent returns a digest of 2 KB or less. Do not copy raw evidence into the parent context. The parent keeps the dialogue, contradictions, approval state, and two-key handshake. Never delegate these items.
      
      ## Orchestration budgets
      
      Token pressure gives a late warning. Active orchestration consumes the context before this warning occurs. One Mold episode can include bounds, grounding, research, Shape, taste tests, planning, approval, and publication.
      
      The 2026-08 workflow sample contains 16 top-level invocations. The median active time is 35.6 minutes. Large sessions use 100 to 276 tool calls and up to 11 sub-agent spawns.
      
      Each phase has a bound and an exhaustion action. When a phase reaches its bound, stop new work. Record the settled work and take the checkpoint.
      
      | Budget | Bound | On exhaustion |
      | --- | --- | --- |
      | Ground per topic | 1 wiki probe and 1 delegated digest | Mark the remainder `[?]`. Treat a third probe as repeated work. |
      | Shape or Sketch per option set | 1 explorer digest | require a new question before a second dispatch |
      | Fork rounds | 3 consecutive rounds that add no new evidence | show the decision map and stop questions |
      | Fork altitude | 3 consecutive forks that move no acceptance criterion, seam, or non-goal | show the decision map; demote the pending fork to `[AGENT-DECIDED]` or a follow-up candidate |
      | Parent-context tool calls | approximately 40 calls | run `/wheypoint` before the next heavy step |
      | Sub-agent spawns | 6 spawns per episode | Run `/wheypoint`. Resume from the digests. |
      | Repeated failures | 2 consecutive failures from the same tool or agent | record the degraded path and use a different route |
      
      Count only calls and spawns from the parent context. Do not count internal sub-agent tool calls. Delegation exists to move those calls out of the parent context.
      
      These budgets are not terminal limits. Exhaustion requires a checkpoint or a recorded degraded path. It does not permit a truncated design. Do not make a silent third attempt.
      
      ## Context estimate
      
      No precise live token count is available. Use the visible signals to estimate context use.
      
      | Estimate | Action |
      | --- | --- |
      | approximately 120,000 tokens | Advise the user that the context is filling. Delegate the next heavy step. Keep each question concise. |
      | approximately 140,000 tokens | Recommend `/wheypoint`. Resume in a fresh context. |
      
      Estimate from the turn count, sub-agent digests, and large pasted inputs. Do not report false precision. Delegate before you recommend a checkpoint. Delegation directly reduces parent-context use.
      
      ## Wheypoint checkpoint
      
      At approximately 140,000 tokens, recommend this action. Do not run it automatically.
      
      ```text
      The dialogue can now reduce model recall. Run /wheypoint to save the settled decisions in .cheese/notes/<slug>.md.
      Resume in a fresh session with /cheese --continue <slug>.
      ```
      
      `/wheypoint` preserves the dialogue, contradictions, approval state, and open Validate or Prototype cycles. The fresh agent resumes at the current handshake state. It does not derive the design again. See `skills/wheypoint/SKILL.md`.
      
      ## Why Mold recommends a checkpoint
      
      A hard token gate can stop confidence work too early. ADR-003 rejects this behavior for cycle caps. Context pressure is approximate. Therefore, Mold recommends delegation or a checkpoint instead of ending the dialogue.
      
    • curd-count.md 4.3 KB
      # Curd count — recommendation driver
      
      Runs after Curdle writes the spec, before finalization. Pushes the parse-and-count
      work into a Python script so the sizing signal is deterministic and stays out
      of the conversation's token budget.
      
      ## What it answers
      
      Curd-count reports candidate sizing and the recommended downstream skill. The
      digest includes goal, quality-gate, and decision signals; landing metadata; and
      an advisory Cook wave-plan mode. It has no handoff field and does not construct
      an execution command. Finalization alone evaluates all required evidence and
      publishes a canonical Cook handoff when the result is ready.
      
      The recommendation names the skill only. The count is advisory sizing: it never
      authorizes Cook, bypasses finalization, or turns a saved non-ready result into a
      runnable handoff.
      
      A decomposition of `PARALLEL_THRESHOLD` (2) or more curds signals a parallel
      Cook wave-plan; below that, high blast radius signals a linear chain. The
      decomposer stays authoritative—the count is a pre-dispatch hint, not the mode
      gate. `/ultracook` is retired as a top-level skill choice.
      
      ## Procedure
      
      After `curdle.md` writes the spec to disk, run the script and read the JSON
      digest into context:
      
      ```bash
      SPEC=$(python3 skills/mold/scripts/mold.pyz artifact-path specs <slug>)
      python3 skills/mold/scripts/mold.pyz curd-count "$SPEC" \
        --blast-radius <low|medium|high>
      ```
      
      Pass the `--blast-radius` value verbatim from the shape-check verdict line
      (see `shape-check.md`). If shape-check was skipped or its verdict was `[?]`,
      omit the flag; the route stays `/cook`, while
      sub-threshold specs receive no Cook mode hint.
      
      ## Signals counted
      
      | Signal | Source in the spec |
      | --- | --- |
      | `goals` | Bullets under `## Goals` |
      | `quality_gates` | Bullets under `## Quality gates` (also matches `## Acceptance criteria` for legacy specs) — reported, **not** counted |
      | `decisions` | Bullets under `## Decisions` (reported but not used in the rule) |
      
      `candidate_curds = goals` — only distinct behavioural goals drive the count.
      `quality_gates` (acceptance criteria) and `decisions` are reported as signals
      but deliberately excluded from the count: they are facets of one coherent
      change, not independent file-disjoint curds. Counting acceptance criteria as
      curds inflated the recommendation toward parallel fan-out for single coherent
      refactors whose own criteria reference the same files (issue #111) — the more
      thoroughly a spec was written, the more likely it mis-recommended fan-out.
      
      ## Decision rule
      
      `recommended_skill` is always `/cook`; it is an advisory destination, not an
      execution decision. Curd-count emits no handoff or command. The independent Cook
      mode signal follows the curd count and blast radius:
      
      | `candidate_curds` | `blast_radius` | `mode` |
      | --- | --- | --- |
      | ≥ 2 (`PARALLEL_THRESHOLD`) | any | `parallel` |
      | < 2 | `high` | `linear` |
      | < 2 | `medium`, `low`, or unknown | `null` |
      
      ## Digest shape
      
      ```json
      {
        "spec_path": "<resolver-owned durable spec path for <slug>>",
        "slug": "<slug>",
        "blast_radius": "high",
        "candidate_curds": 7,
        "signals": {"goals": 7, "quality_gates": 6, "decisions": 3},
        "threshold": 2,
        "decomposable": true,
        "recommended_skill": "/cook",
        "mode": "parallel",
        "rationale": "7 candidate curds >= 2 threshold; parallel fan-out (advisory)"
      }
      ```
      
      ## Independence is the user's call
      
      The script counts; it cannot verify that the candidate curds are file-disjoint
      (criterion 4) from spec text alone. Before a parallel wave-plan runs, mold
      confirms independence with the user — typically by naming each curd's `scope`
      from the typed `CurdPlan` (the planner derives file footprints from the
      Placement block's `slice:` and `public interface:` lines plus the shape-check
      importer list; `## Interface sketches` itself carries no file paths) and
      asking whether any two candidate curds touch the same file. If they do, the decomposer folds the shared-file
      curds back into the linear chain; the dispatched skill is `/cook` either way.
      
      ## When tilth / Python is unavailable
      
      The script depends only on the Python 3 stdlib. If the host has no `python3`,
      Mold may report the sizing signal manually: count the behavioural goals and
      apply the blast-radius mode table. Finalization still owns readiness and
      publishes any Cook handoff; do not substitute an execution command.
      
    • curdle.md 27.2 KB
      # Curdle — artifact extraction
      
      Curdle is the terminal state of mold. It runs only after the two-key handshake (see `handshake.md`).
      
      ## Artifact types
      
      Resolve the spec path with `SPEC=$(python3 skills/mold/scripts/mold.pyz artifact-path specs <slug>)` — it anchors at the per-project durable corpus (see `../../cheese/references/formatting.md` § Corpus location). Issues stay repo-local: write them as `.cheese/issues/<slug>-NNN.md`.
      
      | Type | When | Path |
      | --- | --- | --- |
      | **Spec** | Any meaningful design discussion | `$SPEC` (resolver output) |
      | **Spec + Issues** | Accepted follow-ups whose disposition calls for local recovery or tracker payload | spec at `$SPEC`; issues at `.cheese/issues/<slug>-001.md`, `-002.md`, … |
      | **Issues only** | Pure standalone bug tickets, no design | `.cheese/issues/<slug>-001.md`, … |
      
      A spec is the rich container. It absorbs problem framing, requirements, approach, decisions, interface sketches, risks, and gates. An issue is a separate GitHub-flavoured item. The user can paste it into a tracker.
      
      ## Slug rules
      
      - Lowercase the working problem statement, drop stopwords, kebab-case, cap at 5 words.
      - **Validate every slug before any Curdle write.** Run `python3 skills/mold/scripts/mold.pyz artifact-path specs <slug>`. The command applies `validate_slug` and returns a nonzero status for an invalid slug. Stop on a nonzero status.
      - Accept a user-passed slug only after that command returns status zero. A slug can otherwise contain `..` or `/` and write outside `.cheese`.
      - Reuse the validated slug for every repo-local path. Repo-local paths include `.cheese/issues/`, `.cheese/glossary/`, and `.cheese/.out-of-scope/`. Never interpolate a raw slug into a path.
      - Match the spec's parent slug for issues (`<slug>-001.md`, `-002.md`).
      
      ## Collisions
      
      | Existing | Action |
      | --- | --- |
      | Same slug, status `draft` | Overwrite (default) or rev (`<slug>-v2`) — ask if unsure |
      | Same slug, status `approved` | Default to rev; never silently overwrite |
      | Existing spec, new issues for same slug | Append issues to that slug's series |
      
      ## Spec template
      
      Cross-cutting house style and citation form: [`formatting.md`](../../cheese/references/formatting.md). This section owns the spec shape; formatting.md owns the voice rules and the footnote primitive.
      
      `landing.layers` records ordered groups of canonical curd ids from the approved CurdPlan, as a one-line flow list. Leave it `[]` only when `shape` is `single`; a non-single shape requires at least one layer.
      
      **Fork-id tags.** Every settled consequential fork in the decision ledger must appear in Approach, Interface sketches, and Acceptance, plus Test Contracts for `red-required`. Each line that reflects a fork carries the fork id in parentheses, for example `- AC-3: WHEN ... THE SYSTEM SHALL ... (F-3)` or `public interface: parse(...) -> Result  (F-2)`. The taste test matches the fork id literally, or every 3+ letter word of the decision text; the tag is the reliable form.
      
      **Goal-clause tags.** Every `G-n` clause from the ledger's `goal_clauses` carries its tag on at least one Acceptance line, or on exactly one disposition line: a `Non-goals` bullet, a `Deferred follow-ups` entry, or a `[TBD]` item under `Open questions`. The pre-check fails `goal-coverage:G-n` for an untagged clause and `goal-coverage-cap:<covered>/<total>` when fewer than half the clauses reach Acceptance. See `handshake.md` § Goal coverage. Run `python3 skills/mold/scripts/mold.pyz taste-test --precheck --draft <draft> --ledger <ledger>` before the reviewer dispatch; fix every reported gap first.
      
      ```markdown
      ---
      slug: <slug>
      status: draft
      source: mold-handshake
      created: <YYYY-MM-DD>
      confidence: <low | medium | high>
      leverage: []   # fired trigger ids per `../../cheese/references/routing-policy.md` § Leverage triggers; copied from the handoff packet, extended when a later mode fires one
      gates_overridden: []   # list of unchecked handshake items if `curdle anyway` was used
      agent_introduced_scope: []   # terms in the spec the user did not type — approved through the scope audit table per `handshake.md` § Scope audit table (audit trail; downstream skills trust this list)
      goal_coverage: {}   # G-n -> covered | non-goal | follow-up | tbd, the final disposition map printed as the narrowing delta per `handshake.md` § Goal coverage (audit trail; downstream skills trust this map)
      entity_referent_bindings: []   # list of binding records {noun, verdict, referent, citation, note} for identity/ownership-role nouns bound to code referents or marked NEW ENTITY — each resolved per `handshake.md` § Entity-referent binding (audit trail; downstream skills trust this list)
      agent_resolution: []   # the shared agent-resolution block per `../../cheese/references/agent-resolution.md`
      gate_applicability:
        disposition: red-required | not-applicable
        work_class: behavior | docs-only | refactor-only | test-only | appearance-only
        ui_surface: browser | non-browser | not-applicable
        reason: <required only for not-applicable>
      landing:
        shape: single | orthogonal_flat | stacked_linear | diamond_stack
        layers: []
        per_layer_green: required | tip-only
        review_fixes: fold | top-up
      
      # <Title>
      
      ## Problem
      <one paragraph; what's broken or missing today, who feels it>
      
      ## Goals
      - G-1: <one outcome clause of the pinned goal, verbatim from the ledger>
      - G-2: <...>
      
      ## Non-goals
      - <bullet>  (G-n when this bullet defers a goal clause)
      
      ## Deferred follow-ups
      - **<deterministic follow-up ID>** — <summary>
        - Destination: <github_issue | roadmap_goal | local_draft>
        - State: <prepared | linked | created>
        - Reference: <local draft path | URL | durable roadmap reference>
      
      ## Grounding
      
      Add exactly one row for each probe. Use `hit`, `miss`, or `unavailable` for `Outcome`.
      Use `unavailable` when a probe cannot run. Record the attempted action in `Evidence`.
      Do not leave `Evidence` blank. You can skip a probe, but do not assume its result.
      
      | Probe | Outcome | Evidence |
      | --- | --- | --- |
      | wiki | <hit \| miss \| unavailable> | <wiki path and one-line finding, or what was attempted> |
      | explorer | <hit \| miss \| unavailable> | <explorer digest path and one-line finding, or what was attempted> |
      
      ## Approach
      <chosen option summary>
      
      ## Decisions
      - <one-line decision> — <one-line rationale>
      - _Minor decisions:_ <one line capturing the `[AGENT-DECIDED]` calls the user did not veto — the per-round ledger's minor tier; major decisions get full ADRs per `adr.md`>
      
      ## Acceptance
      
      Write acceptance criteria in **EARS form** by default:
      ```
      WHEN <trigger> THE SYSTEM SHALL <response>
      ```
      If the trigger cannot be stated precisely (e.g. pure internal utilities with no external event), use prose with a `[prose-fallback]` marker.
      
      - AC-1: WHEN <trigger> THE SYSTEM SHALL <response>  (<fork-id>, <G-n>)
      - AC-2: WHEN <trigger> THE SYSTEM SHALL <response>  (<fork-id>, <G-n>)
      
      ## Test Contracts
      
      Include this entire section only when `gate_applicability.disposition` is
      `red-required`. Every numbered Acceptance ID appears exactly once in this table.
      `expected_failure` names a deterministic witness and expected red assertion.
      `mode` is `tracer`, `contract-matrix`, or `guard`.
      The seam is the outer boundary that proves the behavior.
      A matrix names its ratified interface version and each unique row identity.
      Separate row identities with `<br>`.
      A guard or tracer leaves those cells blank.
      Add one row for each criterion.
      
      | Acceptance ID | Interface referent | Outermost stable seam | Expected failure | Mode | Interface version | Matrix rows |
      | --- | --- | --- | --- | --- | --- | --- |
      | AC-1 | <public interface> | <existing outer seam> | <witness and expected red assertion> | tracer | | |
      | AC-2 | <public interface> | <existing outer seam> | <witness and expected red assertion> | contract-matrix | <ratified version> | <row 1><br><row 2> |
      
      ## Interface sketches
      
      The Placement block from Sketch (`modes.md` § Sketch). Architecture at 10,000 ft, not bodies.
      
      ```text
      slice:            <owning slice | NEW SLICE>
      spine step:       <entry | workflow | domain | infra | none>
      public interface: <one signature per new or changed crust export>  (<fork-id>)
      private:          <responsibilities that stay behind the crust>
      crust delta:      <new exports | cross-slice imports | contract changes | none>
      arrows:           <dependency directions added, or none>
      ```
      
      ## Risks
      - <bullet>
      
      ## Open questions
      - [TBD] <question>
      - [BLOCKED] <question> — <unblocker>
      
      ## Quality gates
      - <runnable command>: <expected result>
      
      ## Curds
      <the host-validated typed CurdPlan approved at the two-key handshake>
      
      ## Reproduction (Diagnose only)
      <failing test, curl, replay command, etc.>
      
      ## References
      <one footnote definition per cited source; include only when out-of-scope evidence was cited above per `../../cheese/references/formatting.md` § Citations>
      ```
      
      `source: mold-handshake` marks the strict Mold production path. Every new
      behavior declaration must set `ui_surface` to `browser` or `non-browser`;
      closed non-behavior declarations, including `appearance-only`, set it to
      `not-applicable`. A browser declaration is valid only when every Test Contract
      names an existing browser/E2E interface and outer seam.
      
      Specs without this provenance marker are v0.13-era legacy and stay
      **readable forever**: `validate-spec` accepts them, waiving only the two parts
      the hardened format added after v0.13 — the `Test Contracts` section and the
      `gate_applicability` block — and printing a one-line `NOTICE:` rather than an
      error. Everything a v0.13 spec did carry is still validated. Minting is the
      mirror image: Curdle writes only the template above and gates it with
      `validate-spec --strict`, which enforces the hardened format *and* the
      `source:` marker unconditionally. Legacy is a read-side grace, never a
      write-side option. The policy lives once in
      `src/easy_cheese_schemas/spec_format.py` so every release channel inherits it.
      
      ### Current mold-spec schema (generated)
      
      The `mold-spec` document contract enforced by `validate-spec` (`shape-check.md`), refreshed by `scripts/render_generated_regions.py` from the `MoldSpecDocument` model in `src/easy_cheese_schemas/contracts.py`. Do not hand-edit the generated region.
      
      <!-- BEGIN GENERATED: mold-spec-schema -->
      document mold-spec {
        section "Problem"
        section "Goals"
        section "Non-goals"
        section "Deferred follow-ups"?
        section "Grounding" {
          columns: ['Probe', 'Outcome', 'Evidence']
          per_row: ['Probe and Outcome are drawn from their closed sets', 'Evidence is non-empty, including for unavailable outcomes']
        }
        section "Approach"
        section "Decisions"
        section "Acceptance"
        section "Test Contracts"? {
          columns: ['Acceptance ID', 'Interface referent', 'Outermost stable seam', 'Expected failure', 'Mode', 'Interface version', 'Matrix rows']
          per_row: ['tracer rows leave Interface version and Matrix rows blank', 'contract-matrix rows require both Interface version and Matrix rows']
        }
        section "Interface sketches"
        section "Risks"
        section "Open questions"
        section "Quality gates"
        section "Curds"
        section "Reproduction"?
        section "References"?
      }
      
      rule ac-coverage-exactly-once: "Every Acceptance ID must appear exactly once in the Test Contracts table."
      rule tracer-row-blank-matrix-cells: "Tracer rows must leave Interface version and Matrix rows blank."
      rule contract-matrix-row-requires-both: "Contract-matrix rows require both Interface version and Matrix rows."
      rule grounding-probe-recorded: "The Grounding table must record the wiki probe exactly once with non-empty evidence."
      rule delegation-digest-recorded: "The Grounding table must record the explorer probe exactly once with non-empty evidence."
      rule not-applicable-closed-class: "red-required requires Test Contracts; not-applicable forbids them and requires a reason."
      rule landing-closed-class: "landing fields take only their declared values; layers is empty when shape is single."
      
      type GateApplicability {
        disposition GateApplicabilityDisposition
        work_class WorkClass
        ui_surface UiSurface
        reason? str | None = None
      }
      
      type GroundingRow {
        probe GroundingProbe
        outcome GroundingOutcome
        evidence str
      }
      
      type Landing {
        shape LandingShape
        layers? tuple[tuple[str, ...], ...] = ()
        per_layer_green? PerLayerGreen = required
        review_fixes? ReviewFixes = fold
      }
      
      type MoldSpecDocument {
        frontmatter MoldSpecFrontmatter
        acceptance_ids? tuple[str, ...] = ()
        test_contract_rows? tuple[TestContractRow, ...] = ()
        grounding_rows? tuple[GroundingRow, ...] = ()
      }
      
      type MoldSpecFrontmatter {
        slug str
        status str
        source str
        created str
        confidence SpecConfidence
        gate_applicability GateApplicability
        gates_overridden? tuple[str, ...] = ()
        agent_introduced_scope? tuple[str, ...] = ()
        entity_referent_bindings? tuple[Mapping[str, object], ...] = ()
        landing? Landing | None = None
      }
      
      type TestContractRow {
        acceptance_id str
        interface_referent str
        outermost_stable_seam str
        expected_failure str
        mode TestContractMode
        interface_version? str = ''
        matrix_rows? tuple[str, ...] = ()
      }
      
      enum GateApplicabilityDisposition = "red-required" | "not-applicable"
      
      enum GroundingOutcome = "hit" | "miss" | "unavailable"
      
      enum GroundingProbe = "wiki" | "explorer"
      
      enum LandingShape = "single" | "orthogonal_flat" | "stacked_linear" | "diamond_stack"
      
      enum PerLayerGreen = "required" | "tip-only"
      
      enum ReviewFixes = "fold" | "top-up"
      
      enum SpecConfidence = "low" | "medium" | "high"
      
      enum TestContractMode = "tracer" | "contract-matrix" | "guard"
      
      enum UiSurface = "browser" | "non-browser" | "not-applicable"
      
      enum WorkClass = "behavior" | "docs-only" | "refactor-only" | "test-only" | "appearance-only"
      <!-- END GENERATED -->
      
      ## Issue template
      
      ```markdown
      ---
      slug: <slug>-<NNN>
      status: open
      flavor: bug | chore | slice
      parent_spec: <slug>
      ---
      
      # <One-line summary>
      
      ## Context
      <why this exists, in 1–3 sentences>
      
      ## Acceptance
      - AC-1: <bullet — verifiable outcome>
      
      ## Notes
      - <optional caveat or pointer>
      ```
      
      ## Two-phase Curdle for accepted follow-ups
      
      Accepted follow-ups use a local-first two-phase Curdle. Each receives a deterministic follow-up ID composed from the spec slug and its one-based ordinal, for example `mold-follow-up-routing-F001`.
      
      ### Phase one — local write-ahead state
      
      Preserve every existing Curdle by-product: the spec, ADRs, glossary, domain model, and all rejected-direction records. Add a local issue draft for each accepted follow-up that needs a recoverable tracker payload. Before any external call, persist its ID, destination, `prepared` state, and draft reference in `Deferred follow-ups`.
      
      `$SPEC` is the authoritative store for prepared follow-up state because the resolver anchors it in the durable project corpus. Local issue drafts are auxiliary publication payloads, not the authoritative record. Stage and move this complete local set under the existing atomic-write rule before phase two begins.
      
      ### Phase two — external publication and reconciliation
      
      Only units whose approved action is **create/link now** and whose destination is external enter phase two. A local issue draft destination completes as `prepared` in phase one:
      
      - For GitHub Issues, use the host GitHub capability first and `gh` as the portable fallback. Discover repository labels and issue forms instead of assuming them.
      - For roadmap goals, run the owned `/wiki-roadmap` workflow when that skill and its required capability are available. New roadmap creation and extension remain owned by that workflow.
      - Put the deterministic follow-up ID in every published item. On every retry, search for the exact deterministic follow-up ID before creation. If an exact match exists, link it. You SHALL NOT create a duplicate.
      - A reused external item becomes `linked`; a newly published item becomes `created`. Reconcile that state and the final URL or durable roadmap reference into `Deferred follow-ups`.
      - When a capability is unavailable or publication fails, retain the recovery draft. Keep the follow-up prepared. Report the failed action and retry path. Continue without blocking the approved spec.
      
      Finish roadmap publication and all mechanical spec reconciliation before the implementation handoff. Reconciliation records the already-approved result; it does not reopen the design.
      
      ## ADRs (durable by-product)
      
      Write the session's non-obvious decisions as durable ADRs after both handshake keys pass. Include them with the durable spec in phase one's local atomic write. Both stay in the durable project corpus. The spec is the approved implementation contract. The ADRs preserve its rationale. Resolve the corpus **dynamically**. Probe for the consumer's `repo:<their-repo>:wiki` hallouminate corpus. Write there when it exists. Otherwise write a tracked `docs/adr/<slug>-NNN.md`. Never hardcode a corpus name. See [`adr.md`](adr.md) for the full resolution rule and the ADR format.
      
      ## Durable glossary (by-product)
      
      Write resolved canonical terms to `.cheese/glossary/<slug>.md` in the same atomic step as the spec and ADRs. Downstream skills (`/cook`, `/age`, `/press`) read this file for naming consistency. The glossary is the output of the Ground phase's term resolution; it is not reconstructed from the spec.
      
      Format:
      ```markdown
      # Glossary — <slug>
      
      | Term | Canonical meaning | Code referent (file:line or NEW ENTITY) | Avoid |
      | --- | --- | --- | --- |
      | <term> | <one-line definition> | <referent> | <losing synonym, …> |
      ```
      
      The `Avoid` column records losing synonyms that the Ground phase rejected in favour of the canonical term. Separate multiple synonyms with commas. Use `—` when none exist. Omit the file if Ground resolved no terms and no overloaded-term dialogue occurred.
      
      ## Domain model (cumulative by-product)
      
      During the same atomic step as the spec, ADRs, and per-slug glossary, merge the session's resolved terms with their **Avoid synonyms**. Merge them into the project-level domain model. After the Hallouminate probe, resolve the target through the Mold bundle command:
      
      ```text
      python3 skills/mold/scripts/mold.pyz domain-model-target \
        --probe <unavailable|no-match|match> \
        [--corpus repo:<repo>:wiki --model <present|absent|unknown>]
      ```
      
      Pass `unavailable` when Hallouminate is not loaded or the probe failed. Pass `no-match` when the listing completed but contained no `repo:*:wiki` corpus. Pass `match` with the exact corpus name and its model status when the listing found one. The command accepts only these explicit probe results; it does not import or invoke MCP machinery. It emits canonical JSON with `backend`, string `location`, and `wiki_reachable`. Preserve the resolver's wiki, tracked `docs/`, then XDG read precedence and report a `wiki_reachable: false` fallback before writing a file target.
      
      The per-slug glossary is a branch-local handoff. The domain model is cumulative cross-session memory. It builds the project's ubiquitous language across every session. Add only context-specific terms. Never add general programming concepts.
      
      Merge, don't overwrite:
      - **New term** — append an entry.
      - **Changed term** (definition, referent, or Avoid set differs) — update that entry in place.
      
      Entry format:
      ```markdown
      **<Term>** — <definition>.
      _Avoid_: <syn1>, <syn2>
      _Code_: <file:line (or NEW ENTITY)>
      ```
      Omit the `_Avoid_` line when no synonyms were rejected.
      
      **Lazy context-map split.** A single bounded context lives as one `domain-model.md` at the store root. When a **second** bounded context crystallises, split lazily into:
      - `domain-model/index.md` — the context map: the bounded contexts and their relationships (Pocock CONTEXT-MAP shape).
      - `domain-model/<context>.md` — one page per bounded context, each holding that context's entries.
      
      Do not pre-split for a single context. This layout is identical across all three stores selected by the bundle command (wiki, `docs/`, XDG corpus).
      
      ## Rejected-directions store (by-product)
      
      Write the rejection to `.cheese/.out-of-scope/<slug>-NNN.md` when the agent-introduced-scope audit **rejects a direction**. Do the same when the two-key handshake rejects it. Rejections include "drop <term>" for an approach or design knob, and "not that approach." An explicit deferral becomes a follow-up candidate. A rejected direction is not a follow-up candidate.
      
      Format:
      ```markdown
      # Rejected direction — <slug>-<NNN>
      
      ## Direction
      <one-line description of what was rejected>
      
      ## Rationale
      <why it was rejected, in 1–2 sentences>
      
      ## Context
      Session: <slug>; rejected at: <handshake | scope-audit>
      ```
      
      `/cheese` consults this store before it proposes a direction again. See `skills/cheese/SKILL.md` § Rejected-directions check. Do not write ordinary scope boundaries or accepted follow-ups here. Non-goal-only dispositions create no artifact. Accepted follow-ups use `Deferred follow-ups` and any auxiliary `.cheese/issues/` recovery draft. Write only direction-level rejections. These include approaches, design knobs, and named features that the user explicitly declined. Note: this store uses the dot-prefixed path `.out-of-scope`. Its sibling stores, `glossary/`, `issues/`, and `specs/`, do not use dot prefixes. Each scan must explicitly target the dotted path. A bare `.cheese/*` glob does not match it.
      
      ## Spec-verify pass (optional)
      
      Run `/spec-verify` as an independent spec-review pass before the hand-off when the harness provides it. Skip it without a warning when it is absent. Note the absence once. This pass is optional. It must not block Curdle in an environment that does not bundle the skill. Never create a hard dependency on it.
      
      Detect the skill at the instruction level, not in code. Check whether `/spec-verify` appears in the agent's available toolset. Use the pattern in `../../cheese/references/optional-plugins.md` § Probe pattern. Do not use `command -v` or another shell probe. `/spec-verify` is a skill, not a `$PATH` executable.
      
      ## Atomic write
      
      Stage to a temp directory under `${TMPDIR}` first, then move into place. Never leave partial files on a write failure.
      
      ### Write → read-back → completion record
      
      This is the runtime home of the **Durable writes** coherence gate (`handshake.md` § Agent key). The gate locks the commitment before the handshake; this step honours it. For each durable write — every ADR and the domain-model merge — run:
      
      1. **Resolve** the target dynamically. For the ADR, use the resolution procedure in [`adr.md`](adr.md) § Resolution. For the model, run the `domain-model-target` bundle command shown above with the Hallouminate probe result. It emits `backend`, string `location`, and `wiki_reachable`; `False` means that the wiki probe was not consulted because it was unavailable. Thus, its `file` backend is a degraded fallback, not a confirmed absence. This condition triggers the loud fallback below.
      2. **Write** to that target: `add_markdown` when the backend is `hallouminate`, a staged file write when it is `file`.
      3. **Read back** the entry and confirm that it exists. For the wiki backend, use `ground` or `read_markdown`. For the file backend, read the file again. Treat a write that you cannot read back as a failure. Fail loudly, and do not claim the write.
      4. **Record** it in the curdle completion record printed to the user: one line per durable write naming `<artifact> → <location> (<backend>)`.
      
      **Loud fallback.** If hallouminate is unavailable and the resolver degrades to a file backend, state this in one visible line. File backends include `docs/adr/…`, `docs/domain-model*`, and the XDG corpus. Never write silently to files when the author expected the wiki. See the absent-plugin degrade contract in [`../../cheese/references/optional-plugins.md`](../../cheese/references/optional-plugins.md).
      
      ## Pre-approval typed planner dispatch
      
      Before this procedure, run the digest-bound fresh-context fork taste test on the dialogue-state draft. It must pass; failures reopen only named forks, with two correction rounds. Then run the procedure on the draft before the two-key handshake. It prepares the typed plan that the handshake approves; Curdle later persists the host-validated artifacts.
      
      1. **Dispatch** a fresh-context planner on a `PlannerRequest` built from the current draft spec text. The planner returns a `PlannerResultWriterView`; it does not own contract versions, identifiers, digests, lineage, or evidence references.
      2. **Validate and normalize** the writer view on the host. The normal selected path is the typed `PlannerResult` containing a typed `CurdPlan`; reject malformed or wrong-kind output before approval.
      3. **Still invalid after one retry** — stop before the two-key handshake. Do not approve or persist an invalid plan.
      4. **On success**, count semantic curds and waves from the typed `CurdPlan`, then show `N curds / M waves` with the final approval request. The typed plan is part of what both handshake keys approve. When candidate curds are two or more, ask the landing shape once in that same approval request, alongside the curd-independence confirmation.
      5. Persist the approved spec, typed `PlannerResult`, and typed `CurdPlan`. Do not regenerate or mutate them after approval.
      
      ## Finalization
      
      Finalize the approved spec and plan before the hand-off. The host owns three values and sets each one once:
      
      - `REQUEST_ID` is the `request_id` of the `PlannerRequest`. On a path with no planner, use the spec slug.
      - `ARTIFACT_ROOT` is `.cheese/cook/<slug>-artifacts`. Mold and Cook must use the same directory.
      - The operation id is `<slug>-<ordinal>`. Keep it for an identical retry. Increase the ordinal when an input changes.
      
      Record the handshake verb first. Pass the user's reply word for word; a reply that is not an approval records a rejection:
      
      ```bash
      python3 skills/mold/scripts/mold.pyz approve "$SPEC" \
        --artifact-root "$ARTIFACT_ROOT" \
        --request-id "$REQUEST_ID" \
        --kind plan \
        --response "<the user's literal reply>" \
        --planner-result "$PLANNER_RESULT_JSON"
      ```
      
      Use `--kind partial_plan` for a partial planner disposition. On the Light path, use `--kind scope --curd-id <curd-id>` and omit `--planner-result`. The command prints `approval_path`. Then finalize:
      
      ```bash
      python3 skills/mold/scripts/mold.pyz finalize "$SPEC" \
        --approval "$APPROVAL_PATH" \
        --artifact-root "$ARTIFACT_ROOT" \
        --operation-id "<slug>-<ordinal>" \
        --request-id "$REQUEST_ID" \
        --mode full \
        --planner-result "$PLANNER_RESULT_JSON" \
        --taste-result "$TASTE_RESULT_JSON" \
        --ledger "$TASTE_LEDGER_JSON"
      ```
      
      `--taste-result` is the persisted `taste-test` verdict. `--ledger` is the decision ledger as JSON. `--plan` is optional when the `PlannerResult` embeds its plan.
      
      Read `status` in the output, not only the exit status. A nonzero exit status is an input error; stop. `ready` stores a canonical `HandoffPointer` and prints the Cook `command`. `saved-not-ready` exits zero, stores no pointer, and lists each unmet `requirements` entry and hold.
      
      For `ready`, render the ready branch of [`handoff-menus.md`](handoff-menus.md). The printed `command` contains `--auto`; run it only when the user selects an automatic choice. A manual choice uses `/cook <pointer path> --spec "$SPEC"`. For `saved-not-ready`, follow the saved-not-ready branch of the same menu.
      
      ## Hand-off
      
      Do not render this hand-off until phase-two publication attempts and the mechanical `Deferred follow-ups` reconciliation are complete.
      After writing, suggest the next step inline. **Never auto-invoke.**
      
      | Artifact | Suggested next step |
      | --- | --- |
      | Red-required Spec | `/cook --auto <pointer path> --spec "$SPEC"` (add `--hard` when the user passed it) |
      | Spec | `/cook <pointer path> --spec "$SPEC"` (add `--hard` when the user passed it) |
      | Issues | Paste each into your tracker, or `gh issue create --body-file <path>` |
      
    • evals.md 5.7 KB
      # Evals
      
      Trigger and trace tests for `/mold`. Run these against real session transcripts when the skill changes.
      
      ## Should-trigger queries
      
      These prompts must invoke `/mold` (or its router parent `/cheese` must hand off to it):
      
      - "grill the agent-decided items"
      - "let's design a rate limiter for the API"
      - "I'm thinking about adding OAuth support"
      - "what should the schema for the events table look like"
      - "should we do the migration now or wait, thinking about downtime"
      - "/mold rename the `parse_flags` helper to `parse_args` in cli.py" — must trigger, and must land in the **Quick** tier: one confirm, a mini-spec, no fork questions (`tiers.md`).
      
      ## Should-not-trigger queries
      
      These prompts must NOT invoke `/mold`:
      
      - "fix the failing test in auth.ts" — direct implementation, route to `/cook`.
      - "review this diff for bugs" — review-only, route to `/age`.
      - "just thinking out loud, no need to write anything down" — no artifact intent, route to `/culture`.
      - "what does the Stripe API say about idempotency keys" — external research, route to `/briesearch`.
      
      If a should-not query triggers `/mold`, the description in `SKILL.md` is over-broad — tighten it.
      
      ## Trace checks
      
      For every completed `/mold` run, verify first that the tier was announced in one line with its reason before the first fork question, and that any tier change was an announced upgrade, never a silent downgrade (`tiers.md`).
      
      For each completed `/mold` Grill-mode run, verify:
      
      1. **Every grilled item produces a steelman + tension statement before any verdict.** Do not proceed directly to an uphold or amend verdict. Surface the steelman first.
      2. **One user-fork round or more for each consequential grilled item.** Consequential is the leverage line in [`../../age/references/voice.md`](../../age/references/voice.md). Invoke the question primitive at least once for each consequential item. Use `AskUserQuestion` on Claude Code and Conductor. On another harness, use the equivalent in [`ask-user-question.md`](../../cheese/references/ask-user-question.md). Require a real user turn. Never render and answer an `A/B/C/D` block yourself. Never issue a verdict monologue on a consequential item without a user turn. Items below the leverage line are batch-reported as upheld with a one-line steelman and never become a user turn; a user turn spent on one is a regression.
      3. **Amendments surface as questions before ledger entry.** Ask the user about each amendment that a grill produces. Ask before you write the amendment to the per-round decision ledger.
      4. **Clean-steelman batching stays scoped.** Batch-report a consequential item as upheld only when its steelman finds nothing. Never include a consequential item with a live tension in a batch. Below-the-line items always batch, tension or not; the ledger carries their vetoable alternative.
      5. **Every user fork names what it moves.** Each `Asking` entry cites the acceptance criterion, public seam, or non-goal it changes. A fork with no such target is `[AGENT-DECIDED]` or a follow-up candidate, never a question.
      6. **The `Goal:` line survives every round.** The ledger repeats the pinned goal verbatim from the bounds pass to the handshake. A reworded goal traces to an explicit user fork.
      7. **Every `G-n` clause reaches the handshake with a disposition.** The bounds pass prints the clauses. The narrowing delta names each one as covered, follow-up, non-goal, or `[TBD]`. A spec that covers fewer than half the clauses triggers a re-pin-or-widen fork, never a silent proceed.
      
      ## Failure modes to watch for
      
      - **Verdict monologue** — the agent steelmans every item, self-issues uphold/amend verdicts, and presents a finished verdict block with no user turn. This is the regression this eval exists to catch (see issue #279, and the Grill section in `skills/mold/references/modes.md`).
      - **Amendment silently folded into the ledger** — an amendment appears in `Decided` without a prior question to the user. Log as a regression.
      - **Over-batching** — a consequential item with a real tension gets swept into the "batch-reported as upheld" exception meant only for clean steelmans.
      - **Under-batching** — a below-the-line item (naming, internal scope, a trade-off that fires no trigger) gets its own user turn instead of a ledger line.
      - **Altitude drift** — three or more consecutive forks move no acceptance criterion, seam, or non-goal, and the decision map never renders. The rabbit hole this eval exists to catch: every noun traces to the user, so the noun-level scope gates stay green while the dialogue burrows.
      - **Goal fade** — the `Goal:` line drops out of the ledger render or silently rewords. The taste test catches the terminal form as `goal-drift`; the per-round render is the early form.
      - **Quarter build** — the goal sentence survives and every noun traces, but Acceptance delivers a fraction of the clauses and the agent presents the slice as the whole. The pre-check catches the terminal form as `goal-coverage:G-n` or `goal-coverage-cap`; a missing narrowing delta at the handshake is the early form.
      
      ## Mold-to-Cook live trace
      
      Run this scenario with a fresh OMP task agent in an isolated repository. Supply the changed Mold and Cook bundles explicitly.
      
      1. Give the agent a strict, valid spec that needs two curds.
      2. Supply the planner result, taste verdict, and user approval as scripted host events.
      3. Require `mold.pyz finalize`; reject any `publish` command or direct `CurdPlan` hand-off.
      4. Pass the emitted `HandoffPointer` to Cook's preparation command.
      5. Capture actual tool calls, approval events, and final artifact references.
      
      The trace passes only when the bounded transcript checker accepts it and Cook loads the emitted handoff. Missing approval evidence must stop finalization.
      
      ## How to run
      
      These evals are intentionally manual today.
      
    • gate-graph.md 5.9 KB
      # The gate graph
      
      `GATE_MODEL` in `src/easy_cheese/skills/mold/gate_graph.py` holds the one
      canonical model of Mold's gate state machine. `mold.pyz` bundles it as the
      `gate-graph` subcommand. Both render targets derive from that one model, so
      they cannot drift. See ADR-001. The model is also the gate-prose-sync source.
      One test asserts that the handshake coherence-checklist items equal the model's
      gate nodes. No gate can therefore disappear from the prose without a failure.
      
      ## Subcommand
      
      ```bash
      python3 skills/mold/scripts/mold.pyz gate-graph \
        [--state <state.json>] [--render dot|svg|png|mermaid] [--out <path>]
      ```
      
      - `--render dot` (default): canonical Graphviz `.dot` to stdout.
      - `--render mermaid`: a fenced ```mermaid flowchart block to stdout — renders
        natively in GitHub and markdown viewers, **no binary required**.
      - `--render svg|png`: shells out to Graphviz `dot` when it is on PATH; pass
        `--out <path>` for binary targets. When `dot` is absent it **degrades to
        mermaid** and prints a note to stderr — run-anywhere by construction.
      - `--state`: an optional Mold `state.json`. The command validates its shape.
        The gate model stays static, so the state does not change the graph today.
      
      ## When to use it
      
      - Onboarding a contributor to mold's flow — one picture of modes → gates →
        handshake → curdle.
      - Auditing that the prose checklist and the enforced gates still agree (the
        gate-prose-sync test is the automated form; the rendered graph is the human
        form).
      - Embedding the mermaid block in a doc or PR description where no Graphviz
        toolchain exists.
      
      ## Why dual-render from one model
      
      Requiring Graphviz would break run-anywhere (it is absent on many machines,
      including the dev box). Mermaid-only would lose the canonical `.dot` /
      enforcement angle. Emitting both from one in-memory model keeps zero hard
      dependency *and* keeps the two targets in lockstep — the no-drift guarantee is
      structural, not a convention someone has to remember.
      
      ## Snapshot
      
      `skills/mold/scripts/mold.dot` is the committed canonical `.dot`. A test asserts
      it byte-matches `to_dot()`, so the snapshot can never go stale against the model.
      Regenerate it whenever the model changes:
      
      ```bash
      python3 skills/mold/scripts/mold.pyz gate-graph --render dot \
        --out skills/mold/scripts/mold.dot
      ```
      
      ## The non-goals gate
      
      One coherence gate is worth calling out on its own: `non-goals-audit` (rendered
      `non_goals_audit` in the `.dot`; label *Non-goals audit: every bullet traces to a
      user-stated out-of-scope item or is marked [AGENT-INTRODUCED]*). Like every gate
      node it feeds the handshake and is kept in lockstep with the `handshake.md`
      checklist. It makes the most consequential lean — narrowing scope via `Non-goals`
      — a first-class, testable gate rather than a prose-only check (ADR-002). The
      audit procedure lives in `handshake.md` § Non-goals audit.
      
      ## The goal coverage gate
      
      `goal-coverage` (rendered `goal_coverage` in the `.dot`) is the subtraction
      sibling of `non-goals-audit`. The noun audits catch scope the agent added; this
      gate catches scope the agent dropped. The bounds pass splits the pinned goal
      into `G-n` clauses and records them in the ledger as `goal_clauses`. The taste
      pre-check then reads each clause's disposition from the draft alone: `covered`
      when an Acceptance line carries the tag, `non-goal` / `follow-up` / `tbd` when
      the matching section carries it, `uncovered` otherwise. An uncovered clause
      fails `goal-coverage:G-n`. Fewer than half covered fails
      `goal-coverage-cap:<covered>/<total>` and forces a re-pin-or-widen fork.
      `taste-test --coverage` prints the disposition map for the narrowing-delta
      line. Procedure: `handshake.md` § Goal coverage.
      
      ## Fork taste planner gate
      `fork_taste_test_passed` is the only edge into the typed planner stage. Mold
      hashes the exact draft before it accepts a verdict. The strict
      `ForkTasteVerdict` must cover each settled consequential decision exactly once.
      
      The verdict fails for a stale digest, missing reflection, contradiction, orphan, unsupported assumption, or acceptance gap. A semantic `pass` with blockers also fails.
      
      The ledger JSON may carry the pinned goal as a top-level `goal` string beside `forks`; a blank or non-string `goal` is a ledger error, `ledger-goal-empty`. The draft's goal section is the first heading, at any level, whose text after case-folding and punctuation stripping is exactly `Problem statement`, `Problem`, or `Goal`; a heading with extra words such as `## Goal alignment` or `## Problem statement (v2)` is not the goal section, and a later goal heading never overrides the first. That section must contain the pinned sentence unchanged, compared case- and whitespace-insensitively. A reworded or dropped goal fails as `goal-drift`. A missing or unrecognised goal heading fails as `missing-section:goal:problem`. A ledger without `goal` skips the check. This is the zoom-out gate: the goal the user pinned in the bounds pass is the goal the spec ships. The devil in the details changes Acceptance or an Interface sketch; cruft changes neither, and a fork that changes neither never reaches the user.
      
      The required reflection set depends on the disposition. A `red-required` draft requires Approach, Interface sketches, Acceptance, and Test Contracts. A `not-applicable` draft requires the first three reflections. The applicability gate prohibits Test Contracts in a `not-applicable` draft.
      
      The lexical pre-check (`taste-test --precheck`) runs the deterministic sub-checks (section presence, fork-id or decision-text mention, goal drift, applicability) against the draft alone. It runs before the reviewer dispatch. It does not count toward the two correction rounds. The full `taste-test` with `--verdict` repeats the same checks on the digest-bound verdict.
      
      A third failure stops typed planning and the two-key handshake.
      
      The automatic handoff is `/cook --auto <pointer path>`. It passes the published pointer and the approved metadata without changes. This metadata includes applicability, contract, and taste data.
      
    • grounding.md 5.3 KB
      # Grounding — hallouminate wiki probe
      
      Probe the current repository's wiki corpus at **Ground** phase entry. Probe only when hallouminate is available. Also probe at decision points in any Dialogue mode before you ask the next question. See § When to probe. Add each matching rationale entry or ADR entry to the evidence base.
      
      Record one named probe outcome in the ledger for every probe. The outcome is `hit`, `miss`, or `unavailable`. Record `hallouminate: absent` once when the tool is missing. Then continue with diff evidence and code evidence only.
      
      The `grounding-recorded` coherence gate blocks the first structured question until the ledger carries a probe outcome. The outcome carries citations, or it names the reason for the absence. Keep the degrade path cheap and visible.
      
      Do not map the topic outcomes to `domain-model-target` arguments.
      Use the domain-model probe transport in [`../../cheese/references/optional-plugins.md`](../../cheese/references/optional-plugins.md).
      
      ## Probe shape
      
      The probe mirrors the wiki probe pattern in the detect-and-degrade contract. See [`../../cheese/references/optional-plugins.md`](../../cheese/references/optional-plugins.md).
      
      ```pseudocode
      ground_wiki(topic, repo_name, session_corpus):
        # 1. Check hallouminate availability.
        if "mcp__hallouminate__list_corpora" not in available_tools:
          record once: "hallouminate: absent (tool not loaded)"
          return unavailable
      
        # 2. Select the corpus for THIS repository. Reuse the session selection.
        if session_corpus is None:
          corpora = mcp__hallouminate__list_corpora()
          matches = [c for c in corpora if c == "repo:" + repo_name + ":wiki"]
          if len(matches) != 1:
            record once: "hallouminate: unavailable (no wiki for " + repo_name + ")"
            return unavailable
          session_corpus = matches[0]
      
        # 3. Ground the topic.
        results = mcp__hallouminate__ground(query=topic, corpus=session_corpus, limit=5)
        record: "hallouminate: hit" with citations, or "hallouminate: miss"
        return results
      ```
      
      - Derive `repo_name` from the configured origin remote.
        Use the host-reported repository root name only when no origin exists.
      - Match the corpus name exactly. Never select the first `repo:*:wiki` entry. A different repository's wiki carries another project's private rationale.
      - Record `unavailable` when zero corpora match. Record `unavailable` when more than one corpus matches. Never guess between two candidates.
      - Never block the dialogue on the probe. An `unavailable` outcome satisfies the gate.
      - Retain `session_corpus` for one Mold episode. Repeat discovery only after an `unavailable` outcome or a registry change.
      - State the absence once for each run. Write it to the ledger once. Do not repeat it for each question.
      
      ## When to probe
      
      Probe at **Ground** phase entry. In other Modes (Shape/Sketch/Grill), probe at decision points before the next question when any condition applies:
      
      - The dialogue is about to decide a consequential fork whose options could have prior rationale (e.g. "why not X").
      - Probe when the wiki can possibly answer the next user question. Examples include a settled decision, an ADR, or a recorded convention.
      - The dialogue is about to restate rationale for an existing system or module that may have ADRs.
      - The spec being molded overlaps with a prior mold session in this repo.
      
      Skip the probe in pure Explore mode when there is no named system. Also skip it in Diagnose mode. Diagnose evidence comes from code and logs, not rationale documents.
      
      Cite hits in that round's decision ledger under `Decided / Asking / [AGENT-DECIDED]`. See `../SKILL.md` § Rules. Put a settled wiki decision under `Decided` and cite its wiki page. Do not reopen it as a new question.
      
      ## Prior-evidence fast path
      
      A session can start with prior evidence. Sources include a `/culture` synthesis, a `/briesearch` report, or a `.cheese/notes/<slug>.md` wheypoint. Sources also include an earlier Mold draft or an ADR. Read this evidence once during the Bounds pass. Add each settled item to the ledger. Do not derive settled items again in the parent context.
      
      An item **covers** a decision only when all three conditions apply:
      
      - **Cited.** The item names evidence that a reader can check. Use a path and symbol, line range, wiki page, or dated URL.
      - **Fresh.** The citation resolves at the current HEAD. Probe the evidence again when a referent moved, changed its name, or no longer exists.
      - **Decisive.** The item names the decision that it settles. A topic alone does not settle a decision.
      
      Put covered items under `Decided`. Include the source artifact and citation, such as `via: .cheese/notes/<slug>.md`. Run the normal pass for each uncovered item. The fast path skips work. It never skips a gate. It cannot skip the two-key handshake or fresh-context taste test. It also cannot skip a consequential fork that the user did not select.
      
      Record the intake result for each session. Record `prior evidence: none` when the session starts with no prior evidence. This intake record is not a probe outcome. It does not satisfy `grounding-recorded`. Run the wiki probe and record its outcome separately.
      
      ## Confidence when absent
      
      If hallouminate is absent and design rationale is central to the current question, cap the result at `speculating`. Note this limit inline. See [`../../cheese/references/optional-plugins.md`](../../cheese/references/optional-plugins.md) for the full degrade contract.
      
    • handoff-menus.md 3 KB
      # Handoff branch menus
      
      Read this when rendering `/mold`'s post-Curdle handoff. The `curd-count` digest
      is advisory sizing; finalization owns readiness and execution authority.
      
      - A `ready` finalization result carries a consumer-valid pointer. A
        `saved-not-ready` result carries only durable preparation requirements and
        holds, so render no pointer command and no automatic command. Show each
        requirement and hold. Cook does not read these saved requirements, so offer
        **Let Cook prepare the spec** — `/cook --spec "$SPEC"` only when the result
        has no hold and every requirement `kind` is `approval`, `scope`, or `plan`.
        Cook preparation then asks for each missing plan and approval. For any other
        requirement, such as a failed taste verdict, render no Cook choice.
      - For a ready result, a non-null `handoff` means `red-required`; a null
        `handoff` means closed `not-applicable` or legacy input. Both route to Cook
        with the canonical pointer from finalization: auto choices use
        `/cook --auto <pointer-path> --spec "$SPEC"` and manual choices use
        `/cook <pointer-path> --spec "$SPEC"`.
      
      Then render the branch selected by `mode`:
      
      **Decomposable specs (`decomposable: true`, `candidate_curds ≥ 2`, `mode: parallel`):**
      
      - **Run the full pipeline (parallel fan-out when disjoint, else linear)** *(recommended)* — use the disposition-selected auto command above. Cook later uses the approved curds to select parallel or linear execution; `/plate` publishes the selected ordinary or stacked layout.
      - **Implement manually, one phase at a time** — use the disposition-selected manual command above.
      - **Stop** — dispatch none; leave the spec for later.
      
      **Non-decomposable, high-blast-radius specs (`decomposable: false`, verdict `high` only, `mode: linear`):**
      
      - **Run the full pipeline in fresh-context isolation** *(recommended)* — use the disposition-selected auto command. Red-required behavior continues `cook → press → age → cure → age → cure → age`; closed N/A skips Press and continues `cook → age → cure → age → cure → age`.
      - **Implement manually, one phase at a time** — use the disposition-selected manual command.
      - **Compact and resume by hand** — dispatch none; clear context, then use the disposition-selected manual command. `/cheese --continue` scans phase handoff slugs, so a fresh spec must be resumed through its explicit path.
      - **Stop** — dispatch none; leave the spec for later.
      
      **Non-decomposable, low- or medium-blast-radius specs (`decomposable: false`, verdict `low` or `medium`, `mode: null`):**
      
      - **Implement the spec** *(recommended)* — use the disposition-selected manual command.
      - **Implement and auto-review** — use the disposition-selected auto command. Opening or updating a PR remains `/plate`'s explicit step.
      - **Research more first** — `/briesearch`.
      - **Stop** — dispatch none; leave the spec for later.
      
      `mode: parallel|linear` selects fresh-context Cook execution; `mode: null` selects the smaller in-session path. The user must still opt into `--auto`.
      
    • handshake.md 22.1 KB
      # The two-key handshake
      
      Curdle (artifact extraction) requires **both** keys. Neither is optional.
      
      ## User key
      
      The user key shows explicit extraction intent: approval to write the spec. The direct form is `curdle`. `ship it`, `extract`, or `that's enough` have the same effect. A clear affirmative also turns the key when it directly answers an agent's extraction question. Examples include `ok let's go`, `sounds good`, and `go ahead`.
      
      Judge the key by intent, never by spelling. Capitalization, surrounding whitespace, or punctuation never invalidate otherwise-clear approval. Never demand an exact respelling or a magic string. Do not infer the key from unrelated or ambiguous approval. Ask explicitly when the context does not establish that the user approves Curdle.
      
      ## Agent key — coherence self-check
      
      Print this checklist and require every box checked before extraction (or an explicit `curdle anyway` override):
      
      ```
      Coherence self-check before curdle:
      - [ ] Problem statement: grounded, agreed
      - [ ] Grounding recorded: a wiki probe result — citations or an explicit hallouminate-absent note — preceded the first structured question
      - [ ] At least 2 options weighed (Do Nothing included)
      - [ ] Chosen option grounded in codebase evidence
      - [ ] Exploration delegated: evidence-heavy reads carry an explorer digest, or the parent-context fallback is recorded
      - [ ] Interface sketches: Placement block complete (slice, spine step, public interface, private, crust delta, arrows)
      - [ ] Cross-module calls go through public interfaces, not internals
      - [ ] Identity nouns: each bound to a code referent or marked NEW ENTITY (an ALIAS must be resolved, not just noted)
      - [ ] Non-goals audit: every bullet traces to a user-stated out-of-scope item or is marked [AGENT-INTRODUCED]
      - [ ] Goal coverage: every G-n clause is covered by an AC or carries an explicit disposition, at least half ship, and the narrowing delta is printed
      - [ ] Validate cycles: all launched cycles judged
      - [ ] Chosen option Grilled (≥1 stress-test entry per major branch)
      - [ ] Open questions all marked [TBD] / [BLOCKED] / [?] (none silent)
      - [ ] Quality gates specified (≥1 runnable command)
      - [ ] Reproduction loop captured if Diagnose ran (or [BLOCKED] if no loop is possible)
      - [ ] Durable writes: ADR + domain-model targets resolved and the write, read-back, and completion-record protocol committed for the atomic step (or loud fallback noted)
      - [ ] Fork taste test passed: fresh-context verdict covers every settled consequential decision before typed planning
      - [ ] Spec format valid: validate-spec --strict exits 0 on the draft
      ```
      
      If any box is unchecked, name it and propose the smallest move to fill it. The user can override with `curdle anyway`.
      
      The last box — **Durable writes** — is a commitment checked before the handshake. It does not claim that the write already occurred. It confirms that the ADR + domain-model targets are resolved. It also locks in the write → read-back → completion-record protocol for the atomic-write step (`curdle.md` § Atomic write). The read-back verification and visible completion record occur during that step. Note the hallouminate-absent fallback clearly, never silently.
      
      These checklist items match the gates in Mold's machine-readable gate model. See `gate-graph.md`. A passing `fork_taste_test_passed` verdict opens the typed planner stage. A stale, partial, contradictory, or blocker-bearing verdict keeps typed planning closed. A test compares this checklist with the model nodes. Edit both sources together. Render the flow with `python3 skills/mold/scripts/mold.pyz gate-graph`.
      
      ## Mandatory gates
      
      These are not soft suggestions — Curdle hard-blocks until they are addressed:
      
      - **Ground gate:** ≥1 Ground pass with a citation before Shape's options. Exception: pure greenfield (the agent must say so out loud).
      - **Shape gate:** ≥1 Option block weighed (Do Nothing counts).
      - **Sketch gate:** mandatory when the chosen option touches more than one module or introduces a new public interface. Skip only for trivial single-function changes (the agent must say so out loud).
      - **Grill gate:** mandatory for high-blast-radius decisions. The shape check (`shape-check.md`) ranks blast radius `low | medium | high` from semantic caller search and `tilth_deps` when available. A `high` verdict — multi-module callers or more than five importers — makes Grill mandatory.
      - **Open hypotheses:** any Validate Cycle launched but unjudged blocks Curdle unless the user accepts it as `[TBD]`.
      - **Agent-introduced scope:** every distinguishing noun in the spec must trace to a user-typed mention or carry an approved scope-audit row. See the full procedure in § Agent-introduced scope below. Curdle is the single chokepoint because downstream skills trust the resulting frontmatter and do not re-block.
      - **Entity-referent binding:** bind every identity noun to a code referent or mark it NEW ENTITY. Resolve each ALIAS; do not only note it. See the full procedure in § Entity-referent binding below.
      - **Non-goals audit:** every `Non-goals` bullet traces to a user-stated out-of-scope item or is marked `[AGENT-INTRODUCED]`. Full procedure in § Non-goals audit below.
      - **Goal coverage:** every `G-n` goal clause from the bounds pass is covered by an Acceptance criterion or carries an explicit disposition. At least half the clauses ship. The handshake prints the narrowing delta. `curdle anyway` does not waive this gate. Full procedure in § Goal coverage below.
      - **Fork taste test:** Require a fresh-context verdict before decomposition. Dispatch the verdict to a read-only `reviewer (taste-test)` at `default` / `medium`, resolved through `../../cheese/references/agent-resolution.md`. The verdict must match the draft SHA256. It must cover each settled consequential decision exactly once. It cannot contain contradictions, orphaned decisions, unsupported assumptions, or acceptance gaps. When the ledger pins a `goal`, the draft's Problem statement must contain it unchanged, compared case- and whitespace-insensitively, or the verdict fails as `goal-drift`. Hand the reviewer the ledger's `goal` and `goal_clauses` with the draft, so its Drift lens judges the spec against the original ask and not against the already-narrowed draft. Mold permits the initial verdict and two corrective rounds. A third failure stops the process. Before the reviewer dispatch, run `taste-test --precheck` on the draft and ledger. Fix every mechanical gap it reports; the pre-check consumes no correction round.
      - **Spec format gate:** Run `validate-spec --strict` on the draft before Curdle extracts it. The command must exit with status 0. Curdle writes only the current hardened format. It does not use the legacy read grace period.
      - **UI surface classification:** every Mold-produced spec carries a provenance
        marker and an explicit `ui_surface` value under `gate_applicability`.
        `browser` requires an existing browser/E2E interface and outer seam for every
        Test Contract; `non-browser` is explicit and never inferred from prose;
        closed non-behavior work, including appearance-only, uses
        `not-applicable`. The taste and curd gates enforce this field without
        changing legacy specs.
      
      ## Scope audit table
      
      The agent-introduced scope, non-goals, entity-referent, and follow-up audits below populate **one table, presented once, before the handshake**. Each row carries a default disposition. One confirm of the table approves every default except the rows marked `needs your verb`. A row needs its own explicit verb only when it fires a leverage trigger (`../../cheese/references/routing-policy.md` § Leverage triggers) or is an unresolved ALIAS / NEW ENTITY binding. A row fires a trigger when the term, bullet, or noun it names would itself fire one of the eight ids if kept: an auth knob fires `auth`, a new export fires `contract`, a new domain fires `new-slice`. Such a row renders `needs your verb` in its Default cell, and the confirm never covers it. The grep and semantic search that populate the rows still run; the per-row approval round does not.
      
      ```
      Scope audit:
      | # | Kind | Term / bullet / noun | Source | Default | Leverage |
      | --- | --- | --- | --- | --- | --- |
      | 1 | scope | <noun> | agent / citation | keep | — |
      | 2 | non-goal | <bullet> | agent | keep | — |
      | 3 | entity | <noun> | search | Bound <referent> | — |
      | 4 | follow-up | <unit: member, member> | dialogue | non-goal only | — |
      | 5 | scope | <noun> | citation | needs your verb | contract |
      | 6 | entity | <noun> | search | needs your verb (ALIAS <referent>) | — |
      Confirm the table to accept the defaults. Rows marked `needs your verb` block until you name a verb for each.
      ```
      
      Curdle runs the table as the terminal backstop. It remains the single chokepoint that downstream skills trust (RC3).
      
      ## Agent-introduced scope
      
      Before curdle, audit the draft spec for features the user did not type the name of.
      
      Procedure:
      
      1. Extract distinguishing nouns from the spec's `Approach`, `Decisions`, and `Interface sketches` blocks. Include proper-noun-like terms, library names, algorithm names, Greek parameter letters, config keys, and knobs.
      2. For each noun, grep the prior user turns for a literal mention. Search only the user's typed messages, not agent or sub-agent output.
      3. **Any noun with zero hits is agent-introduced.** Mark it `[AGENT-INTRODUCED]` inline in the draft and add a `scope` row to the scope audit table. Default `keep` when the noun restates the user's ask or binds to a code referent, `follow-up` when it names new work, `drop` otherwise.
      
      4. **One confirm of the table approves the defaults.** A row that fires a leverage trigger needs its own verb: "keep <term>", "drop <term>", or "make <term> a follow-up". "Make <term> a follow-up" records a candidate within `Decided`. This choice does not create an issue or other artifact.
      5. **When a direction is dropped**, whether the user typed the verb or confirmed a `drop` default, write a rejection record to `.cheese/.out-of-scope/<slug>-NNN.md`. A direction can be an approach, design knob, or named feature that the user declines. Use the format in `curdle.md` § Rejected-directions store. Do not make a rejected direction a follow-up candidate. Add explicit deferrals to the follow-up candidate set instead.
      6. Do not silently promote a flagged term from a research citation into a design knob. This applies to briesearch sub-agent citations, fetched docs, and MCP results. The citation is evidence, not a mandate. See `skills/briesearch/references/synthesis.md` § Alternatives are open questions.
      
      This gate exists because research sub-agents have historically over-synthesised. For example, a Tavily snippet mentioning "X or Y" became a shipped `[setting].knob = "x" | "y"` flag. The flag passed through curdle → cook although the user never typed the distinguishing noun. The grep heuristic detects this type of drift early.
      
      Curdle is the single chokepoint for this gate. Downstream skills (`/cook`, etc.) trust the spec frontmatter and do not re-block. Record approved-but-flagged terms in spec frontmatter as `agent_introduced_scope: [<term>, …]`. This record preserves the paper trail.
      
      ## Non-goals audit
      
      `Non-goals` narrows scope — it removes work the user may have wanted without ever asking. That makes it the single most consequential lean, and the existing drift gates never audited it (they read only `Approach / Decisions / Interface sketches`). This gate guards it, as a sibling of Agent-introduced scope.
      
      Procedure:
      
      1. For each `Non-goals` bullet, grep prior user turns for a statement that puts the item out of scope. Search only the user's typed messages. Examples include "don't bother with X", "leave Y alone", and an explicit deferral.
      2. **Any bullet with no such user statement is agent-introduced.** Mark it `[AGENT-INTRODUCED]` inline and add a `non-goal` row to the scope audit table with default `keep`. Non-goals that the bounds pass authored as `[AGENT-DECIDED]` are agent-introduced by definition and enter the table the same way. The user keeps, drops, or rewords it by confirming or editing the row.
      3. Record approved-but-flagged non-goals in the same `agent_introduced_scope` frontmatter list, so the paper trail survives downstream.
      4. Add every audited non-goal to the follow-up candidate set, including approved `[AGENT-INTRODUCED]` bullets. Candidate status preserves the scope boundary without accepting future work.
      
      This audit is the `Non-goals audit` coherence gate. It is the `non_goals_audit` node in the gate model (`gate-graph.md`). Populate its rows as non-goals are proposed; present them once, in the scope audit table. Curdle reruns it as the terminal backstop and hard-blocks extraction until every bullet traces to the user or has an approved `[AGENT-INTRODUCED]` row.
      
      ## Goal coverage
      
      The noun-level gates catch additions. This gate catches subtractions. A spec can keep the goal sentence verbatim, pass every noun audit, and still ship one quarter of the ask. The remaining three quarters vanish through a narrow Acceptance section, never through a `Non-goals` bullet. The goal-coverage gate makes every cut visible and puts a floor under it.
      
      Procedure:
      
      1. **Decompose in the bounds pass.** Split the pinned goal into 2–6 outcome clauses, `G-1` … `G-n`. Each clause names one observable outcome the user asked for. Print the clauses under the `Goal:` ledger line in round one, and repeat them each round. Only an explicit user fork adds, removes, or rewords a clause. Record them in the ledger JSON as `goal_clauses: [{id: G-n, text: ...}, ...]`.
      2. **Tag the draft.** Every Acceptance line that delivers a clause carries its tag, for example `- AC-2: WHEN ... THE SYSTEM SHALL ... (F-1, G-2)`. A clause the spec does not deliver carries its tag on exactly one disposition line instead: a `Non-goals` bullet, a `Deferred follow-ups` entry, or an `Open questions` item marked `[TBD]`. Acceptance wins when a tag appears in more than one place.
      3. **Run the check.** `python3 skills/mold/scripts/mold.pyz taste-test --precheck --draft <draft> --ledger <ledger>` fails `goal-coverage:G-n` for each clause with no tag in any of those four sections. It fails `goal-coverage-cap:<covered>/<total>` when fewer than half the clauses are covered by Acceptance. Both codes also fail the digest-bound verdict.
      4. **Print the narrowing delta.** Before the handshake, run `python3 skills/mold/scripts/mold.pyz taste-test --coverage --draft <draft> --ledger <ledger>` and print one line: `Original ask: G-1..G-n. This spec ships: <covered>. Deferred: <G-n (follow-up)>, <G-n (non-goal)>, <G-n (tbd)>.` The delta is the visible cut list. A spec with no deferred clause prints `Deferred: none`.
      5. **Respect the cap.** When `goal-coverage-cap` fires, the spec is a slice of the goal. Do not proceed. Put one fork to the user: **re-pin** the goal to the slice (the ledger `Goal:` line and clauses change through an explicit user fork), or **widen** the spec until at least half the clauses are covered. Never rename a slice as the whole.
      6. **No override.** `curdle anyway` accepts unchecked coherence items. It does not waive an uncovered clause or the cap, for the same reason it does not waive a leverage row: downstream skills trust the spec and never re-check.
      
      The disposition the spec records on each deferred clause feeds the scope audit table. A `non-goal` disposition enters as a `non-goal` row; a `follow-up` disposition enters as a `follow-up` row. Record the final disposition map in spec frontmatter as `goal_coverage: {G-1: covered, G-2: follow-up, ...}` so the paper trail survives downstream.
      
      This gate exists because the agent-introduced-scope and non-goals audits ask *did the user type this*. Neither asks *did the spec keep everything the user typed*. Agents narrow an ask by building the first tractable quarter and describing it as the whole. The goal sentence survives, the nouns all trace, and the Acceptance section is one quarter the size it should be. The coverage matrix reads the cut from the Acceptance section and the cap refuses a spec that is mostly cut.
      
      ## Follow-up disposition (inside the non-goals audit)
      
      Before the two-key handshake, dispose of every follow-up candidate in one batch: the `follow-up` rows of the scope audit table. This process extends the existing `Non-goals audit` gate. It does not add or rename a gate. The default destination is **non-goal only**; every other destination is a user edit on the row.
      
      1. Group related candidates into independently deliverable units. Each unit is one `follow-up` row whose cell lists its members; confirming the table accepts the grouping, and the user splits or merges by editing the row.
      2. Search GitHub Issues and Hallouminate roadmap goals when discovery is available. A semantic match is surfaced on the row as a recommended `link #<id>`, not adopted as the default: the default destination stays non-goal only, and the user adopts the link by editing the row.
      3. Recommend one destination per unit:
         - **non-goal only** — keep the scope boundary, create no follow-up artifact, and offer no action choice;
         - **GitHub Issue** — use for discrete, independently actionable work;
         - **roadmap goal** — use for coordinated, milestone-scale, or dependency-linked work;
         - **local issue draft** — use when publication is not desired or available.
      4. The user approves the destination by confirming the row's default or editing it. An edited destination also names the action: **create/link now** or **leave prepared**.
      5. Record accepted units for Curdle. Keep rejected design directions in the rejection store. Do not add them to this batch.
      
      The user approves grouping, splitting, semantic-match reuse, destination, and action choices by confirming the table's defaults or editing the rows. Mold settles none silently; every default is visible in the table. Omit this batch when no candidates exist. Preserve the current handshake and Curdle flow.
      
      Record each candidate within `Decided` as `[FOLLOW-UP?]`. Include its summary, source, and rationale. A follow-up candidate is dialogue state only. It does not create an artifact or future commitment.
      
      After both keys pass, Curdle writes local artifacts first. It then publishes approved follow-ups. It reconciles their state and references into the durable spec. It only then renders the implementation handoff.
      
      ## Entity-referent binding
      Before curdle, audit the draft for **identity/ownership-role nouns**. These nouns identify roles that hold, own, span, or claim state or lifecycle. Examples include owner, run, session, claim-holder, coordinator, worker, lease, tenant, and lock-holder. The role triggers the audit, not a fixed word list. Flag domain-specific identities. Do not flag plain value nouns such as formats, algorithms, or config knobs.
      
      The mechanism is semantic symbol search, one query per identity noun, following the [shared routing contract](../../cheese/references/code-intelligence-routing.md). The gate is *not* "did search find something" — it is a three-way verdict on what search returns:
      
      | Search outcome | Verdict | Action |
      | --- | --- | --- |
      | Symbol whose shape matches the design's assumed role | **Bound** | record code referent + `file:line` citation |
      | Symbol of a different shape/referent (aliasing) | **ALIAS** | state the divergence; resolve by renaming to the real entity or designing the intended one |
      | No symbol | **NEW ENTITY** | add a spec section designing it |
      
      Procedure:
      
      1. Extract identity/ownership-role nouns from the spec's `Approach`, `Decisions`, and `Interface sketches` blocks.
      2. Search each noun and classify it `Bound` / `ALIAS` / `NEW ENTITY` per the table above.
      3. Add one `entity` row per identity-role noun to the scope audit table. A `Bound` row needs no approval; an `ALIAS` or `NEW ENTITY` row blocks until resolved. The binding detail reads:
      
         ```
         Entity-referent binding check:
         | design noun | code referent | citation | divergence note |
         | --- | --- | --- | --- |
         | run | ALIAS — make_run_id (one dispatch) | — | code `run` is one dispatch, not a session; design assumed a session spanning siblings (a search *hit* of the wrong shape) — state the divergence, rebind to the real entity |
         | session | NEW ENTITY | — | no symbol; the coordinator session the design needs must be designed |
         ```
      
      4. **An unresolved binding hard-blocks curdle**, exactly as an unapproved `[AGENT-INTRODUCED]` noun does. A search *hit* does not resolve the binding. Determine whether the design's usage differs from the code's existing meaning of the same word. If it differs, state and settle the aliasing before extraction.
      
      This gate is the referent-level sibling of Agent-introduced scope. That gate asks *did the user type this noun*. This gate asks *does the code have it, with the assumed shape*. One example shows why the gate exists. A fully handshook spec declares its goal-claims "owned by the run/session". The code's `run` names one task dispatch, not a coordinator session. The aliased noun then reaches a re-age blocker and a cure-pass-2 design decision that belongs in Mold. Curdle is the single chokepoint. Downstream skills (`/cook`, etc.) trust the spec frontmatter and do not re-block. Record bound and flagged nouns in frontmatter as `entity_referent_bindings: [{noun, verdict, referent, citation, note}, …]`. Use a list of binding records. Preserve the referent and promised `file:line` citation in this record.
      
      ## Override semantics
      
      `curdle anyway` permits one durable save when the agent coherence key is
      unchecked. It does not grant execution authority and does not disable later
      gates. Record the override and every unchecked item in the spec frontmatter.
      It accepts every other default.
      Finalization returns `saved-not-ready` with a preparation hold; it must not
      publish a pointer or an automatic Cook command until the requirements are
      cleared through fresh approval. The override does not waive the scope-audit
      leverage rows, unresolved identity bindings, failed taste, stale references,
      invalid landing IDs, an uncovered `G-n` clause, the goal-coverage cap, or a
      user do-not-implement hold. Downstream skills trust the saved preparation
      result and never reinterpret the override as approval.
      
      ## Why both keys
      
      The user knows their intent; the agent knows the dialogue's coherence. Either one alone produces drift — user-only writes incoherent specs; agent-only writes specs the user didn't actually want.
      
    • mini-spec-mode.md 5.6 KB
      # Agent-invoked mini-spec mode — full procedure
      
      Read this when `/mold` uses agent-invoked mini-spec mode. This mode is the tier-1 escalation from `/cheese`, per `SKILL.md` § Agent-invoked mini-spec mode. It provides the full procedure, mini-spec schema, and `## Provenance` rules.
      
      1. **Derive slug** from the user's ask (kebab-case noun-phrase, ≤ 4 words).
         Check the leverage triggers in `../../cheese/references/routing-policy.md` first. A mini-spec always carries `leverage: []`. When any trigger fires, refuse the mint, name the trigger ids, and return the ask to `/cheese` for `/mold`'s user mode.
      2. **Write the resolver-owned `<spec-path>`** with the mini-spec schema below. Resolve it via `python3 skills/mold/scripts/mold.pyz artifact-path specs <slug>`. Never hardcode a repo-local spec path: the resolver anchors it at the durable corpus, matching the Curdle step.
      3. **Validate the minted spec** with `python3 skills/mold/scripts/mold.pyz validate-spec --strict <spec-path>`. Stop on a nonzero exit; no malformed or legacy-compatible artifact advances to Cook.
      4. **Return the resolved spec path** to `/cheese`: every disposition dispatches `/cook --auto <spec-path>`. Return the full resolver path, never a bare slug.
      5. **Append `--hard`** to that command when the user passed the flag. Every disposition carries it. Plate alone runs the gate.
      
      The two-key handshake does not fire in this mode. The agent-introduced-scope check still runs implicitly. Every distinguishing noun in the mini-spec must come from the user's input or the tier-2 `/culture` or `/briesearch` synthesis. Record that synthesis in `## Provenance`. Never add any other noun. The mini-spec records only the user's request. It never records the agent's interpretation.
      
      ## Mini-spec schema
      
      Mini-spec mode always writes `shape: single`, so `landing.layers` stays `[]`. Do not add an inline `#` comment inside the `landing` block. The front-matter reader keeps the comment as part of the value.
      
      ```markdown
      ---
      slug: <kebab-slug>
      status: draft
      source: agent-mini-spec
      created: <YYYY-MM-DD>
      confidence: <low | medium | high>
      intent: <one-sentence restatement of the user's ask>
      blast_radius: low | medium | high
      leverage: []
      inputs: <one-line>
      outputs: <one-line>
      agent_resolution: []
      gate_applicability:
        disposition: red-required | not-applicable
        work_class: behavior | docs-only | refactor-only | test-only | appearance-only
        ui_surface: browser | non-browser | not-applicable
        reason: <required only for not-applicable>
      landing:
        shape: single | orthogonal_flat | stacked_linear | diamond_stack
        layers: []
        per_layer_green: required | tip-only
        review_fixes: fold | top-up
      verification: <one-line: the obvious check>
      ---
      
      ## Contract
      <one paragraph: behavior change, scope boundary>
      
      ## Grounding
      
      Add exactly one row for each probe. Record the real outcome. Never invent a row.
      
      | Probe | Outcome | Evidence |
      | --- | --- | --- |
      | wiki | <hit \| miss \| unavailable> | <wiki path and one-line finding, or what was attempted> |
      | explorer | <hit \| miss \| unavailable> | <explorer digest path and one-line finding, or what was attempted> |
      
      ## Acceptance
      - AC-1: <verifiable check 1>
      - AC-2: <verifiable check 2>
      
      ## Test Contracts
      Include this section only for `red-required`; omit it for `not-applicable`.
      
      | Acceptance ID | Interface referent | Outermost stable seam | Expected failure | Mode | Interface version | Matrix rows |
      | --- | --- | --- | --- | --- | --- | --- |
      | AC-1 | <public interface> | <existing outer seam> | <expected RED assertion> | tracer | | |
      | AC-2 | <public interface> | <existing outer seam> | <expected RED assertion> | contract-matrix | <ratified version> | <row 1><br><row 2> |
      
      ## Non-goals
      - <what we are NOT changing>
      
      ## Provenance (tier 2 only)
      - culture: <one-line synthesis of what /culture concluded>
      - briesearch: <one-line synthesis>; artifact: <absolute report path returned by research-layout>
      ```
      
      Mini-spec mode writes `shape: single` unless the user named a shape.
      
      `source: agent-mini-spec` marks the strict Mold production path. New behavior
      specs must set `ui_surface` to exactly `browser` or `non-browser`; closed
      non-behavior specs, including `appearance-only`, set it to `not-applicable`.
      The taste and curd gates reject an omitted or unsupported value. `browser`
      requires every Test Contract to name an existing browser/E2E interface and
      outer seam; `non-browser` never consults contract prose for classification.
      User-invoked ceremony specs use `source: mold-handshake` and the same rules.
      Specs without either marker remain legacy-compatible.
      
      `## Provenance` appears only when `/cheese` reaches tier 2 before falling into tier 1. This occurs when `/culture` or `/briesearch` supplies context absent from the original input. Omit the section when tier 1 fires on the raw input.
      
      ### Briesearch sidechain contract
      
      Mold owns the dialogue and the approval state for every research request. Apply these rules to each `/briesearch` call:
      
      - Send `invocation: sidechain` in the request. A missing value defaults to `top-level`, which releases the run from Mold's control.
      - Send `allow_question: false`. Mold asks every user question itself.
      - Reuse the Mold parent slug for the request. Do not derive a second slug. The parent slug also names the research artifact.
      - Record the full absolute report path returned by `research-layout` in the `artifact:` field. This link preserves the citations. It lets `/cook` or any later skill read them again without new research.
      - Map a `don't know` result to an open hypothesis. Record no `outcome`. Keep Curdle blocked until new evidence or an explicit `[TBD]` decision settles it.
      - Omit `artifact:` only when `/briesearch` reads local code patterns and writes no durable file.
      
    • modes.md 10.7 KB
      # The six modes of mold
      
      Mold has no fixed entry point. Inspect the input shape and pick a starting mode. Announce the mode in one line. Low-confidence classifications default to **Explore**.
      
      ## Routing — input shape to starting mode
      
      | Input shape | Start mode | Heuristic |
      | --- | --- | --- |
      | Stack trace, "X is broken/slow/flaky" | Diagnose | error markers, `file:line` refs, symptom verbs |
      | File path, PR ref, existing spec in the durable spec corpus (resolver-owned; see `SKILL.md` Curdle) | Ground | concrete artifact exists; read it first |
      | Half-baked design doc with signatures or schemas | Sketch | already has interfaces; refine them |
      | "I want to add X" with concrete nouns | Bounds pass → Shape | run the bounds pass first (edges → goals/non-goals), then jump to options |
      | "Should we do X? thinking about Y" | Bounds pass → Grill | bounds pass first, then stress-test the tentative plan |
      | Vague noun, half-sentence, "thinking about" | Explore | no grounded artifact, no chosen direction |
      
      **Front-loaded bounds pass.** Every row above selects a *secondary* mode. Regardless of input shape, mold first runs the bounds pass from `SKILL.md` Flow step 1 and opens the per-round decision ledger. For a concrete ask ("I want to add X", "Should we do X") the pass is one ledger line: goals and non-goals as the agent read them, marked `[AGENT-DECIDED]`. It becomes a question only when the goal is genuinely unknown or a leverage trigger fires. Then Shape/Grill receives the scope.
      
      ## Mode definitions
      
      ### Explore — intent extraction
      
      **Job:** collapse ambiguity with high-leverage questions. Borrow the Job-To-Be-Done frame: Why Now, What This Unlocks, Who Has The Pain, Do Nothing. Use lettered options to compress decisions.
      
      **Exit when:** the dialogue states one problem statement and one concrete pain point, and the ledger pins that statement on its `Goal:` line.
      
      ### Ground — anti-hallucination
      
      **Job:** anchor every claim to evidence from code, docs, or prior research. When the user uses overloaded terms ("account", "session", "user"), pause and ask a canonical-term question. At the curdle atomic step, write resolved terms to the session's durable glossary at `.cheese/glossary/<slug>.md`. See `curdle.md` § Durable glossary. Downstream skills (`/cook`, `/age`, `/press`) can read these terms for naming consistency.
      
      **On Ground entry:** after the Hallouminate probe, resolve and load the project's cumulative domain model through the Mold bundle command:
      
      ```text
      python3 skills/mold/scripts/mold.pyz domain-model-target \
        --probe <unavailable|no-match|match> \
        [--corpus repo:<repo>:wiki --model <present|absent|unknown>]
      ```
      
      Use the domain-model probe transport in [`../../cheese/references/optional-plugins.md`](../../cheese/references/optional-plugins.md).
      Do not derive these arguments from Ground's topic-search `hit` or `miss`.
      
      Pass `unavailable` when Hallouminate is not loaded or the probe failed. Pass `no-match` when the listing completed but contained no `repo:*:wiki` corpus. Pass `match` with the exact corpus name and its model status when the listing found one. The command accepts only explicit probe results and does not import MCP machinery. Its JSON contains `backend`, string `location`, and `wiki_reachable`. Complete the read-probe cascade before any write: wiki, tracked `docs/domain-model*`, then `<project_corpus_root()>/domain-model*`. A listed wiki corpus does not win without a confirmed model. An existing file-store model wins over a wiki corpus without a confirmed model. The resolution mirrors the `adr_target()` *pattern* in `adr.md` § Resolution. It is dynamic, and the existing model always wins. If the probe is unreachable, degrade to "not loaded" and report it. Never block Ground because the probe is unreachable. `False` means no wiki probe occurred because no hook existed or the hook raised. In that case, announce "domain model not loaded from the wiki". Do not present the file-store result as the whole picture. The model is cross-session memory. The per-slug glossary is the branch-local handoff. **Challenge immediately** when a user term conflicts with an existing model entry. Ask: "the model defines X as …, you seem to mean Y — which is it?" Challenges are LIVE here. Defer model writes to the approval gate. Curdle owns the write; see `curdle.md`. Never write inline during Ground.
      
      **Invariant:** never say "I think the code does X" without semantic source-code evidence gathered according to the [shared routing contract](../../cheese/references/code-intelligence-routing.md).
      
      **Exit when:** every critical claim has a citation.
      
      ### Shape — option generation
      
      **Job:** turn a grounded problem into 2+ candidate approaches with trade-offs. Always include **Do Nothing**. Present lettered options (`A/B/C/D`) for the user to select. The user chooses consequential forks (the leverage line in `../../age/references/voice.md`); do not settle them. Settle every fork below the line and log it. Give a one-line rationale for each option, not a verdict. Validate Cycle every critical assumption behind an option. Score options by the information they leave behind. Prefer the option that reduces the next maintainer's required knowledge or makes that knowledge more obvious.
      
      **Exit when:** the user picks one option (→ Sketch). Return to Explore when no option survives.
      
      ### Sketch — interface lockdown
      
      **Job:** place the change in the architecture at 10,000 ft. The output is the **Placement block** that fills `## Interface sketches` (`curdle.md` § Spec template):
      
      - `slice:` which domain slice owns the change, or `NEW SLICE` (a `new-slice` leverage trigger)
      - `spine step:` where it sits on the request path (entry → workflow → domain → infra), or `none`
      - `public interface:` one signature per new or changed crust export, nothing else
      - `private:` what stays behind the crust, as a one-line list of responsibilities, not signatures
      - `crust delta:` new exports, cross-slice imports, or contract changes, or `none`
      - `arrows:` any dependency direction the change adds, checked against [`../../cheese/references/sliced-bread.md`](../../cheese/references/sliced-bread.md)
      
      Run the shape check (`shape-check.md`) before drafting when the change touches multiple modules or introduces a new public interface; print its summary block first. No block, no sketch. Single-module, internals-only sketches note "shape check skipped: single-module change"; that skip line satisfies the "no block, no sketch" precondition, as `shape-check.md` § When to skip defines for every sanctioned skip. Do not write bodies, helper signatures, or internal pseudocode in Sketch; those belong to `/cook`. A non-empty `crust delta` is a consequential fork.
      
      **Acceptance notation (EARS):** for every public interface line, emit acceptance criteria in EARS form: `WHEN <trigger> THE SYSTEM SHALL <response>`. If the trigger cannot be stated precisely (e.g. pure internal utilities), fall back to prose with a `[prose-fallback]` marker.
      
      **Language default:** when a sketch introduces a component with a free language choice, default to the repository's incumbent memory-safe typed language (Python under a strict type checker, or TypeScript in `strict` mode). When the incumbent is C or C++, treat Rust as the default for new components. Choose Go only for standalone tooling where diff uniformity dominates. Treat Elm and Gleam as niche. Reviewer familiarity and model generation accuracy dominate review speed; cross-language review throughput itself is unmeasured. Record any departure as an `[AGENT-DECIDED]` item for Grill.
      
      **Exit when:** the Placement block is complete, every acceptance criterion uses EARS form or has `[prose-fallback]`, every cross-module call uses public interfaces, not internals, and the shape-check verdict is recorded or explicitly skipped under the gate above.
      
      ### Grill — adversarial clarification
      
      **Job:** stress-test the chosen approach and sketched interfaces. Grill runs on consequential forks and `high` blast-radius options only. Tag each grilled item with what it moves: an acceptance criterion, a public seam, or a non-goal. An item that moves none of those, or that sits below the leverage line, is not a user fork: batch-report it as upheld with a one-line steelman, or record it `[AGENT-DECIDED]`; either way the ledger carries its vetoable alternative (`../../age/references/voice.md`). Such items never become a user turn. Use **one grilled item per turn** for consequential items, except for the clean-steelman batch below. For each consequential decision, produce at most a **steelman + tension statement**. Then present a **user fork**: uphold / amend-as-proposed / user's own call. Invoke the question primitive in [`../../cheese/references/ask-user-question.md`](../../cheese/references/ask-user-question.md). Use a real user turn. Do not render an `A/B/C/D` prose block and answer it yourself. Never self-issue verdicts for items that change the design. When the steelman fails cleanly and grilling finds nothing, you MAY batch-report items as upheld. When grilling produces an amendment, ask through the same primitive before adding the amendment to the ledger. Traverse decision branches and contract corners. Pause for a Validate Cycle when an unverified assumption appears.
      
      **Exit when:** every branch and contract corner is touched and agent confidence ≥ user confidence.
      
      ### Diagnose — symptom inputs
      
      **Job:** entry mode for stack traces and "X is broken". Phases:
      `Build a Loop → Reproduce → Hypothesize (3–5 ranked, falsifiable) → Confirm root cause`.
      
      **Phase 0 (Build a Loop)** is the core discipline. Agree on a fast, deterministic, falsifiable feedback technique BEFORE chasing hypotheses. Techniques include a failing test, curl/CLI script, headless browser, replay, bisection harness, or differential loop. The chosen loop becomes the Reproduction block in the bug-shaped spec. Thus, `/cook` can verify the fix against the same signal.
      
      Diagnose is **diagnostic-only** — hand off to Shape ("what's the fix?") then Curdle emits a bug-shaped spec.
      
      ## User knobs (free-form interrupts)
      
      `explore`, `ground`, `shape`, `sketch`, `grill`, `diagnose`, `validate <hypothesis>`, `prototype <question>`, `curdle`, `pause`, `enough`, plus the tier knobs `quick`, `light`, and `full` (`tiers.md`). Honour these immediately.
      
      `prototype <question>` launches a Prototype Cycle (`prototype-cycle.md`): a
      throwaway built in a hermetic sub-agent worktree to settle an ungrillable design
      unknown, returning only the answer as a digest. The code is discarded; the answer
      is the keeper.
      
      ## Uncertainty markers
      
      | Marker | Meaning |
      | --- | --- |
      | `[?]` | Agent uncertain; needs validation |
      | `[TBD]` | User uncertain; decision deferred |
      | `[BLOCKED]` | External dependency unresolved |
      | `[CONFLICT <id>]` | Codebase contradicts a stated assumption |
      
    • prototype-cycle.md 3.3 KB
      # The Prototype Cycle
      
      An escape hatch for design questions that can't be settled by reasoning, search,
      or doc-reading — only by *trying it*. Spawnable at any point in the dialogue, in
      parallel with a Validate Cycle. Mold owns the parent dialogue; the sub-agent owns
      the throwaway. The code is discarded; the answer is the keeper.
      
      Use it when a question is **ungrillable**: an API's real behaviour, whether two
      libraries compose, the actual shape of an error, an ergonomics call that only a
      running sketch can answer. Do not use it for questions a semantic source search,
      bounded source read, or Validate Cycle already settles — those are cheaper. Follow the [shared routing contract](../../cheese/references/code-intelligence-routing.md) for source-code evidence.
      
      ## The frame
      
      Always announce the cycle before dispatching — the announcement is the discipline.
      
      ```text
      Launching a prototype cycle on question: "<ungrillable design unknown>"
      
      Plan:
        spawn sub-agent(isolation: "worktree")   # degrade to a temp dir if the repo is not git
          build a throwaway (may try several variations)
        digest ← { question, answer, snippet?, confidence }   # <=2 KB; no code dumped
        discard the worktree                      # the answer is the keeper, never the code
        log state.prototype_cycles[] ; optionally emit an ADR (adr.md)
      ```
      
      **1 cycle == 1 design question resolved**, not 1 per variation. The sub-agent may
      try several throwaways internally; that is still one cycle.
      
      ## What the sub-agent returns
      
      A digest, never a code dump (sub-agent split + digest size live in the shared
      kernel at `../../age/references/sub-agent-gate.md`):
      
      | Field | Content |
      | --- | --- |
      | `question` | the design unknown, restated |
      | `answer` | the resolved behaviour, in one or two sentences |
      | `snippet?` | the minimal decision-encoding fragment, only if it captures the answer better than prose |
      | `confidence` | `certain \| speculating \| don't know` |
      
      The worktree is discarded after the digest is extracted. Nothing from the
      throwaway tree is committed, copied back, or referenced by path — if a fragment
      matters, it lives in the digest `snippet`.
      
      ## Isolation and degrade
      
      - Default: `isolation: "worktree"` — a hermetic git worktree, auto-cleaned.
      - The repo is not a git repo: degrade to a temp directory under `${TMPDIR}`,
        say so out loud, and clean it up after extraction.
      - Harness lacks sub-agent spawning: run the throwaway inline in a scratch dir,
        note the loss of isolation, and still discard it.
      
      ## Budget
      
      Prototype cycles are **context-bounded, not capped** (ADR-003). Run as many as
      confidence needs; the 120k/140k context-budget mechanic
      (`context-budget.md`) is the natural limiter. A **soft backstop of 10**
      prompts a single "still gathering — continue?" check; it is not a hard stop and
      the user can wave it through.
      
      ## Logging
      
      Every launched cycle is logged in the mold state file:
      
      ```yaml
      prototype_cycles:
        - id: pc-1
          question: "Does library X's streaming API surface backpressure?"
          answer: "Yes — it yields when the consumer is slow; no manual pause needed."
          confidence: certain
          adr: ADR-002   # optional, when the answer encodes a non-obvious decision
      ```
      
      An open cycle (no `answer:`) blocks Curdle until it settles or the user accepts
      it as `[TBD]`, exactly like a Validate Cycle.
      
    • review-canvas.md 1.2 KB
      # Mold review canvas
      
      Use the bundled review canvas when visual artifacts or browser interaction help resolve Mold forks.
      
      ## Procedure
      
      1. Publish the review document with `python3 skills/mold/scripts/mold.pyz review publish --state-dir DIR --input FILE [--base-revision N]`.
      2. Start `python3 skills/mold/scripts/mold.pyz review serve --state-dir DIR --port 0` and give the returned private URL to the user.
      3. Read submitted snapshots with `python3 skills/mold/scripts/mold.pyz review poll --state-dir DIR --after CURSOR --timeout SECONDS`.
      4. Reconcile each exact question and option identifier into the decision ledger.
      5. Publish a new revision when the review document changes. Never replace dirty feedback silently.
      6. Stop the server with `python3 skills/mold/scripts/mold.pyz review close --state-dir DIR` when the review ends.
      
      Autosave only preserves a working copy. `Send to agent` creates feedback, not approval.
      
      Browser feedback never satisfies the taste gate, typed-plan gate, or two-key handshake.
      
      The canvas is optional. It is a local-only review aid, not an approval mechanism. It must not request approval, bypass the taste gate, bypass the typed-plan gate, or bypass the two-key handshake.
      
    • shape-check.md 5.8 KB
      # The shape check
      
      Run this before drafting in Sketch mode. Also run it whenever discussion in any mode depends on "what does this touch" or "what depends on this". The check is read-only. Culture and mold both run it; only the artifact stage differs.
      
      ## What it answers
      
      - **Signatures**: what does the touched function/type look like today? What sibling signatures already exist in the same module so a new one fits convention?
      - **Callers** (upstream): who calls the touched symbol, and from which modules?
      - **Callees** (downstream): what does the touched symbol call into? Surfaced by the same symbol query — `kind: "symbol"` returns a `── calls ──` footer with one-hop callees. No extra call.
      - **Imports / blast radius**: which files import this module? Which does this module import?
      
      These four answers describe the change's shape and bound its blast radius. Upstream identifies who breaks if you change it. Downstream identifies what you could pull into the change. InlineCoder-style bidirectional inlining gives the downstream half empirical value for repo-level edits. Ignoring it leaves a known gap.
      
      ## Procedure
      
      Run all three queries. Each query is cheap when the answers are small. A skipped query causes silent misrouting later.
      
      | Question | Backend capability | Call |
      | --- | --- | --- |
      | Current signature? Sibling signatures? Downstream callees (`── calls ──` footer)? | semantic symbol search | `tilth_search(queries: [{query: "<symbol>", kind: "symbol"}], expand: 2, scope: "<module>")` |
      | Who calls this? (upstream) | semantic caller search | `tilth_search(queries: [{query: "<symbol>", kind: "callers"}])` |
      | What's the import / blast radius? | dependency search | `tilth_deps(path: "<file>")` |
      
      The first call serves two purposes. Its `── calls ──` footer provides the cheap callee read. Do not issue a separate query.
      
      For multi-symbol changes, batch up to five symbols in a single semantic search call (`query: "a, b, c"`). Re-run only when a new symbol enters scope. Follow the [shared routing contract](../../cheese/references/code-intelligence-routing.md).
      
      ## Output expected before exit
      
      A summary at the top of the Sketch turn (or culture's blast-radius step):
      
      ```
      Shape check on <symbol(s)>:
        signature(s):  <one line per touched seam>
        callers:       <count> sites in <N> non-test files (paths)
        callees:       <count> one-hop calls (names) — omit line if empty
        blast radius:  imported by <count> files; imports <count> modules
        slice:         <owning slice from the import path>
        crust delta:   <new exports | cross-slice imports | contract changes | none>
        verdict:       low | medium | high
      ```
      
      The `callees` line is optional — print it only when the symbol query's `── calls ──` footer is non-empty. A leaf function with no callees should drop the line, not print `0`.
      
      `slice` and `crust delta` come from the same `tilth_deps` answer read against [`../../cheese/references/sliced-bread.md`](../../cheese/references/sliced-bread.md): the touched symbol's own path names the owning slice; the importer list shows which other slices consume it. Any importer outside the owning slice that reads past its crust, any new cross-slice import, or any new export is a crust delta.
      
      Three consumers print this block: mold's Sketch turn, culture's blast-radius step, and cook's Contract step. The block shape is the same in all three; only the gate that follows differs.
      
      A `high` verdict means multi-module callers, more than five importers, or a non-empty crust delta. It makes the Grill gate mandatory in mold; see `handshake.md`. Before continuing trade-off talk, culture must label the option `[high blast radius]`.
      
      ## When semantic source tooling is unavailable
      
      Shape-check must not block dialogue when its preferred tools are missing. Use a sanctioned alternative when available. **For shape-check specifically, do not substitute textual search**. `grep` / `rg` over a symbol name counts string occurrences, not callers or importers. A guessed blast-radius verdict is worse than an unknown.
      
      - **Callers / callees**: fall back to LSP `textDocument/references` / `textDocument/prepareCallHierarchy` when a language server is reachable. Note the substitution out loud.
      - **Imports / blast radius**: no LSP equivalent. Skip the count, mark the line `unknown`, and lean on the verdict downgrade below.
      - **Verdict**: cap it at `[?]`, not `low | medium | high`. A guessed verdict is worse than an honest unknown. For gating, Sketch and culture must treat `[?]` like `high` until the user accepts the gap. The Grill gate engages, and culture labels the option `[high blast radius]`.
      
      If both tilth and LSP are unavailable, say so once and proceed with `[?]`. Do not silently substitute a textual search for the shape-check itself.
      
      ## When to skip
      
      - The touched symbol has zero callers (greenfield) — say so out loud.
      - The change affects one private function in one file and has no exports. Sibling signature lookup still applies. You can skip dependencies and callers.
      - The user explicitly said `skip the shape check`.
      
      A skipped check prints one line in place of the block, `shape check skipped: <reason>`, and that line satisfies the "no block, no code" precondition in cook's Contract and mold's Sketch. Closed non-behavior work (docs-only, appearance-only) always takes this path.
      
      ## Why
      
      Trade-offs and seams discussed without a shape check rely on the agent's guess at impact. The check converts that guess into numbers — caller count, callee count, importer count — the user can argue with.
      
      Direction matters. Upstream callers identify who breaks if the seam changes. Downstream callees identify what the change can pull in. Bidirectional structural context measurably improves accuracy on repo-level edits. The existing symbol query provides the downstream half at no additional cost.
      
    • tiers.md 4.3 KB
      # Tiers — scale the ceremony to the job
      
      Mold picks a tier at the end of the Bounds pass (`../SKILL.md` Flow step 1), once the goals, non-goals, and shape-check verdict are on the ledger. Announce the tier in one line with its reason before the first fork question:
      
      ```text
      tier: quick — clarity check passed, verdict low, no open fork
      ```
      
      The user overrides with the `quick`, `light`, or `full` knob at any time. Mold upgrades on its own when the evidence changes. It never downgrades silently.
      
      ## The three tiers
      
      | Tier | Enter when every condition holds | Runs | Skips | Artifact → handoff |
      | --- | --- | --- | --- | --- |
      | **Quick** | Cook's standalone fast-path check passes on the bounded ask ([`../../cook/SKILL.md`](../../cook/SKILL.md) § Standalone fast-path), which includes zero fired leverage triggers ([`../../cheese/references/routing-policy.md`](../../cheese/references/routing-policy.md) § Leverage triggers); shape-check verdict `low`, or skipped as greenfield or a single private function; no consequential fork open after bounds | Bounds, one wiki probe, one fast confirm (`go`, `yes`, `ship it`) | Explore, Shape, Sketch, Grill, Validate and Prototype cycles, fork taste test, typed planner, handshake checklist, ADRs, follow-up publication | mini-spec through [`mini-spec-mode.md`](mini-spec-mode.md), still gated by `validate-spec --strict`; finalize with `python3 skills/mold/scripts/mold.pyz finalize` and hand Cook its canonical `HandoffPointer` |
      | **Light** | Goal is clear after bounds; verdict `low` or `medium`; at most two consequential forks; no new public seam across modules; one expected curd | Bounds with `G-n` clauses, Ground, Shape for the open forks, Sketch only when a public seam changes, fork taste test, goal coverage and narrowing delta, two-key handshake, Curdle phase one | Explore; Grill unless the user asks or a fork turns high-blast; typed planner (one curd needs no `CurdPlan`); issue-draft publication | full spec (`source: mold-handshake`) → `python3 skills/mold/scripts/mold.pyz finalize` → canonical `HandoffPointer` handed to Cook |
      | **Full** | Anything else: verdict `high` or `[?]`, three or more forks, a new cross-module public seam, two or more expected curds, a Diagnose input, or the `full` knob | The whole Flow | Nothing | spec + `PlannerResult` + `CurdPlan` → `python3 skills/mold/scripts/mold.pyz finalize` → canonical `HandoffPointer` → `## Handoff` menu |
      
      A fired leverage trigger rules Quick out: the fork it names is consequential, so the ask enters Light or Full by the rows above. Leverage picks whether the user steers; the verdict, fork count, and curd count pick how much of the Flow runs.
      
      The fast confirm is Quick's user key and `validate-spec --strict` is its agent key. The checklist in [`handshake.md`](handshake.md) applies to Light and Full only. Light marks each handshake box that does not apply as `n/a: <reason>` out loud rather than leaving it unchecked. `curdle anyway` is never needed to leave a gate that was never entered.
      
      ## Upgrade rules
      
      Upgrade the moment any condition breaks. Announce the new tier with its trigger and keep every ledger entry.
      
      - A consequential fork opens after Quick's confirm → Light. The confirm is void until the fork is picked.
      - The shape-check verdict rises to `high` or `[?]` → Full, Grill mandatory.
      - A second module or a new public seam enters scope → Full.
      - The expected curd count reaches two → Full. The typed planner is required.
      - Cook returns `next: mold` on a Quick mini-spec → re-enter at Light with Cook's failure as prior evidence.
      
      Downgrade only on the user's knob. Say what the lower tier skips before continuing.
      
      ## What no tier skips
      
      - The wiki probe and its ledger record (`grounding-recorded`).
      - The agent-introduced-scope check: every distinguishing noun traces to the user's words.
      - `validate-spec --strict` on whatever artifact ships.
      - The user's say on every consequential fork.
      - The leverage-trigger check: a fired trigger never lands in Quick.
      
      ## Relationship to `/cheese`
      
      `/cheese` enters mini-spec mode directly at its tier 1 with no confirm, because the clarity check already passed on the raw input. Mold's Quick tier is the same mode entered from a user invocation, with one confirm because the user chose to talk first. A `mold` intent from `/cheese` still lands in user mode and tiers itself here.
      
    • validate-cycle.md 2.4 KB
      # The Validate Cycle
      
      Any mode can invoke a Validate Cycle. Always **announce the cycle** before dispatching — the announcement is part of the discipline.
      
      ## The frame
      
      ```text
      Launching a validate cycle on hypothesis: "<single declarative sentence>"
      
      Plan:
        /briesearch  — fetch evidence
        Judge        — support, contradict, or refine?
        Settle       — accept, revise, or reject. Continue from current mode.
      ```
      
      A bare `/briesearch` call without this frame is discouraged. The frame forces commitment to a hypothesis plus a judgment step.
      
      ## Outcomes
      
      | Outcome | Meaning | Next action |
      | --- | --- | --- |
      | **SUPPORTED** | Evidence aligns with the hypothesis | Promote to a decision |
      | **CONTRADICTED** | Evidence disagrees | Mark `[CONFLICT <id>]`, revise or abandon |
      | **REFINED** | Evidence partially aligns | Restate with new precision and re-validate or accept |
      
      Diagnose's parallel hypothesis ranking IS this cycle, parallelized.
      
      ## Budget
      
      Validate cycles are **context-bounded, not capped** (ADR-003 of the mold-parity
      spec). Confidence-gathering is the goal; an arbitrary cap cuts it short.
      
      - **No hard cap.** Run as many `/briesearch` cycles as confidence needs. The
        context-budget mechanic (`context-budget.md`) is the natural limiter — offload
        deep evidence to a sub-agent and watch the window.
      - **Soft backstop of 10.** At the 10th launched cycle, ask once "still gathering —
        continue?"; it is a check, not a stop, and the user can wave it through.
      - Cycles backed by local semantic source-code evidence alone are unbudgeted — they do not count toward the backstop.
      
      The same context-bounded rule governs Prototype Cycles (`prototype-cycle.md`).
      
      ## When to skip
      
      - The claim is already grounded by a bounded source read or earlier cycle; source-code reads follow the [shared routing contract](../../cheese/references/code-intelligence-routing.md).
      - The decision is reversible and small — running a cycle costs more than just trying it.
      - The user explicitly said "skip the cycle".
      
      ## Logging
      
      Every launched cycle is logged in the mold state file:
      
      ```yaml
      validate_cycles:
        - id: vc-1
          hypothesis: "Express's Router supports per-route middleware arrays"
          outcome: SUPPORTED
          sources: [Context7]
        - id: vc-2
          hypothesis: "We can hot-swap the auth middleware without restart"
          outcome: CONTRADICTED
          conflict_id: cf-1
      ```
      
      Open hypotheses (no `outcome:`) block Curdle until they settle or are explicitly accepted as `[TBD]`.
      
  • scripts
    • mold.dot 4.1 KB · in bundle
    • mold.pyz 9.9 MB · in bundle
  • phase-contract.yaml 294 B
    contract_version:
      schema_uri: https://schemas.easy-cheese.dev/phase-contract
      major: "1"
      minor: "0"
    source: mold
    input_schema_uris:
      - https://schemas.easy-cheese.dev/planner-request
    outputs:
      - destination: cook
        payload_schema_uri: https://schemas.easy-cheese.dev/mold-cook-handoff
    
  • SKILL.md 14.9 KB
    ---
    name: mold
    description: Turn a high-leverage design decision into an approved spec through grounded dialogue. Use it when a leverage trigger fires (auth, irreversible effects, concurrency, contracts, destructive ops, a new slice, a cross-slice dependency, an invariant gap) or when the user asks for a spec or design. Typical phrases include "let's design X", "shape this into a spec", "what should the API for Z look like", and "/mold". A feature ask with zero fired triggers is a `/cook` mini-spec, not a mold; route it through `/cheese`. Do NOT use it for free-form discussion without artifact intent (`/culture`), direct implementation (`/cook`), or research-only questions (`/briesearch`). Ceremony scales to the ask through `references/tiers.md`, so a small clear change gets a one-confirm mini-spec rather than the full dialogue.
    license: MIT
    metadata: {dispatches-agents: true}
    ---
    
    # /mold
    
    Ceremony scales to the job. The Bounds pass picks one of three tiers from `references/tiers.md`: **Quick** writes a one-confirm mini-spec, **Light** runs only the dialogue modes the open forks need, and **Full** runs the whole Flow below. `/cheese`'s tier-1 escalation enters mini-spec mode with no confirm; see `## Agent-invoked mini-spec mode`.
    
    ## Flow
    
    1. **Bounds pass** — open the `Goal / Decided / Asking / [AGENT-DECIDED]` ledger with the goal pinned as one sentence; only an explicit user fork changes it. Split it into `G-n` clauses (`references/handshake.md` § Goal coverage). Map every input's goals and **non-goals** as one `[AGENT-DECIDED]` line; ask the user only when the goal is genuinely unknown or a leverage trigger fires. Run the shape check, then announce the tier with its reason (`references/tiers.md`). Quick exits here: one fast confirm, then `## Agent-invoked mini-spec mode`. Upgrade the tier whenever the evidence changes; never downgrade silently.
    2. **Route** — choose the secondary mode from `references/modes.md`, announce it, and correct false premises first.
    3. **Dialogue** — consequential forks are the user's to pick. A fork is consequential per the leverage line in `../age/references/voice.md`. Every other fork is `[AGENT-DECIDED]`. Supply options, trade-offs, and evidence before you ask. Ground each critical claim through code, the [Validate Cycle](references/validate-cycle.md), or a [Prototype Cycle](references/prototype-cycle.md). Resolve every contradiction. Render the decision map after three consecutive fork questions, or on request.
    4. **Sketch** — For work across modules or with a new public interface, run `references/shape-check.md`. Bind identity and role nouns to code referents. Record the Placement block; no bodies.
    5. **Plan for approval** — run the fresh-context fork-coherence taste test with `python3 skills/mold/scripts/mold.pyz taste-test` and persist its digest-bound pass; a failure reopens only named forks, and the third failed verdict stops. Light with one expected curd stops here: no planner; finalize the bounded spec with `python3 skills/mold/scripts/mold.pyz finalize` and retain its canonical `HandoffPointer`. Otherwise dispatch a typed `PlannerRequest`, validate its `PlannerResultWriterView` (one retry, then stop before the handshake), normalize on the host, and persist only the typed `PlannerResult` and `CurdPlan`. Present the plan's semantic curds and waves at the handshake. See `references/curdle.md` § "Pre-approval typed planner dispatch".
    6. **Two-key handshake** — Before extraction, the user and agent must agree to the draft spec and displayed typed plan. The user provides an explicit verb. The agent performs a coherence self-check. Neither key changes nor disappears. See `references/handshake.md`.
    7. **Curdle** — Resolve the durable spec path with `SPEC=$(python3 skills/mold/scripts/mold.pyz artifact-path specs <slug>)`. Phase one writes the local artifact and write-ahead prepared state before any external call. It writes the approved spec at `"$SPEC"`. It also writes the host-validated `PlannerResult` and `CurdPlan`. It also writes local issue drafts and the session's non-obvious decisions as durable ADRs. Phase two publishes approved follow-ups. Retain the prepared recovery state when an external capability is unavailable or publication fails. Phase two reconciles their state and references into the durable spec before any handoff. The resolved spec path is internal; Cook receives only the finalizer's canonical `HandoffPointer`.
    8. **Finalize and hand off** — after reconciliation, run [`python3 skills/mold/scripts/mold.pyz curd-count`](references/curd-count.md), then finalize through `## Handoff`. Full and Light both hand that pointer to Cook. Dispatch only the user's non-stop selection.
    
    Portability: [rules](../cheese/references/harness-portability.md). Slash commands are host renderings, not the control model.
    
    ## Follow-up candidates
    
    Every non-goal and explicit dialogue deferral becomes a `[FOLLOW-UP?]` follow-up candidate. Dispose of the set before the two-key handshake; details: `references/handshake.md` § Follow-up disposition.
    
    ## Modes
    
    | Mode | Use when | Goal |
    | --- | --- | --- |
    | Explore | The idea is vague | Identify the real problem and pain point |
    | Ground | A file, bug, or existing doc is named | Verify facts against evidence |
    | Shape | The goal is known but approach is open | Compare viable options (Do Nothing always included) |
    | Sketch | Interfaces or module boundaries matter | Lock responsibilities and seams |
    | Grill | A favoured approach needs stress-testing | Steelman each item, then put every design-changing call to the user as a fork |
    | Diagnose | A symptom, failure, or trace is supplied | Build a Loop → reproduce → hypothesize → confirm root cause |
    
    Modes: references/modes.md. Evals: references/evals.md. Canvas: [review-canvas.md](references/review-canvas.md).
    
    ## Agent-invoked mini-spec mode
    
    `/cheese`'s tier-1 escalation calls `/mold` after the call site passes all cook fast-path checks, and the Quick tier enters the same mode after its one confirm. It produces a spec without design dialogue. This mode skips the rest of the Flow above. Derive a slug. Write the mini-spec. Parse its declared gate applicability. Finalize through `## Handoff` and return its canonical `HandoffPointer` to Cook. Append `--hard` when the user passed it.
    
    The two-key handshake does not run in this mode. The agent-introduced-scope check still runs implicitly. Every distinguishing noun must come from the user's input or tier-2 `/culture`/`/briesearch` synthesis. Never add one silently.
    
    Full procedure, the mini-spec schema, and the `## Provenance` rules: `references/mini-spec-mode.md`.
    
    ## Preferred tools and fallbacks
    
    Call source-code search, read, and edit backends according to [`code-intelligence-routing.md`](../cheese/references/code-intelligence-routing.md). Shape checks use semantic caller search plus dependency context; procedure: `references/shape-check.md`.
    
    Mold-specific tools beyond source-code routing:
    
    | Need | Prefer | Fallback |
    | --- | --- | --- |
    | External validation | `/briesearch` with Context7/Tavily | user docs, repo docs, or note as unverified |
    | Wiki grounding (Ground entry + decision points; scope per `references/grounding.md` § When to probe) | `mcp__hallouminate__list_corpora` + `mcp__hallouminate__ground` on `repo:<repo>:wiki` | record `hallouminate: absent` in the ledger, proceed on code evidence, and cap at `speculating` when design rationale is central |
    
    **The grounding record precedes the first structured question:** the ledger holds a probe result — citations or `hallouminate: absent` — first. Mark each unsupported claim `[?]` until settled.
    
    ## Sub-agent context gate
    
    `/mold` owns the dialogue, contradictions, and approval state. Do not delegate these items. Delegate evidence-heavy code work to a fresh-context `explorer` and external research to a `researcher`. **Shape uses an explorer digest as input.** Record parent-context exploration as a degraded path. See `references/context-budget.md` for budgets and checkpoints.
    
    ### Gate graph
    
    `python3 skills/mold/scripts/mold.pyz gate-graph --render dot|svg|png|mermaid` renders one gate model. Image targets use Mermaid when Graphviz is unavailable. Tests keep gate nodes aligned with the handshake checklist. See `references/gate-graph.md`.
    
    ### Gate applicability and Test Contracts
    
    Every Mold-produced spec carries a provenance marker in frontmatter:
    
    ```yaml
    source: mold-handshake | agent-mini-spec
    ```
    
    Every spec declares `gate_applicability`:
    
    ```yaml
    gate_applicability:
      disposition: red-required | not-applicable
      work_class: behavior | docs-only | refactor-only | test-only | appearance-only
      ui_surface: browser | non-browser | not-applicable
    ```
    
    `ui_surface` is required on the Mold production path: `browser` means every
    Test Contract names an existing browser/E2E interface and outer seam,
    `non-browser` is explicit and never inferred from prose, and `not-applicable`
    is required for closed non-behavior classes including appearance-only.
    `red-required` requires `behavior` plus a complete `## Test Contracts` table
    with one executable red row; `not-applicable` requires a closed class, a
    reason, and no contracts. Mold never infers applicability. Row-level rules:
    `references/curdle.md` § Test Contracts.
    
    ### Fork taste gate
    
    `python3 skills/mold/scripts/mold.pyz taste-test` binds the verdict to draft SHA256 and each settled fork. Stale, partial, or blocked verdicts fail; a failure reopens only named forks, with two rounds. Approved `red-required` specs pass unchanged metadata and the published pointer to `/cook --auto`.
    
    Each fork appears in Approach, Interface sketches, Acceptance, plus Test Contracts for `red-required`; none in `not-applicable` specs. Do not rename sections. Tag reflecting lines with fork id and run `taste-test --precheck` before dispatch. `goal` must survive verbatim in Problem statement (`goal-drift`); each `G-n` clause carries an Acceptance or disposition tag (`goal-coverage`). See `references/curdle.md` § Spec template and `references/gate-graph.md`.
    
    ## Approval gate
    
    Curdle requires the **two-key handshake**. It requires an explicit user verb: `curdle` or `ship it`. It also requires the agent's coherence self-check. Present the validated typed `CurdPlan`'s `N curds / M waves` with the final approval request in Flow step 5; on Light's single-curd path there is no plan, so present the spec alone and mark the plan boxes `n/a`. See `references/handshake.md` for the checklist, mandatory gates, and override semantics.
    
    Before the handshake, print the **narrowing delta** (`taste-test --coverage`), then present the **scope audit table** once. One confirm approves the defaults; only leverage rows and unresolved bindings need a verb, and `curdle anyway` waives neither. See `references/handshake.md`.
    
    If any gate is unmet, propose the smallest next question, evidence check, or planner correction. Do the same if the typed plan remains invalid after one retry. Write artifacts only after both keys pass.
    
    ## --hard
    
    Mold never runs the metacognitive check. Plate alone runs it at the
    verified-artifacts boundary. Mold appends `--hard` to every Cook command that
    it emits when the user passed the flag. Cure forwards the same flag to Plate.
    See `../hard-cheese/references/composition.md`.
    
    ## Handoff
    
    **Pipeline:** culture → **[mold]** → cook → press → age → cure → plate
    
    After Curdle's phase two finishes, run [`python3 skills/mold/scripts/mold.pyz curd-count`](references/curd-count.md) for the blast-radius digest. Finalize with `python3 skills/mold/scripts/mold.pyz finalize` and keep its consumer-valid canonical `HandoffPointer` path; `finalize` does not require `curd-count` first. Prompt through the shared handoff gate ([policy](../cheese/references/handoff-gate.md)). Approved `red-required` behavior recommends handing the canonical `HandoffPointer` to `/cook --auto`. Keep the applicability, contract, and taste metadata unchanged. Append `--hard` when the user passed it. Never pre-select.
    
    The digest's `mode` is orientation, not a skill. Render the fixed blast-radius menu from `decomposable`, `candidate_curds`, `verdict`, and `mode`; see `references/handoff-menus.md`.
    
    ## Rules
    
    - Dialogue first; artifacts are the by-product.
    - **Tiered lettered options.** Consequential forks use `A/B/C/D` choices via the question transport at `../cheese/references/ask-user-question.md`. Never decide them silently. Everything below the leverage line is `[AGENT-DECIDED]` by default: make the call, log a one-line vetoable alternative in the ledger, and do not ask. A fork is valid only after its depth was contributed in-dialogue first. Precede every structured question with visible prose that weighs the fork and the evidence. Keep one open picker.
    - **Altitude tag.** Every `Asking` fork names the acceptance criterion, public seam, or non-goal it moves. A fork that moves none, or that sits below the leverage line, is `[AGENT-DECIDED]` or a follow-up candidate, never a user question.
    - **Decision ledger.** Each round prints `Goal / Decided / Asking / [AGENT-DECIDED]`, the goal verbatim. Curdle persists consequential decisions to [ADRs](references/adr.md) and minor ones to the spec. The taste verdict names every settled consequential entry exactly once.
    - **Decision map and fork-round cap.** Stop after three consecutive fork rounds that add no new evidence, or three consecutive forks that fail the altitude tag, or when the user requests a decision map. Show completed forks, remaining forks, and a ready or blocked verdict. A fourth round requires new grounding, a delegated digest, or a `/wheypoint` checkpoint. The map shows ledger state. It does not create an artifact.
    - Do not implement code.
    - Do not write production files before the approval gate.
    - Do not silently settle uncertain claims.
    - Apply the shared voice kernel at `../age/references/voice.md`. Correct false premises. Mark each critical claim's confidence as `certain | speculating | don't know`. Steelman before you dismiss. Put consequential forks to the user; depth informs the question, never replaces it.
    
    The schema entanglement behind curdle's spec-template and cook's writer views is phase registry × schema catalog × models per transition. The generated [`../cheese/references/schema-intertwine.md`](../cheese/references/schema-intertwine.md) documents it.
    
    ## Agent resolution
    
    Resolve delegates through [`../cheese/references/agent-resolution.md`](../cheese/references/agent-resolution.md).
    
    | Work | Preferred types | Permissions/isolation | Minimum power | Effort | Fallback |
    | --- | --- | --- | --- | --- | --- |
    | Explore the codebase | explorer | read-only, fresh-context | default | medium | compatible explorer, then general |
    | Research external constraints | researcher | read-only, fresh-context | default | medium | compatible researcher, then general |
    | Plan for approval | planner, general | read-only, fresh-context | powerful | high | compatible planner, then general |
    
    The canonical mold spec or mini-spec carries the shared `agent_resolution` block.
    Commands: [`references/commands.md`](references/commands.md).
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related