specStructuralContract function
The EXACT structural contract taught to the specify agent, in the words it reads. Items 1–5 are enforced by specStructuralFindings; items 6–10 are parsed by parseSpecContract in shadow measurement only. buildSpecifyBrief renders this string VERBATIM, so neither phase can hide a rule from the architect.
The shipped exemplar is round-tripped through both readings in test: it passes specStructuralFindings and parses without a record finding.
runner/gridHome thread through to the two lookup-narrative sentences
item 9 quotes and to the embedded specExemplarDesign.
Implementation
String specStructuralContract({
String runner = kDefaultOverlayRunner,
String? gridHome,
}) =>
'''
### The structural contract (a DETERMINISTIC gate, run before any critic reads your spec)
`spec-validation` is not a critic and holds no opinion. Its live A/F result is
the five presence and placeholder checks in items 1–5:
1. **Acceptance** carries at least one `- [ ]` checkbox line.
2. **The design carries all four `## ` headings**, spelled exactly:
`## Implementation Plan`, `## Touches`, `## ADR Alignment`,
`## Validation Plan` — each OPENING ITS OWN LINE. A heading NAMED inside a
sentence ("the machine gate is the fast subset — see `## Validation Plan`")
is a MENTION: it neither satisfies this rule nor displaces the real section
further down. Backtick any heading you name in running prose.
3. **`## Implementation Plan` carries NUMBERED steps.** Every step opens with an
ordinal — an ordered-list item (`1. …` / `1) …`) or an ordinal heading
(`### Step 1 — …` / `### 1. …`). A bulleted or prose-only plan has no ordinal
and FAILS however complete it is. Steps carrying fenced code read best as
`### Step N — …` headings.
4. **`## Validation Plan` carries at least one `- ` item.**
5. **No placeholder token in PROSE.** These exact tokens, case-insensitively:
$_bannedTokenLine.
$_specContractShadowBoundary
Items 6–10 are the strict record grammar measured over the retained corpus by
`spec_contract_shadow.dart`; they do not affect `SpecValidationCapability`'s
grade before that ruling:
6. **Every acceptance criterion is an ADDRESSABLE record**:
`$kAcceptanceRecordForm` — ids UNIQUE and CONTIGUOUS from `AC-1`. The id is
what the validation plan maps onto.
7. **Every implementation step carries five LABELED lines**, each opening its
own line: $_stepFieldLabelLine. `Change:` states the BEHAVIOUR and INVARIANT
a zero-context builder must produce; a fenced code block beside it is
optional EVIDENCE, never a required field. `Paths:` cites backticked
REPO-RELATIVE paths (no leading `/`, no `..`); `Commit:` is a
conventional-commit subject. The step opener is `$kStepRecordForm`, and the
ordinal-list openers rule 3 names still count.
8. **Every `## Touches` item is** `$kTouchRecordForm` — exactly ONE
repo-relative backticked path and one disposition word.
9. **Every `## ADR Alignment` item is** `$kDecisionRecordForm`, whose citation
resolves as `<repo>#<slug>`, a `docs/decisions/` path, or a legacy
`ADR-<nnnn>` id. The section is NEVER silent about the lookup: when
the roster union is empty for every queried surface, write
"${noGoverningDecisionSentence(runner: runner, gridHome: gridHome)}"; when
the lookup FAILED or exited non-zero, write
"${failedDecisionLookupSentence(runner: runner, gridHome: gridHome)}" — an
unknown union is not an empty one, and a crashed index is never graded clean.
10. **Every `## Validation Plan` item is** `$kValidationRecordForm`, exactly
ONCE for every acceptance id and NEVER for an id no criterion declares.
Headings and ordinals are read from PROSE, and so are those tokens: markdown
QUOTATION is exempt (fenced blocks, `inline code` spans, `>` blockquote lines).
A token you QUOTE as evidence — a comment your plan deletes, a gate note cited
verbatim — points at work rather than deferring it, so backtick any banned token
you must name. The same cuts the other way: a `## Touches` heading that exists
only inside a code block is evidence, not a section.
Below is a COMPLETE spec that passes the live gate and parses clean under the
shadow grammar. Copy its SHAPE.
`````markdown
$kSpecExemplarAcceptance
${specExemplarDesign(runner: runner, gridHome: gridHome)}
`````''';