Skip to content
Back to skills

Sd Write Spec

ASecurity

Write a scope's full requirement set -- FR and NFR documents -- from the intent/discovery layer, in one pass. The narrowing step of the engineering diamond, the third of legion's three: it crystallizes the IEEE 830-style requirement set the executor consumes, every SHALL naming what earned it and every gap escalated rather than resolved in-body. It is not part of the sd-service-design pipeline and has its own entry point. Two input modes: from an intent alone (system work) or from a landed se...

  • 3 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 23, 2026
researchgoshellbashnodesecurityperformance

Works with

  • cli

Security analysis

A100/100

Scanned September 26, 2026

npx -y skills add runlegion/legion --skill sd-write-spec --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Sd Write Spec?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Sd Write Spec
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/runlegion-sd-write-spec/badge)](https://www.skillsdirectory.com/skills/runlegion-sd-write-spec)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: sd-write-spec
description: |
  Write a scope's full requirement set -- FR and NFR documents -- from the intent/discovery
  layer, in one pass. The narrowing step of the engineering diamond, the third of legion's
  three: it crystallizes the IEEE 830-style requirement set the executor consumes, every
  SHALL naming what earned it and every gap escalated rather than resolved in-body. It is
  not part of the sd-service-design pipeline and has its own entry point. Two input
  modes: from an intent alone (system work) or from a landed service design (product
  work). Invoke when a scope is ready to move from discovery to a buildable spec.
version: 0.2.0
user-invocable: true
allowed-tools: Bash, Read
---

# Spec writer: the intent/discovery layer in, a buildable requirement set out

Legion's work runs three diamonds: the problem (discover, define), the solution design
(develop, deliver design assets and the design system), and the engineering (research and
toys, then spec and build). This skill is where the engineering diamond narrows. Upstream
is judgment -- claims, insights, design, the abductive leap. Downstream is execution -- an
agent that follows the spec without needing to have done the thinking. The spec is where
the judgment becomes rules, and its whole worth is that a rule-follower can execute it
without a hole to fall into. So the spec is complete or it is escalated; it is never left
ambiguous for someone who cannot resolve the ambiguity.

## Two invariants (bind every requirement)

- **Every SHALL names what earned it.** A requirement's `traces_to` cites the source that
  makes it true: a proven toy or experiment, a supported or bounded insight (by id), a
  settled intent proposal, an operator ruling on a resolved open question, a settled
  boundary rule, an actor's core stake, an ecosystem moment of truth. The list is
  exhaustive: a mapping rule that would grant a SHALL on anything else is a defect in one
  of the two, to reconcile rather than to follow. A candidate SHALL whose only ground is
  "the current system does this" is the let-go-of-the-past fault in spec clothing -- it is
  how the legion-cmd spec drifted into a rebuild of the guards it existed to replace.
  Unproven ground (an intent proposal with `needs_pressure_test`, or anything grounded only
  in present behavior) routes to a **RESEARCH document**, not a SHALL: build the toy first.
- **UNCLEAR goes up, never resolved in-body.** A contradiction or silent gap in the inputs
  is escalated, not decided. Land the set as far as it goes, name the gap in the affected
  requirement, and carry every gap in your report to your caller -- the caller routes it to
  whoever owns the answer. The report to your caller IS the escalation: do not signal the
  owner directly and do not post the run to the bullpen, both of which wake the whole team
  for a cost the report already carries, and the caller is the one who wakes the owner. (A
  run with no caller is the only case where the async
  `legion signal --to <owner> --verb question` applies.) Resolving a gap in-body (labelling
  it DECIDED and moving on) is the exact failure the meaning-drift audit found in the
  issue-writer; this skill does not repeat it.

## Distill each requirement as you write it

A requirement is a block. Distill it at the block, as you write it, before the next one --
not as a pass over the finished set (the checks are the `legion-distill` skill; the writer
runs them here, a reader checks after). The block's one reader is a rule-follower who
executes it without having done the thinking, so the test is: can that reader act on this
requirement from its own text and its `traces_to`, with no hole to fall into? Run four
checks per requirement:

- **One SHALL.** The requirement states exactly one thing to build. Two things are two
  requirements.
- **Carries.** A rule-follower executes it from its text plus its cited source -- no term
  left undefined, no step left to guess, acceptance naming an observable rather than an
  intention.
- **Traced.** `traces_to` names what earned it (invariant 1). A SHALL with no earner is a
  stop.
- **No invention is a stop.** If finishing the block needs a fact the inputs do not give --
  a metric with no measurement, a resolution to a contradiction, a mechanism the intent only
  proposes -- HALT that block. Do not fill the hole. Escalate it (invariant 2) or route it to
  RESEARCH, and write no requirement over an invented fact. A block you cannot finish without
  inventing is the gap to send up, not to smooth.

The set is done when every block carries or is escalated, never when a hole was filled to
make a block read complete.

## Input modes

- **Intent-only** (system work -- legion-cmd is the case): the intent alone. An intent may
  or may not carry a `claims` array. When it does, each claim's `right_if` becomes
  acceptance criteria. When it does NOT (a migrated or older intent), derive from what the
  intent actually has: `direction.proposals`, `current_state`, `actors`, `boundaries`,
  `open_questions`. Do not assume the claims-bearing shape -- read the intent's own fields.
- **Service-design** (product work): the intent plus the landed ecosystem, personas,
  journeys, blueprints, and Discovery. "Landed" means the document exists in the store and
  validates against its schema; `draft` status is fine. Read every input by id first
  (`legion document view <id> --json`); when the caller supplies only the surface, find the
  rest with `legion document list --doc-type <type> --surface <surface> --json`. An
  archived predecessor of another doc-type (a painmatrix) is not a Discovery; migrate it
  first. The requirement set is derived from all of them, and each requirement traces to
  the specific source it came from.

A missing artifact and a gap inside an artifact are different failures. A missing or
schema-invalid artifact PARKS the run; step 1 says what parking means. A gap inside a
landed artifact is invariant 2: land the set, name the gap, escalate. A weak artifact
(a Discovery whose insights are all `blocked`) is landed, not missing; the run proceeds
and the verdicts decide what earns what.

There is no story layer. A requirement traces DIRECTLY to its source in the intent and the
ecosystem (decided 2026-06; reconfirmed) -- the intent's claims and the ecosystem's moments
of truth carry what a user-story layer would have, so `traces_to` points straight at them.

## The mapping

**Both modes:**

- `direction.proposals` -- a settled proposal (`status: settled`, no `needs_pressure_test`)
  becomes a SHALL; a `needs_pressure_test` proposal routes to RESEARCH, never a SHALL. A
  proposal that is `proposed` but NOT pressure-test-flagged has not earned a SHALL either:
  if the intent clearly commits to it as direction, it becomes a **SHOULD** (recommended,
  not mandatory); if it reads as a "maybe" or is genuinely undecided, escalate it and spec
  nothing on it. Only `settled` grounds a SHALL.
- `current_state` -- `real` vs planned governs tense (a SHALL for what must exist), never
  priority. A `real` entry that records a proven experiment with cited sources (an audit
  corpus with reproductions, a probe script that found real defects) IS invariant 1's "proven
  toy or experiment" and earns a SHALL; a `real` entry that merely describes the present
  system earns nothing. A `known_gap` is a pain the requirement addresses, not a
  requirement itself; it may ground an NFR's `traces_to` alongside the actor's stake that
  says the gap must be closed, never alone.
- `boundaries` -- an entry whose `note` states a rule the scope must hold to ("must never
  depend on X", "the dependency runs one way") is a settled constraint and earns a SHALL,
  folded into an FR since no constraint doc-type exists. An entry that only assigns
  ownership is scoping, not a requirement: when it hands a capability to another owner,
  that capability is out of this scope, and a requirement that would cross the line is the
  boundary violation to name and escalate rather than spec.
- `open_questions` -- an unresolved one, or any unresolved contradiction, is escalated,
  not resolved (invariant 2). A resolved one whose `resolution` records an operator
  ruling earns a SHALL for the outcome it names. A field elsewhere in the intent that
  still contradicts that resolution (a settled proposal that assumes cancelled machinery)
  is an UNCLEAR, not a fact; name it and escalate it to the intent's owner.
- When a resolved decision names machinery as required WHILE a `needs_pressure_test`
  proposal proposes the same machinery, split it: the settled WHAT (the outcome, the
  behavior) becomes a SHALL; the unproven HOW (the specific mechanism) routes to RESEARCH,
  and the FR notes the dependency. A resolved ruling on the outcome does not make the
  unproven mechanism a SHALL.

**Service-design mode adds** (these fields exist only when the artifacts do -- do not look
for them in intent-only mode):

- **Discovery insights, by `status`** (the schema's verdict field). `supported` earns a
  SHALL for the need it evidences. `bounded` earns a SHALL whose scope is the bound the
  insight states, and nothing beyond it. `contradicted` earns nothing and cancels any
  candidate whose only ground it was; say so in the report. `blocked` and
  `saturated-unevidenced` are unproven ground: they earn nothing and kill nothing, a
  requirement with another earner stands, the insight may be cited in a description, and
  its `next_probe` folds into the RESEARCH document for the mechanism it would test.
- **FRs** from blueprint `steps[].layers` (`backstage`, `support`) -- these say what the
  system must do, so they are where a requirement is found, never what makes it true. A
  blueprint step is a supporting token, never the earner: the earner is the supported
  insight, moment of truth, or settled proposal the step serves. A step with none of
  those behind it earns no SHALL; it takes a SHOULD from the journey goal it serves, per
  the priority rule below, and where it serves no goal either it is escalated. From the
  ecosystem's `moments_of_truth`: a moment of truth's
  `success` text earns a SHALL; its `failure` text is what the `errors` object guards
  against and earns nothing on its own. A persona's own `moment_of_truth` supports a
  citation; only the ecosystem's earn.
- **Error-handling requirements** from blueprint `steps[].fail_points` (where the service
  breaks) and the ecosystem's `failure_modes` -- what must happen when it does. These
  populate the requirement's `errors` object. A step's `frictions` (customer hurt; the
  field that superseded `pain_points`, which older blueprints still carry) are what the
  requirement must relieve, not where it breaks. A blueprint carrying none of these leaves
  `errors` to the ecosystem's `failure_modes` alone. A failure mode whose `recovery` is
  undecided is an UNCLEAR carried in `errors`, not a rule.
- **Acceptance criteria** for a service-design FR come from the blueprint step or the
  moment of truth it serves -- the step's success condition, or the MOT's `success`, is
  what `verification.acceptance` checks. In intent-only mode with a `claims` array, the
  claim's `right_if` is the acceptance. In intent-only mode WITHOUT claims, acceptance
  comes from the proposal's own text and the intent's cited evidence: each criterion names
  one observable, and where the intent cites a defect issue with a reproduction, the
  pre-fix reproduction is a criterion (the harness must catch it).
- **NFRs** from moments of truth and non-functional concerns. A `known_gap` is evidence of
  the pain, not an earner: cite it beside the stake that earns the NFR, and where no stake
  says the gap must be closed, escalate it rather than writing a SHALL on the gap alone.
  In intent-only mode, NFRs come from `actors` stakes and the source notes in
  `meta.sources` (a cited
  reflection is read through its note there; there is no command to view a reflection as a
  document).
- **Priority derived at the spec boundary and shown in `traces_to`.** Personas carry
  `needs[].priority` (SHALL/SHOULD/MAY) and the skill does not honour them as earners: a
  persona-stated SHALL is a claim to check, and the earner is the supported insight or
  moment of truth behind it. When none exists, escalate the need; do not spec it on the
  persona's word. What earns what: a supported insight or a moment of truth's success ->
  **SHALL**; the journey's `meta.goal`, served by a step with no insight behind it ->
  **SHOULD**; a journey row's `opportunities` entry or a persona need the inputs mark as a
  delighter -> **MAY**. In intent-only mode, priority derives from the same shape one layer
  up: a settled outcome, a ruling, or an actor's core stake -> SHALL, a served goal ->
  SHOULD, a nice-to-have or an uncommitted consumer -> MAY.
- **A pre-existing spec on a sibling surface** is not an input and is not superseded by
  this run. Read it, report every requirement of yours that overlaps one of its, and every
  trace of its that now points at an archived or blocked ground. Whether the old set is
  retired is the crit's call.

### The `traces_to` grammar

`traces_to` is one string: the source tokens that earned the requirement, then the
derivation: `<token>[; <token>...] -- <PRIORITY> because <rule>`. Tokens are
`intent.<json-path>` (e.g. `intent.direction.proposals[3]`,
`intent.open_questions.FQ-1.resolution`), `discovery.<insight-id>`, `moment_of_truth.<n>`,
`blueprint.step.<n>`, `journey.phase.<n>`, `persona.<slug>.needs[<i>]`, and
`boundary.<owner>`. The first token is the earner; the rest support. Only a token naming
something invariant 1 lists may lead: `intent.<json-path>` for a settled proposal, a
ruling, an actor's stake, or a proven experiment; `boundary.<owner>` for a settled
boundary rule; `discovery.<insight-id>` for a supported or bounded insight;
`moment_of_truth.<n>`. `blueprint.step.<n>`,
`journey.phase.<n>`, and `persona.<slug>.needs[<i>]` are supporting tokens only.
`meta.priority` holds the value; `traces_to` shows how it was derived. That is one
source, shown twice, not two sources.

Every NFR needs `category` (a closed enum:
performance/scalability/reliability/availability/security/privacy/observability/maintainability/compatibility/usability/compliance
-- use `scalability` for locality, `maintainability` for policy-as-data), `metric`,
`target`, and `measurement`; an NFR without a real measurement is an aspiration, not an NFR
-- decline to invent a performance target with no way to measure it (escalate the threshold
as an open question instead). A target of zero that is the failure mode's own definition
(zero leaked handles, zero differing verdicts) is not invented; a count or a duration with
no number in the inputs is.

## Procedure

1. **Check every input exists and validates, then read each by id in full.** The intent
   always; in service-design mode the ecosystem, personas, journeys, blueprints, and
   Discovery too. Do the existence check before the reading: a missing or schema-invalid
   input parks the run, and there is nothing to read 60KB of inputs for. Parking means:
   land nothing, write the report naming the missing input and its unblock, and signal the
   surface's owner (`--verb request`). Do not treat the intent's `meta.sources` as inputs;
   they are provenance, read through the intent's notes.
2. **Resolve the schemas** by `x-doc-type` (`requirement` and `nfr`) from
   `legion document list --doc-type schema --json`; read their `required` and `properties`
   as the contract. Requirement requires `meta`, `title`, `description`, `traces_to`
   (`meta` requires `id`, `type`, `surface`, `status`, `priority`, `owner`, `date`,
   `author`); NFR additionally requires `category`, `metric`, `target`, `measurement`,
   `verification`. `meta.priority` is the single source of a requirement's priority value;
   `traces_to` shows the derivation (see the grammar above) and nothing else repeats it.
   Status lands `draft`. The `list` output's `payload` is a JSON string; parse it a second
   time to reach `x-doc-type`.
3. **Derive the whole set for the scope in one pass**, numbered `FR-<SURFACE>-NNN` /
   `NFR-<SURFACE>-NNN`. The typed id IS the id, so you MUST pass `--id <typed-id>` on
   create (see step 5) -- omit it and every document gets a random UUID, breaking the
   numbering and every `depends_on`/`nfr_refs`. The store does not check the two against
   each other: it takes the storage id from the flag and never reads `meta.id`, so a
   mismatched pair lands silently. The storage id is a projection of `meta.id` kept in
   sync by you, not a second source of truth.
   Set `depends_on` between requirements and `nfr_refs` from an FR to the NFRs that bound
   it -- these cohere only when the set is written together, which is why it is one
   invocation. `constraint_refs` points at a `constraint` doc-type that does NOT exist in
   this store: do not try to land constraints; fold a constraint-like rule into an FR and
   say why (a technology-choice SHALL, for instance).
4. **Route unproven ground to RESEARCH, escalate UNCLEAR.** A claim the inputs cannot
   ground becomes a RESEARCH document (its own doc-type -- resolve its schema by
   `x-doc-type: research`; its meta is a DIFFERENT shape from a requirement's, so template
   it off the research schema, not off an FR). The shape, so you need not read the whole
   schema to start: `finding` is one sentence and for a not-yet-built toy reads
   `UNTESTED: <hypothesis>`; every entry in `claims` is `unverified`;
   `provenance.verification` counts them as `unverifiable`; `meta.status` is `draft` (its
   enum is draft/review/done, not the requirement's). The requirement cannot cite it
   through a field -- there is no `research_refs` and `traces_to` is one string that names
   the SHALL's earner. Carry the link the other way: name the dependency in the FR's
   `description`, and set the research doc's `links[]` back to the FR with
   `relationship: informs` (the field is required). A contradiction between inputs is
   named in the requirement and signalled up, not silently resolved.
5. **Validate one of EACH doc-type before batch-creating** -- an FR, an NFR, and a RESEARCH
   sample (three different meta shapes). The store refuses a schema violation on every path;
   catching it on one document is cheaper than on the whole set. Three id/priority rules the
   schemas do not spell out:
   - A **requirement** carries priority in `meta.priority` AND you pass `--priority <same>`
     on create -- the flag populates the queryable storage column, which stays null if you
     only set the payload; keep them equal (this is a projection kept in sync, not a second
     source of truth).
   - An **NFR** carries priority only in `meta.priority`; the `--priority` flag is
     requirement-only, so the NFR's storage column stays null. That is a store limitation,
     not yours to work around -- do not omit `meta.priority`.
   - A **RESEARCH** doc has no `meta.id`/`surface`/`owner`/`priority`, but it DOES take a
     typed storage id: `RESEARCH-<SURFACE>-<SLUG>` (the store accepts `--id` on any
     doc-type, and the cmd research set already uses this form). Pass it on create so the
     FR's description and the prediction fingerprint can name something readable.
   - **Create order**: NFRs first, then the FRs that reference them, then the RESEARCH
     documents whose `links[]` point at FRs. The store checks neither reference existence
     nor `depends_on` cycles on create, so a wrong order lands silently; the order is your
     only check.
   - Write the JSON files with a Bash heredoc; the skill's tools are Bash and Read.

   ```
   legion document validate --schema <requirement-schema-id> --file fr-sample.json
   legion document validate --schema <nfr-schema-id> --file nfr-sample.json
   legion document validate --schema <research-schema-id> --file research-sample.json
   legion document create --doc-type requirement --id FR-<SURFACE>-001 --priority SHALL --owner <agent> --surface <surface> --from <file>
   legion document create --doc-type nfr --id NFR-<SURFACE>-001 --owner <agent> --surface <surface> --from <file>
   legion document create --doc-type research --id RESEARCH-<SURFACE>-<SLUG> --owner <agent> --surface <surface> --from <file>
   ```

6. **Emit the predictions** (see Instrumentation below): one for the set, one per RESEARCH
   document. Emit after the documents land, so every prediction names a real id.
7. **Report** the set: the FR and NFR ids, the RESEARCH documents spun off, every gap
   escalated with the signal sent for it, the overlap with any pre-existing spec on a
   sibling surface, and every prediction id emitted with its claimed confidence. One
   scope's spec per invocation. When you run as a spawned agent, deliver the report with
   SendMessage and end your turn with one line, so the harness's idle notice does not
   repeat a truncated copy of it.

## Instrumentation

The writer makes judgment calls the pipeline should score, and the uncertainty engine is
how a judgment becomes a track record instead of a belief. Instrument the judgments, not
the mechanics: priority and RESEARCH routing follow from the inputs' `status` fields and
are not predictions, so they get no emission. Two things are predictions.

- **The set covers the intent.** One prediction, under this skill's name, that the crit
  will accept the set without adding a requirement the inputs earned or rejecting one as
  unearned. Stake it from what you actually saw. Anchors: an intent with `claims` and a
  Discovery whose insights are `supported`, with nothing escalated, sits near 0.8; a
  claims-less intent specced from settled proposals alone sits near 0.6; a set whose
  Discovery insights are all `blocked`, or that leans on rulings and actor stakes rather
  than settled proposals, starts near 0.4. Two anchor conditions do not compound; pick the
  lowest that applies and let the escalations do the rest. Weigh the escalations rather
  than counting them. A gap named inside a requirement (FQ-4 bounding a trait registry) is
  a place the crit may reject that requirement, and lowers the number. A requirement you
  declined to write because its only ground was blocked or open is the add-risk: if a
  reader could argue the inputs earned it, the crit may add it, and that lowers the number
  too. Only an open question whose ground could earn nothing under any reading leaves it
  untouched. For the payload count, an escalation is one distinct gap named in a
  requirement's description or `errors`, or in the report; the same gap in two
  requirements counts once. Do not default to one number -- a writer that always says 0.8
  gives the estimator nothing to learn from.

  ```
  legion uncertainty emit --surface legion.sd --feature-key sd.write-spec \
    --session-id "$CLAUDE_CODE_SESSION_ID" --orphan-ttl-days 180 \
    --input-fingerprint <intent-id>:spec:<surface> --claimed-confidence <p> \
    --payload '{"intent":"<intent-id>","surface":"<surface>","mode":"<mode>","fr":<n>,"nfr":<n>,"research":<n>,"escalations":<n>}'
  ```

- **Each RESEARCH hypothesis holds.** One prediction per RESEARCH document: the probability
  the toy, once built, confirms the hypothesis. This is the only place the writer stakes a
  claim about the world rather than about its own artifact, and it is where the spread is
  real. Derive it from the inputs' evidence for the mechanism: a `current_state.real` entry
  that says the mechanism is proven in miniature, with cited issues, earns roughly 0.7 to
  0.8; a proposal argued from first principles with no experiment behind it sits near 0.5;
  a `known_gap` or open question that names it unproven at this shape pulls it toward 0.3.
  A settled sibling proposal that supports the outcome but not the mechanism is weak
  evidence: it may move the number a little, never into the next band. A narrative
  instance in a journey (one probe that worked once) is not an experiment; it may nudge
  within a band, never across one. Name the evidence you used in the payload.

  This payload carries the one free-prose field in the pipeline, so build it in a file
  rather than inline: an apostrophe in your evidence line ends the shell's single quote,
  and because emit exits 0 with no read-back it would write a mangled row rather than
  fail in front of you.

  ```
  cat > research-pred.json <<'JSON'
  {"research":"<research-doc-id>","informs":["FR-..."],"evidence":"<one line>"}
  JSON
  legion uncertainty emit --surface legion.sd --feature-key sd.research-hypothesis \
    --session-id "$CLAUDE_CODE_SESSION_ID" --orphan-ttl-days 180 \
    --input-fingerprint <research-doc-id> --claimed-confidence <p> \
    --payload "$(cat research-pred.json)"
  ```

The emit mechanics -- session id and model, the exit-0 rule, the 180-day orphan window,
non-blocking emission, never self-witnessing -- are held once in the sd-service-design
skill (Instrumentation, "Emit mechanics") and bind here. What is this writer's alone:
`<mode>` is the literal `intent-only` or `service-design`, and the report records each
prediction id with the surface string, since the crit rebuilds the set fingerprint from
intent id and surface.

**The issue, when there is one.** When this run writes the spec for a known issue -- your
caller's brief names it as `<owner>/<repo>#<n>` -- add `--issue <owner>/<repo>#<n>` to both
emits above, so legion-verify finds them by that issue (an exact match on the reference,
never a search of payload text). A spec written from an intent with no issue behind it
emits exactly as shown, without `--issue`; never invent an issue to fill the flag.

**Who witnesses, and when.** A prediction nobody witnesses is an orphan and is excluded from
calibration, so the witness event is named here, not left to be discovered:

- The set prediction is witnessed by the **crit** (the acceptance step that moves documents
  past `draft`), which reads the id from this run's report and confirms it by rebuilding
  the fingerprint `<intent-id>:spec:<surface>` -- witness takes the id, never the
  fingerprint, and no lookup by fingerprint exists. `outcome_correctness` is the
  fraction of the set accepted as written, with
  label `shipped` when nothing was added or rejected, `scoped-down` when the crit cut
  requirements, and `escalated` when it sent the set back. Until the crit exists as a skill,
  the operator who accepts the set witnesses it by hand with the same rule.
- Each RESEARCH prediction is witnessed when its document's status lands `done`. Its id is
  in this run's report, and the fingerprint that confirms it is the research document's own
  id. Whoever records the finding runs `legion uncertainty witness <id> --outcome-label shipped
  --outcome-correctness 1.0` if the hypothesis held, `0.0` if refuted, and the held/refuted
  fraction of its claims when mixed. The document's `provenance.verification` counts are
  the source of that number.

## Refuses

- Minting `system-foundations` trace nodes. Foundations are a separate layer -- new
  verbs and capabilities that have nothing to do with the intent/discovery layer -- so when
  a requirement needs a trace target that does not exist, surface it and ask; the node is
  created in the foundations layer on its own terms, never as a side effect of a spec run.
- Writing issues. The spec is the requirement set; turning requirements into issues is the
  issue-writer's job, downstream.
- A SHALL grounded only in "the current system does this," or any requirement with no
  `traces_to` source -- unproven ground routes to RESEARCH.
- Landing a `constraint` document -- the doc-type does not exist here; a constraint becomes
  an FR.
- Resolving an input contradiction in-body. It escalates.
- Any status beyond `draft`. Acceptance is the crit, a separate step.
- Witnessing its own predictions. The writer stakes them; the crit and the research finding
  score them. A self-witnessed prediction is the rubber stamp the engine exists to catch.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.