# Spec Producer Governance

> Partial Skill: invoke by name only — the SDD default spec-producer procedure. Loaded in-session by the conductor when it runs the spec-producer role inline, not user-triggered.

- Skill: `cyberuni/spec-producer-governance` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add cyberuni/spec-producer-governance`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cyberuni/spec-producer-governance/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: cyberuni (https://skillmd.com/u/cyberuni)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cyberuni/spec-producer-governance

---


# Spec-Producer Governance — the default authoring procedure

The procedure the **conductor** follows when it runs the **spec-producer** role from the SDD default — i.e. no plugin covers the domain and no model-tuned producer agent is named for the slot, so the conductor **loads this governance and authors inline** in its own warm context (recorded `produced-by.spec-producer: sdd:automaton`). The grader is separate — a **cold spec-judge** (`sdd:sdd-spec-judge` or the plugin's judge) always reviews the output; this governance never judges its own work.

Load alongside this governance: `sdd:spec-format-governance` (the required `## Use Cases` section and the `spec.md` enrichment / human-readability rule), `sdd:suite-format-governance` (the `.feature` format bar and scenario-ordering convention), and the resolved **oracle**, **builder**, and **architect** actor bars — **forward** face — to self-align before writing (scope and kill-or-ship, testability/coverage, structural fit). These are exactly the bars the spec-judge grades **backward** at the spec gate, so the producer self-aligns to the same lens set it will be graded against. Load `sdd:ownership-governance` for the write-ownership matrix — which fields the spec-producer may write and which belong to the conductor or the gate skill.

**Track every governance you load.** The spec-judge cannot otherwise tell a skipped pre-flight from a correctly run one — both look like the same output gap. Keep a running list of each governance name as you load it (this governance plus every bar named above) and declare the full list as `governances_loaded` in your structured output — a **required** field, listed even when empty, and **never** written into `spec.md` or the `.feature`.

## Inputs (folded in by the conductor)

```
DOMAIN, DOMAIN_PATH, SPEC_PATH
COMMAND_SURFACE:  <command syntax / signatures / events — or null>
DESIGN_DECISIONS: <known choices — or null>
USER_INPUT:       <What / Why / command surface for a new feature — or null>
BACKFILL:         <true if implementation already exists>
JUDGE_FEEDBACK:   <spec-judge SCENARIOS_FAILING / BLOCKER from a prior pass — or null>
USER_ANSWERS:     <answers to previously returned QUESTIONS — or null>
```

## Procedure

1. **Gather intent, grilling breadth-first and depth one-at-a-time.** First scan the request holistically and summarize every issue; then drive the single most important to resolution before the next — one deep thread, not many shallow. For `BACKFILL`, read source, tests, and history and infer What / Why / decisions / surface; otherwise use `USER_INPUT`. A required input that is missing and cannot be inferred becomes a `CONTENT_GAP` (an `<!-- open: -->` marker), never an invention. Revision pass (`JUDGE_FEEDBACK` non-null): fix only the failing scenarios / sections; fold in `USER_ANSWERS`. **Settle the prose before touching the suite** — scenarios authored against unsettled prose chase a moving target.

2. **Reconcile contradictions toward the correct answer, not the popular one.** When grilling surfaces a conflict — between the `spec.md` body and the `.feature`, between either and the design rules or the implementation, or between two rules — do not guess, and do not just count which reading more files repeat. Zoom out and reason about which is actually right given the design's intent and the whole model; weigh the evidence (the canonical definition, what the implementation does, which decision is most recent and authoritative) to find the coherent answer. Edit the side that is wrong; never reword a rule merely because more files echo it. If the correct answer cannot be established, return a `CONTENT_GAP` rather than picking a direction.

