SDD Ownership Governance
Who may write what. Every act in the SDD workflow has a write leash; this skill is the canonical
matrix. The field definitions are in sdd:lifecycle-governance; the legality of the resulting state
is in sdd:gate-validation-governance; the plan/ledger write split is in sdd:combat-log-governance.
Write-ownership matrix
| Field / artifact |
Written by |
Never written by |
status |
the gate skill (spec-gate) — on a human verdict, or to match a conductor self-assertion within leash |
the conductor, any producer |
project-path |
the conductor (at scaffold; scaffold-project-spec) |
producers, the gate skill |
run-level leash + approach — the kind: leash ledger line (session-local; to the conductor's own ledger shard, not spec.md frontmatter — the conductor's autonomy bar, start-mission) |
the conductor (initial evaluation) |
producers, the gate skill |
approval self-assertion (verdict: approve/pause + by: agent/none + why) |
the conductor (synthesis only) |
producers, the gate skill |
approval human ratification (verdict: approve/reject + by: <name>) |
the gate skill (spec-gate), in-session position only |
the conductor, any producer, any spawned delegate |
<!-- open: --> markers |
the conductor |
producers (they emit gaps, not markers) |
produced-by map |
the conductor (records the resolved producer per role at production) |
producers, judges, the gate skill |
contested-type → chosen-plugin state (.agents/sdd/) |
the conductor (or start-mission for a contested artifact-type); distinct from produced-by |
producers, judges, the gate skill |
combat-log report / correction / halt lines |
the conductor (append-only, to the plan's *.log.jsonl) |
producers, judges, the gate skill |
ledger gate line — self-asserted (by: agent) |
the conductor (append-only, to its own ledger shard) |
producers, judges |
ledger gate line — human-ratified (by: <name>) |
the gate skill (spec-gate), in-session position only |
the conductor, producers, judges |
ledger followup line — the durable follow-up record (class: blocking/backlog) |
the conductor (append-only, to its own ledger shard, at handoff, unconditionally — no permission, no forge, no human) |
producers, judges, the gate skill |
ledger strategy lines |
the doctrine-loop Scanner (append-only) |
the conductor, producers, judges |
spec.md body + the .feature |
the spec-producer |
the conductor, judges, solution/impl producers |
a @pinned scenario (user-owned) |
the user (in-session) |
every agent role — may propose, never executes a change/removal without in-session user authorization |
<unit>.solution.md |
the solution-producer |
the spec-producer, judges |
plan brief + todos |
the conductor |
producers, judges |
| implementation + its verification |
the impl-producer |
the impl-judge (it runs, never authors) |
Each appended *.log.jsonl / ledger-shard line carries its writer's pseudonymous handle
(SDD_HANDLE if set, else omitted — attribution falls back to the git commit author; never
user.email, never a git config read); combat-log lines additionally carry a write-time UTC ts,
while ledger lines carry none (sdd:combat-log-governance). The in-file handle / by is
advisory — the git commit signature is the attestation.
Producer write boundary
A spec-producer writes the spec.md body and the .feature only. It must not write the
control frontmatter (status, project-path, approval, produced-by) or the .agents/sdd/
resolution state. A required input it cannot supply or infer is returned as a CONTENT_GAP — the
conductor turns it into an <!-- open: --> marker. Producers do not write markers directly.
The conductor writes <!-- open: --> markers, the produced-by map, the run-level leash (the
kind: leash line to its own ledger shard, session-local — not a spec.md frontmatter field), and — when it
self-asserts a gate within the effective leash — the provisional approval.<gate> entry
(verdict: approve + by: agent with the why derivation; a halt is verdict: pause with its
why and no by). There is no leash field in the approval entry — the leash is the run-level
record on the ledger. The gate skill writes status (on a human verdict or to match the
conductor's in-leash self-assertion) and the human ratification of approval (rewriting by: agent
→ by: <name>).
Ratification authority is positional. A human-attributed gate write — status → approved | implemented, a verdict carrying by: <name>, the human-ratified ledger gate line, and the freeze
— belongs to the in-session position that holds the real user channel. By default this is
trivially satisfied: the conductor is the main session, so the position that grills is the
position that ratifies. The rule bites only in the headless / fan-out fallback, where the
automaton runs as a spawned subagent with no user channel: it then writes only by: agent
self-assertions and pause halts, and on a human gate emits a verdict packet and stops — it never
writes a human ratification, even when a coordinator relays "the user approved" (a relayed claim
is not user confirmation). This is positional, not definitional: the same conductor definition run
in-session may perform the write. A self-assertion is provisional: the act is delegable, the
accountability is not — the human ratifies the trail. No role writes outside the spec it owns or
spawns specs on its own.
Freeze (write constraint)
Never write a frozen .feature. Once a .feature carries its @frozen tag, no role — producer,
judge, solution-producer, or conductor — may add, remove, or rewrite its scenarios. A discovered gap
that requires changing specified behavior is a BLOCKER returned upward (the file must unfreeze and
its layer revert to draft — the gate/skill decides), never an in-place edit. The matching lifecycle
rule (what freezing means as a state) is in sdd:lifecycle-governance.
The freeze binds the contract only (spec.md + the suite). The combat log (the plan's
*.log.jsonl) and the durable ledger/ shards are exempt: they are operational provenance, never
frozen, and the conductor and Scanner keep appending to their own shards within their boundaries above
even while a file sits @frozen.
A judge — spec-judge or impl-judge — must not modify spec.md or the suite: it reports, it does
not patch.
User-owned scenarios (@pinned)
A @pinned scenario is user-owned — the one scenario the spec-producer does not
own. Any agent role may propose changing or removing it, but never executes the change
without in-session user authorization — the authority of a human ratification (positional, not
relayable, not self-assertable within leash). Only the user applies @pinned. This is grounded in
ownership, not freeze: it holds at draft and survives a re-open, since ownership does not lapse
when a file unfreezes. The marker and its seed-growth role are sdd:suite-format-governance.
Key points (read-check)
- One writer per field/artifact (the matrix) — no role writes outside the spec it owns or spawns.
- Never write a frozen
.feature — a behavior-changing gap is a BLOCKER returned upward, never
an in-place edit.
- Human ratification is positional — the in-session channel only; never relayed, never
self-asserted within leash.
- A
@pinned scenario is user-owned — the agent proposes, never executes a change or removal
without in-session user authorization.
1---2name: ownership-governance3description: Partial Skill: invoke by name only4---56# SDD Ownership Governance78Who may write what. Every act in the SDD workflow has a write leash; this skill is the canonical9matrix. The field definitions are in `sdd:lifecycle-governance`; the legality of the resulting state10is in `sdd:gate-validation-governance`; the plan/ledger write split is in `sdd:combat-log-governance`.1112## Write-ownership matrix1314| Field / artifact | Written by | Never written by |15|---|---|---|16| `status` | the gate skill (`spec-gate`) — on a human verdict, or to match a conductor self-assertion within leash | the conductor, any producer |17| `project-path` | the **conductor** (at scaffold; `scaffold-project-spec`) | producers, the gate skill |18| run-level leash + approach — the `kind: leash` ledger line (session-local; to the conductor's own ledger shard, **not** spec.md frontmatter — the conductor's autonomy bar, `start-mission`) | the **conductor** (initial evaluation) | producers, the gate skill |19| `approval` **self-assertion** (`verdict: approve`/`pause` + `by: agent`/none + `why`) | the **conductor** (synthesis only) | producers, the gate skill |20| `approval` **human ratification** (`verdict: approve`/`reject` + `by: <name>`) | the gate skill (`spec-gate`), **in-session position only** | the conductor, any producer, any spawned delegate |21| `<!-- open: -->` markers | the **conductor** | producers (they *emit gaps*, not markers) |22| `produced-by` map | the **conductor** (records the resolved producer per role at production) | producers, judges, the gate skill |23| contested-type → chosen-plugin state (`.agents/sdd/`) | the **conductor** (or `start-mission` for a contested artifact-type); **distinct from `produced-by`** | producers, judges, the gate skill |24| combat-log `report` / `correction` / `halt` lines | the **conductor** (append-only, to the plan's `*.log.jsonl`) | producers, judges, the gate skill |25| ledger `gate` line — self-asserted (`by: agent`) | the **conductor** (append-only, to its own ledger shard) | producers, judges |26| ledger `gate` line — human-ratified (`by: <name>`) | the gate skill (`spec-gate`), **in-session position only** | the conductor, producers, judges |27| ledger `followup` line — the durable follow-up record (`class: blocking`/`backlog`) | the **conductor** (append-only, to its own ledger shard, at handoff, **unconditionally** — no permission, no forge, no human) | producers, judges, the gate skill |28| ledger `strategy` lines | the doctrine-loop Scanner (append-only) | the conductor, producers, judges |29| `spec.md` body + the `.feature` | the **spec-producer** | the conductor, judges, solution/impl producers |30| a **`@pinned` scenario** (user-owned) | the **user** (in-session) | every agent role — may **propose**, never **executes** a change/removal without in-session user authorization |31| `<unit>.solution.md` | the **solution-producer** | the spec-producer, judges |32| plan brief + `todos` | the **conductor** | producers, judges |33| implementation + its verification | the **impl-producer** | the impl-judge (it *runs*, never authors) |3435Each appended `*.log.jsonl` / ledger-shard line carries its writer's pseudonymous `handle`36(`SDD_HANDLE` if set, else omitted — attribution falls back to the git commit author; **never**37`user.email`, never a `git config` read); combat-log lines additionally carry a write-time UTC `ts`,38while ledger lines carry none (`sdd:combat-log-governance`). The in-file `handle` / `by` is39**advisory** — the git commit signature is the attestation.4041## Producer write boundary4243A **spec-producer** writes the `spec.md` body and the `.feature` only. It must **not** write the44control frontmatter (`status`, `project-path`, `approval`, `produced-by`) or the `.agents/sdd/`45resolution state. A required input it cannot supply or infer is returned as a `CONTENT_GAP` — the46conductor turns it into an `<!-- open: -->` marker. Producers do not write markers directly.4748The **conductor** writes `<!-- open: -->` markers, the `produced-by` map, the run-level leash (the49`kind: leash` line to its own ledger shard, session-local — not a spec.md frontmatter field), and — when it50self-asserts a gate within the effective leash — the provisional `approval.<gate>` entry51(`verdict: approve` + `by: agent` with the `why` derivation; a halt is `verdict: pause` with its52`why` and no `by`). There is no `leash` field in the `approval` entry — the leash is the run-level53record on the ledger. The **gate skill** writes `status` (on a human verdict or to match the54conductor's in-leash self-assertion) and the human ratification of `approval` (rewriting `by: agent`55→ `by: <name>`).5657**Ratification authority is positional.** A human-attributed gate write — `status → approved |58implemented`, a verdict carrying `by: <name>`, the human-ratified ledger `gate` line, and the freeze59— belongs to the **in-session position** that holds the real user channel. By default this is60trivially satisfied: the **conductor is the main session**, so the position that grills *is* the61position that ratifies. The rule bites only in the **headless / fan-out fallback**, where the62automaton runs as a **spawned subagent** with no user channel: it then writes only `by: agent`63self-assertions and `pause` halts, and on a human gate emits a verdict packet and stops — it never64writes a human ratification, **even when a coordinator relays "the user approved"** (a relayed claim65is not user confirmation). This is positional, not definitional: the same conductor definition run66in-session may perform the write. A self-assertion is **provisional**: the act is delegable, the67accountability is not — the human ratifies the trail. No role writes outside the spec it owns or68spawns specs on its own.6970## Freeze (write constraint)7172**Never write a frozen `.feature`.** Once a `.feature` carries its `@frozen` tag, no role — producer,73judge, solution-producer, or conductor — may add, remove, or rewrite its scenarios. A discovered gap74that requires changing specified behavior is a `BLOCKER` returned upward (the file must unfreeze and75its layer revert to `draft` — the gate/skill decides), never an in-place edit. The matching lifecycle76rule (what freezing *means* as a state) is in `sdd:lifecycle-governance`.7778The freeze binds the **contract only** (`spec.md` + the suite). The combat log (the plan's79`*.log.jsonl`) and the durable `ledger/` shards are **exempt**: they are operational provenance, never80frozen, and the conductor and Scanner keep appending to their own shards within their boundaries above81even while a file sits `@frozen`.8283A judge — spec-judge or impl-judge — must not modify `spec.md` or the suite: it reports, it does84not patch.8586## User-owned scenarios (`@pinned`)8788A `@pinned` scenario is **user-owned** — the one scenario the spec-producer does **not**89own. Any agent role may **propose** changing or removing it, but **never executes** the change90without **in-session user authorization** — the authority of a human ratification (positional, not91relayable, not self-assertable within leash). Only the user applies `@pinned`. This is grounded in92**ownership, not freeze**: it holds at `draft` and survives a re-open, since ownership does not lapse93when a file unfreezes. The marker and its seed-growth role are `sdd:suite-format-governance`.9495## Key points (read-check)96971. **One writer per field/artifact** (the matrix) — no role writes outside the spec it owns or spawns.982. **Never write a frozen `.feature`** — a behavior-changing gap is a `BLOCKER` returned upward, never99 an in-place edit.1003. **Human ratification is positional** — the in-session channel only; never relayed, never101 self-asserted within leash.1024. **A `@pinned` scenario is user-owned** — the agent proposes, never executes a change or removal103 without in-session user authorization.