3. **Write the `spec.md` body per `sdd:spec-format-governance`.** That bar owns the required structure — the `## Use Cases` section (subject, non-goals, and per use case its actor / goal, entry point, and extensions, plus the surface-element trace) and the enrichment rules; follow it rather than re-listing sections here (a hardcoded list drifts from the bar).

   **Find the use cases before you name them.** A use case is discovered from the situation the change serves, not derived from the interface you already have in mind — deriving it from the surface reproduces the surface and calls it a requirement. **Enumerate by actor, never by entry point** (`sdd:spec-format-governance` owns the ordering): walking the interface returns only the use cases it already implies and is blind to the one nobody built. **List the actors first** — every person in a role, sibling capability, scheduler, or operator that reaches this capability, plus whoever is affected by its outcome without invoking it (the reviewer, the on-call, the next agent). **Then per actor name the goals** they arrive with — their result, not the call they make; where the answer restates the mechanism ("the caller wants to call it"), you have renamed the function, not found the use case, and the honest move is a `CONTENT_GAP`, never a plausible actor you invented. **Then map goals to entry points**, and report both mismatches: a goal with no entry point is a way in the capability lacks or a goal another node owns, and an entry point serving no listed goal is surface nobody asked for. On `BACKFILL` the source yields only the **served** use cases by construction — recover the unserved ones from the request history, the issue tracker, and recurring workarounds, and record where each came from rather than presenting an inferred set as complete. **Then enumerate the extensions** — walk each use case for **any path from its trigger that does not reach its success outcome**. That criterion decides membership; the recurring kinds (the refusal, the error, the boundary, the partial result, the contended or absent input) are a **prompt to search, not a closed set** (`sdd:spec-format-governance` owns the criterion — a divergence matching none of them still belongs, and a kind that cannot arise is not owed a row). Where nothing can diverge, write `extensions: none — <why>`, so the claim is visible and contestable rather than absent. **Then trace the surface** — take each element the capability exposes (flag, option, parameter, prop, event) and name the use case that needs it and the elements it may not be combined with. An element you cannot attribute to a use case is the finding, not an oversight to fill in: raise it, because the Oracle bar's verdict on it is cut-or-justify.

   **Then check the extensions against the CFG — the producer-side mirror of the Architect bar.** Where the node carries a `## Control Flow` graph, every extension you just enumerated is a path that graph must actually contain, and every forbidden combination is a decision it must actually refuse. Walk them **both ways**: an edge with no extension is the ordinary uncovered-edge case, and an **extension with no edge** is a divergence the prose claims and the drawn graph cannot take (`sdd:architect-spec-governance` grades exactly this backward). Fix whichever side is wrong — add the missing edge where the extension is real, drop the extension where the graph is right — and never report `STATUS: complete` with a stated extension no edge reaches. Where the graph already reaches every stated extension, **amend neither side**: the check has found nothing, and rewriting a graph or an extension it cleared manufactures churn the Architect lens never asked for. This is a self-alignment duty, not a judge's: settling it here spends no cold round on a contradiction the Architect lens will find every time. On a node with **no** CFG the check is vacuous and fires nothing. Author the body content — What, Why, design decisions, and the command / API surface where one exists — and enrich for human review (headings, tables, short paragraphs, a diagram where it carries the idea). Never leave placeholders (`TBD`, `TODO`, empty sections). **Do not** write the control frontmatter (`status`, `project-path`, `approval`, `produced-by`) — those belong to the conductor and the gate skill. Every referenced engine, skill, or artifact path you name must be real — a reference that resolves to nothing is caught mechanically at step 5 below, but naming a real path the first time spends no round on it. **On `BACKFILL` the four sections are still mandatory** — draw the `## Control Flow` CFG and its `## Scenario map` from the code, never stop at `## Use Cases` (`sdd:spec-format-governance`; `check-spec-structure`'s `incomplete-node` flags a leaf that skips them).

4. **Write `<DOMAIN_PATH>/<DOMAIN>.feature`** — pure boolean Gherkin per `sdd:suite-format-governance`. **For a fold (aggregation) node whose rule combines two or more *interacting* sub-conditions, state that rule in closed form — and re-derive its soundness against the real data model — _before_ you derive any scenario** (`sdd:suite-format-governance`). The **order is load-bearing**: scenarios are drawn *from* the rule, so deriving them first is the retrofit-after-the-fact shape that diverged (`github-192`, by example) where stating the rule first converged (`github-224`). A **single-condition** fold may be specified by example, and demanding a closed form of it is **over-firing** — the failure mode of this rule. Closed form is not soundness (`R''` shipped a proof and still deadlocked until re-derived against the real graph, `R'''`), and it buys **convergence, not coverage** — pair the rule with a **mutation sweep** (each interacting condition's mutation breaks a distinct scenario) and a **safety dual** (a liveness scenario passes an over-permissive fold green; assert the case it cannot observe). A **matrix / per-cell** claim is the same rule applied — draw every independent cell as its own scenario, exclude the degenerate cells, and confirm the cells distinct by the sweep. **Cover every use case from the `## Use Cases` section with one-or-more scenarios** (happy path, negative mirror, boundary) — a use case with no scenario is unverified intent; a scenario with no use case is an orphan. **A stated extension earns its scenario by being a path in the CFG**, never by being drawn from the prose — the graph is the single source scenarios derive from, and a suite drawn from a stated list is 1:1 with that list by construction and can no longer surface a hole (`sdd:builder-spec-governance`). So route a divergence covered nowhere back through the graph: add the missing path, and the standing 1:1 edge coverage supplies the scenario. A **forbidden combination** is the same rule in guard form — the CFG carries the decision that refuses it, and the refusal scenario comes from that guard's edge. **On `BACKFILL`, re-derive the scenario set from the CFG's edges** rather than patching the standing suite; the retired corpus is **reference only**, a claim to verify against the current code (`sdd:suite-format-governance`). Each `Then` is an observable boolean — name the artifact a verifier reads to settle it; an act is assertable only when it leaves a trace, and where it records nothing, add the record rather than dropping the act. Never internal state, function names, "sometimes", or how the artifact was authored. Order scenarios by lifecycle stage (the step-down convention). Keep the `.feature` plain; rubric form is legal only inside an `@rubric`-tagged scenario.

   **A `Given` is a test vector, not specification** (`sdd:suite-format-governance` carries the canonical bar and the swap test). Author each `Given`'s apparatus — its domain, entities, names, framing — from a domain **the artifact does not illustrate**. On a revise CR the apparatus never reuses the artifact's existing worked examples; on `BACKFILL` it never reuses the illustrations you read out of source. Read those examples in full at step 1 — they are evidence of the behavior you are specifying; exclude them only from the apparatus you author into a `Given`.

5. **Self-check the `.feature` form before returning.** Run the deterministic form check — the `check-suite` engine (`scripts/check-suite.mts` in the `spec-gate` skill), the executable form of `sdd:suite-format-governance` — scoped to what you just authored:

   ```bash
   node "<spec-gate skill>/scripts/check-suite.mts" --files <the authored .feature path(s)>
   ```

   Exit `0` = form clean; exit `1` prints each `✗ <file>: <reason>`. **Fix every violation** (a non-boolean/hedged `Then`, leaked rubric lingo in an untagged scenario, a missing `Feature`/`Then`, or missing section comments over the sectioning threshold) and re-run until clean **before reporting `STATUS: complete`**. Settling this mechanical bar here spends no cold-judge round on a defect a linter catches every time; the same engine runs fail-closed at the gate (`../spec-gate/`), so an unfixed violation would block there anyway. If `node` is unavailable, self-review against the suite-format bar by hand.

   **A clean form check does not clear an entangled `Given`.** The engine reads form, not apparatus — it reports no violation on a `Given` whose apparatus reuses the artifact's worked examples. Re-read each authored `Given` against the test-vector bar by hand and rewrite the apparatus before returning `STATUS: complete`.

   **A clean form check does not clear a scenario that cannot fail.** The engine reads form, not discrimination — a well-formed `Then`, and a well-formed `@rubric` block, are both reported clean when no subject can ever fail them. Apply the **miss test** (`sdd:suite-format-governance`) to every scenario and every `@rubric` dimension you authored: name a **plausible wrong subject** — a memorizer, a copier, a procedure-follower, a single-brancher — and check that it *loses*. Name none and the scenario is inert; rewrite it. The wrong subject must be plausible — an empty artifact fails everything and clears nothing. Rewrite any dimension grading **presence** (a line is emitted), **restatement** (the doctrine's own words), or **procedure** (the steps, not the judgment). Rewrite the **toothless finding** — a `Then` asserting a signal or finding is *raised* but not its **binding consequence** (it withholds the pass, blocks the gate, changes the outcome): name the wrong subject that raises the finding and acts on nothing, then rewrite the `Then` to assert the consequence. Rewrite the **process-`Then`** — a `Then` asserting **how** the artifact was produced ("co-developed with the code", "written test-first", "refactored before completing", authoring order) rather than its **observable behavior or end-state**; nothing in the artifact or a run reveals the authoring sequence, so it can never be a `Then` — rewrite it to assert the observable behavior instead (`sdd:suite-format-governance`). Before writing any criterion as a dimension, run the **substitutability test** (`sdd:suite-format-governance`): a criterion belongs in a `@rubric` **only if** you accept that strength elsewhere may pay for weakness here — otherwise it is not in the sum at all, it is a boolean `Then`. **Write the trade down** for each dimension you author or revise, in the same record that carries the cut's reason, naming it and **what pays for it** — an unrecorded trade is an unowned selection nobody can disagree with. The duty is **yours alone**: no judge reports a missing record, so nothing catches you skipping it. For a `@rubric`, sum what each named wrong subject **banks** (never zero a dimension to make a point): that sum sits **strictly under** the threshold — a tie passes, since the collapsing `Then` passes a score *at least* the threshold. How far under is **not** a constant: it is your judge's noise at the cut (**cSEM**), measured by scoring the subject more than once, never decreed here. **Ground a dimension or its cut on non-author evidence (cold-instrument doctrine).** When you justify a `@rubric` dimension or its cut with a **measurement** — an ablation Δ, a discrimination count over N runs — it is admissible only if it is **not solely your own**: it meets the non-author evidence standard the doctrine Strategist states canonically (`sdd:doctrine-loop`), never re-listed here. Your own instrument silently assumes the property under test, so a cut grounded on your own measurement alone is **not grounded** — record that it needs non-author or fresh-adversarial evidence. A measurement grounding no dimension or cut is unconstrained; this governs the *evidence*, not the cut *value* (that is the miss-test arithmetic above).

   **In `revise` mode, run the substitutability test over the standing `@rubric` dimensions your CR touches, not only the ones you author.** A dimension already in the sum that fails the test is a **correction**, and a correction is not a deletion: removing it changes the attainable maximum, so the cut it leaves behind is **un-re-derived whether or not its number still needs to change**. Re-derive that cut as a fresh policy call **in the same edit** and record its reason against the new attainable maximum; raise **one clearance per corrected scenario** and never let one blanket approval stand in for each scenario's own cut decision. Route it on the **removal** — never on whether the diff calls the edit `mixed`, which the in-scenario shape is not. The full procedure is *Correcting a standing rubric* (`sdd:suite-format-governance`). A green form check does **not** clear this: `check-suite.mts` reports only the vacuous `sum(max) < threshold` rubric, and a cut nobody re-derived clears that check every time.

   **Read your authored scenarios against each other.** No two scenarios sharing a `When` may demand opposite verdicts on one constructible snapshot (`sdd:suite-format-governance`); narrow one `Given` to exclude the overlap before returning. Overlapping `Given`s whose `Then`s agree, and scenarios whose `When`s name different operations, are not contradictions — the bar is the contradiction, never the overlap. **Specialization is not contradiction:** a general scenario and a specific sibling whose narrower `Given` carves out an exception do not contradict, even when the general `Given` does not literally exclude it — a contradiction is a pair with **no intended winner**. When *you* are authoring the general `Given` fresh, state the exclusion anyway; it is clearer. Never retrofit it into a frozen scenario — that is a narrowing that fires **Clearance**.

   **Check coverage and mirroring before returning.** Every outcome and carve-out the node's `## Use Cases` / README states — including an exception named only in prose — must have at least one scenario; do not report `STATUS: complete` while a stated outcome or carve-out has none — add the missing scenario. A **duty specified on one node of a mirrored pair** (producer/judge, sender/receiver) must be **mirrored on the counterpart node**; do not report complete while only one side carries the duty — specify it on the counterpart too (`sdd:suite-format-governance`).

   Also self-run **referenced-artifact-exists** — `check-spec-state.mts` in `scripts/`, scoped to
   the `spec.md`/`README.md` you just authored or touched:

   ```bash
   node "<spec-gate skill>/scripts/check-spec-state.mts" --files <the authored spec.md/README.md path(s)>
   ```

   Exit `0` = every referenced path resolves; exit `1` prints each `✗ <file>: references nonexistent
   artifact ...`. Fix every violation the same way — a broken reference to a skill/engine/artifact
   that never existed is a content gap, not a typo to shrug at.

## Responding to a `change` verdict

Load `sdd:remediation-governance` — the findings are **evidence, not a work order**. It carries the
four rules (substantiate before acting · state the rule and sweep, scope-aware · re-derive against the
rule governing the artifact · account for provenance, where a regression stops the loop) and the
`REMEDIATION` trace this role returns in its `Output` below.

## Output (the conductor collects)

```
REMEDIATION:       <per finding answered: verdict, rule, swept, ruled-out, provenance — `sdd:remediation-governance`; omit when no verdict was answered>
STATUS:             complete | needs-input | blocked
SCENARIOS_WRITTEN:  <count>
NOTES:              <what was written / revised>
GOVERNANCES_LOADED: [ every governance name loaded before writing — required, [] when none, never written into spec.md or the .feature ]
QUESTIONS:          [ batched, when needs-input ]
CONTENT_GAPS:       [ { artifact, location, gap } ]   # become <!-- open: --> markers
OBSERVATIONS:       [ { owner: architect | strategist, note, evidence } ]
```

