feat: harden OpenSpec agent resilience

This commit is contained in:
2026-08-26 10:11:02 +03:00
parent 6719160c13
commit 8462a3ba75
15 changed files with 798 additions and 320 deletions
+159 -298
View File
@@ -1,5 +1,5 @@
name: wealth-ledger-sdd
version: 2
version: 3
description: WealthLedger SDD workflow - proposal → specs → design → tasks → apply
artifacts:
- id: proposal
@@ -7,48 +7,34 @@ artifacts:
description: Owner-approved intent without implementation details
template: proposal.md
instruction: |
Создай Proposal, который формулирует намерение и объясняет, ПОЧЕМУ
изменение нужно. Его должен понимать и утверждать владелец продукта или
процесса без знания структуры кода.
Critical Rules:
- Создай только Proposal: причина, намерение, scope, ожидаемый результат и
явные non-goals языком Change Owner.
- Сначала исследуй canonical main specs; для audit-derived change также
прочитай remediation registry.
- Capabilities перечисляет каждую новую или изменяемую behavior spec точным
path. Если spec-level behavior не меняется, не выдумывай Requirement:
оставь capabilities пустыми и установи `skip_specs: true`.
- Оставь технологии, зависимости, архитектуру, API, database/code/file
structure для Design, а implementation steps и verification — для Tasks.
- После записи запусти
`bash specs/scripts/verify-openspec-planning.sh <change>`. Исправляй
artifact только при `artifact-validation`; при `invocation` исправь вызов,
при `environment` — prerequisite. Structural success не является approval.
Sections:
Разделы:
Required Shape:
- **Why**: проблема или возможность и причина заняться ею сейчас.
- **What Changes**: намерение, ожидаемый результат и явные non-goals.
- **Capabilities**: какие поведенческие specs появятся или изменятся:
- **New Capabilities**: List capabilities being introduced. Each becomes a new `specs/<capability-path>/spec.md`. Use kebab-case for path segments you introduce (e.g., `user-auth` or `identity/user-auth`) and follow the project's existing spec organization.
- **Modified Capabilities**: List existing capabilities whose REQUIREMENTS are changing. Only include if spec-level behavior changes (not just implementation details). Each needs a delta spec file. Use the exact existing path under `openspec/specs/`. Leave empty if no requirement changes.
- **Impact**: затронутые пользователи, процессы или части системы только
на уровне scope.
- **What Changes**: намерение, ожидаемый результат и non-goals.
- **Capabilities**:
- **New Capabilities**: exact `specs/<capability-path>/spec.md`; новые path
segments используют kebab-case и существующую organization.
- **Modified Capabilities**: exact existing path под `openspec/specs/`
только при изменении Requirements.
- **Impact**: затронутые пользователи, процессы или части системы на уровне
scope, без implementation topology.
IMPORTANT: The Capabilities section is critical. It creates the contract between
proposal and specs phases. Research existing specs before filling this in.
Each capability listed here will need a corresponding spec file.
Every change must either declare at least one capability (new or
modified) or explicitly opt out of specs: `openspec validate` rejects a
change with zero deltas unless the change's `.openspec.yaml` sets
`skip_specs: true`. Use `skip_specs: true` only when no spec-level
behavior changes (pure refactor, tooling, docs) - specs describe
behavior, so if behavior does not change, no spec should change either.
Do not invent a requirement just to satisfy validation.
Artifact boundary — MUST NOT include:
- технологии, библиотеки, зависимости или выбранную архитектуру: эти
решения появляются только после Delta Specs в Design;
- API signatures, database structures, имена файлов, классов или
функций: это implementation detail для Design;
- implementation steps, task decomposition или verification commands:
это конкретизируется в Tasks после утверждения Design.
This is the foundation - specs, design, and tasks all build on this.
До сохранения исследуй canonical main specs и remediation registry для
audit-derived change. После записи выполни
`bash specs/scripts/verify-openspec-planning.sh <change>`: на этой стадии
verifier проверяет Proposal и явно оставляет downstream validation
pending. Исправь технический формат и повтори check до запроса approval;
structural success не означает approval Change Owner.
Один Proposal формирует contract для downstream artifacts. Покажи его
Change Owner и остановись до explicit approval.
requires: []
- id: specs
@@ -56,129 +42,47 @@ artifacts:
description: Observable behavior and invariants changed by the proposal
template: spec.md
instruction: |
Создай Delta Specs, определяющие, ЧТО наблюдаемо изменяется в системе.
Critical Rules:
- Создай behavior contract только для capabilities утверждённого Proposal:
observable inputs, outputs, errors и security/privacy/reliability/
compatibility constraints.
- Не добавляй intent вне Proposal, code/database/file structure, technology
choices, delivery steps или test procedure. Scenario задаёт WHEN/THEN
behavior; способ проверки выбирается позже.
- Создай один `specs/<capability-path>/spec.md` на каждый Proposal path.
New path следует Proposal; modified path точно совпадает с существующим
path под `<planningHome.root>/openspec/specs/` и не переименовывается.
- Используй только применимые `## ADDED Requirements`,
`## MODIFIED Requirements`, `## REMOVED Requirements` и
`## RENAMED Requirements`; не оставляй пустые operation sections.
- Каждый `### Requirement:` содержит SHALL/MUST и хотя бы один
`#### Scenario:` с `- **WHEN**` и `- **THEN**`.
- После explicit Proposal approval и записи запусти planning verifier.
Исправляй artifact только при `artifact-validation`; `invocation` и
`environment` не разрешают менять Delta Specs.
Spec является behavior contract, а не планом изменения кода.
Delta Operations:
- `ADDED`: новый Requirement.
- `MODIFIED`: скопируй из main spec полный existing Requirement block со
всеми Scenarios, затем измени behavior; heading совпадает точно.
- `REMOVED`: добавь **Reason** и **Migration**.
- `RENAMED`: только heading rename в формате `FROM:` / `TO:`.
Good spec content:
- Observable behavior users or downstream systems rely on
- Inputs, outputs, and error conditions
- External constraints (security, privacy, reliability, compatibility)
- Scenarios that can be tested or explicitly validated
New Capability:
Добавь `## Purpose` из 1–2 предложений (не менее 50 characters). Archive
переносит его в новую main spec; без него появляется ручной `TBD`. Для
existing capability `Purpose` в delta не добавляй. Existing Purpose меняй
прямо в main spec под `planningHome.root` отдельным явно разрешённым
изменением. `planningHome.root` уже разрешает store-backed или local root;
не вычисляй path самостоятельно.
Artifact boundary — MUST NOT include:
- intent или scope за пределами утверждённого Proposal: сначала верни
изменение в Proposal;
- internal components, class/function names, files или database
structures: implementation structure определяется в Design;
- library, framework или infrastructure choices: alternatives и решение
принадлежат Design;
- step-by-step implementation, delivery sequencing или verification
commands: это принадлежит Tasks;
- test procedure вместо behavior scenario: scenario фиксирует
наблюдаемые WHEN/THEN, а способ проверки выбирается позднее.
`skip_specs: true` допустим только при отсутствии Proposal capabilities и
delta files. Specs должны быть проверяемыми, но Scenario не означает
обязательный unit test: уровень проверки определяется риском.
Quick test: if the implementation can change without changing externally
visible behavior, it likely does not belong in the spec.
Create one spec file per capability listed in the proposal's Capabilities section.
`<capability-path>` is the spec directory relative to `specs/` (for example,
`user-auth` or `identity/user-auth`). Preserve the full path:
- New capabilities: use the exact path from the proposal at `specs/<capability-path>/spec.md`. Any path segment newly introduced in the proposal must be kebab-case. Follow the project's existing organization; do not add a new domain level when the project uses a flat layout.
- Modified capabilities: use the exact existing path from `openspec/specs/<capability-path>/` when creating the delta at `specs/<capability-path>/spec.md`. Do not move or rename the capability.
There must be at least one spec file unless the change's `.openspec.yaml`
sets `skip_specs: true` (no spec-level behavior change) - `openspec validate`
rejects a zero-delta change without that marker. If the proposal lists no
capabilities and `skip_specs` is not set, revisit the proposal first.
Delta operations (use ## headers):
- **ADDED Requirements**: New capabilities
- **MODIFIED Requirements**: Changed behavior - MUST include full updated content
- **REMOVED Requirements**: Deprecated features - MUST include **Reason** and **Migration**
- **RENAMED Requirements**: Name changes only - use FROM:/TO: format
Format requirements:
- Each requirement: `### Requirement: <name>` followed by description
- Use SHALL/MUST for normative requirements (avoid should/may)
- Each scenario: `#### Scenario: <name>` with WHEN/THEN format
- **CRITICAL**: Scenarios MUST use exactly 4 hashtags (`####`). Using 3 hashtags or bullets will fail silently.
- Every requirement MUST have at least one scenario.
New capabilities only: start the delta spec with a `## Purpose` section -
one or two sentences (50+ characters, or `openspec validate --strict`
reports it as too brief) describing what the capability is for. Archive
copies it into the main spec it creates; without it the new main spec is
left with a `TBD ... Update Purpose after archive` placeholder to fill in
by hand. Do NOT add `## Purpose` to a delta for an existing capability -
that spec already has one and the delta's is ignored. To change an
existing capability's Purpose - including a leftover `TBD` placeholder -
edit `<planningHome.root>/openspec/specs/<capability-path>/spec.md`
directly. `planningHome.root` comes from the `openspec instructions ...
--json` response. Always use it rather than a repo-relative path: it
resolves to the store whenever the change lives in one - whether that
came from `--store`, a project `store:` pointer, or a global default
store - and to the current repository otherwise. Do not try to work out
which case applies; the field already has.
MODIFIED requirements workflow:
1. Locate the existing requirement in `<planningHome.root>/openspec/specs/<capability-path>/spec.md` (the same store-aware root as above)
2. Copy the ENTIRE requirement block (from `### Requirement:` through all scenarios)
3. Paste under `## MODIFIED Requirements` and edit to reflect new behavior
4. Ensure header text matches exactly (whitespace-insensitive)
Common pitfall: Using MODIFIED with partial content loses detail at archive time.
If adding new concerns without changing existing behavior, use ADDED instead.
Compact operation examples:
```
# ADDED in a new capability: include Purpose.
## Purpose
Lets users take their data out of the product in a portable format.
## ADDED Requirements
### Requirement: User can export data
The system SHALL allow users to export their data in CSV format.
#### Scenario: Successful export
- **WHEN** user clicks "Export" button
- **THEN** system downloads a CSV file with all user data
# MODIFIED: copy the complete old requirement, then edit it.
## MODIFIED Requirements
### Requirement: Session expiration
The system MUST reject an expired session and preserve every surviving
scenario from the main spec.
#### Scenario: Expired session
- **WHEN** a request uses an expired session
- **THEN** the system rejects the request
# REMOVED requires both fields.
## REMOVED Requirements
### Requirement: Legacy export
**Reason**: Replaced by new export system
**Migration**: Use new export endpoint at /api/v2/export
# RENAMED changes only the heading.
## RENAMED Requirements
- FROM: `### Requirement: Old name`
- TO: `### Requirement: New name`
```
Specs должны быть проверяемыми, но scenario не означает автоматический
unit test: уровень проверки выбирается по риску поведения.
Перед записью установи явный approval Proposal из разговора. После
записи выполни `bash specs/scripts/verify-openspec-planning.sh <change>`
и исправь технические ошибки до запроса approval Delta Specs. Если
обнаружено изменение intent, вернись к Proposal и инвалидируй downstream
approvals вместо скрытого расширения Specs.
Покажи Delta Specs Change Owner и остановись до explicit approval. Если
обнаружилось изменение intent, вернись к Proposal и инвалидируй downstream
approvals.
requires:
- proposal
@@ -187,58 +91,45 @@ artifacts:
description: Architectural implementation approach and delivery decisions
template: design.md
instruction: |
Создай Design, объясняющий, КАК архитектурно выполнить утверждённые
Delta Specs.
Critical Rules:
- Создай архитектурный способ выполнить утверждённые Delta Specs крупными
решениями, rationale, alternatives, risks и migration order.
- Не добавляй observable behavior вне Specs, не пересказывай upstream
artifacts и не пиши file-by-file checklist, verification commands,
будущие results, commits или Completion Evidence.
- Разреши до сохранения любой вопрос, который меняет Specs, approach или
Tasks. `Open Questions` оставляет только genuinely deferrable unknowns.
- После explicit Delta Specs approval и записи запусти planning verifier.
Исправляй Design только при `artifact-validation`; `invocation` и
`environment` требуют исправить вызов или prerequisite.
Artifact boundary — MUST NOT include:
- новое observable behavior или invariant, отсутствующие в утверждённых
Delta Specs: сначала верни изменение в Specs;
- пересказ Proposal или Specs вместо архитектурных constraints и
решений, необходимых для выбранного подхода;
- file-by-file implementation checklist, verification commands или
пошаговый список правок: это принадлежит Tasks;
- будущие delivery results, commit identifiers или Completion Evidence:
они фиксируются только после наблюдаемого выполнения.
Required Shape:
- **Context**: current state и constraints подхода.
- **Goals / Non-Goals**: технические границы.
- **Decisions**: ключевые решения, rationale и alternatives.
- **Delivery Map**: ровно `frontend`, `backend`, `specs`, `docs`; каждая
area имеет `affected` outcome или конкретный `N/A` reason. `specs` всегда
`affected`.
- **Contract Gate Decision**: `runtime-openapi` = `required`, только когда
меняются обе стороны API contract; иначе конкретный `N/A`.
- **Risks / Trade-offs** и **Migration Plan**.
- В Migration Plan — `### Rollback Contract`: `required` с Trigger,
Actions, Data safety, Verification для auth/security, data integrity/
migration, public contract или другого труднообратимого решения; иначе
`N/A` с конкретным Reason.
Обязательные разделы:
- **Context**: только текущее состояние и ограничения подхода.
- **Goals / Non-Goals**: технические границы, не пересказ Proposal.
- **Decisions**: крупные решения, rationale и рассмотренные alternatives.
- **Delivery Map**: ровно frontend, backend, specs и docs; для каждой
области `affected` с ожидаемым архитектурным результатом либо `N/A` с
конкретной причиной. `specs` всегда affected. Здесь же зафиксируй
Contract Gate Decision для `runtime-openapi`: `required`, только когда
change затрагивает обе стороны API contract, либо `N/A` с причиной.
- **Risks / Trade-offs**: риск и mitigation.
- **Migration Plan**: порядок поставки и rollback, если применимо.
Solution Assessment:
Включи section внутри Design, если change вводит или существенно заменяет
auth, security, storage, external integration, observability, caching,
concurrency, shared infrastructure/tooling либо другое дорогостоящее
необратимое решение. Сравни mature options по fit, maturity, security,
operating cost, constraints и migration cost. Custom implementation
допустима только после конкретной несовместимости alternatives. Не создавай
отдельный assessment artifact.
Внутри Migration Plan добавь `### Rollback Contract` с table fields.
Status `required` обязателен для auth/security, data integrity/migration,
public contract и другого существенно труднообратимого решения и требует
Trigger, Actions, Data safety и Verification. В остальных случаях Status
`N/A` требует конкретный Reason. Отдельный rollback artifact не создавай.
Добавь **Solution Assessment**, если изменение вводит или существенно
заменяет auth, security, storage, external integration, observability,
caching, concurrency или общую infrastructure/tooling либо содержит
другое дорогостоящее необратимое решение. Сравни зрелые готовые решения
по fit, maturity, security, operating cost, constraints и migration cost.
Custom implementation допустима только после фиксации несовместимости
подходящих alternatives и принятых рисков. Не создавай отдельный artifact.
**Open Questions** допустим только для неизвестного, которое не меняет
Specs, выбранный подход или Tasks. Иначе остановись и запроси решение
владельца до сохранения Design.
Open questions are for genuinely deferrable unknowns, not decisions you
skipped. If a question would change the specs, the chosen approach, or
the task breakdown, resolve it now - ask the user instead of guessing.
Design формируется только после явного owner approval Delta Specs. После
записи выполни `bash specs/scripts/verify-openspec-planning.sh <change>`
и исправь технические ошибки до запроса approval. Если Design показывает
несовместимость с intent или behavior, остановись, вернись к самому
раннему затронутому artifact и инвалидируй downstream approvals.
Покажи Design Change Owner и остановись до explicit approval. Если approach
несовместим с intent или behavior, вернись к самому раннему затронутому
artifact и инвалидируй downstream approvals.
requires:
- specs
@@ -247,76 +138,46 @@ artifacts:
description: Implementation checklist with trackable tasks
template: tasks.md
instruction: |
Создай implementation checklist, достаточный для выполнения Design и
Delta Specs. Это конкретное DO, а не ещё один архитектурный документ.
Critical Rules:
- Создай dependency-ordered implementation checklist только после explicit
Design approval. Формат каждого item:
`- [ ] X.Y [frontend|backend|specs|docs|workspace] action`.
- Каждый checkbox имеет ровно одну indented `- **Covers:**` и одну
`- **Verification:**` line, одного owner и помещается в одну рабочую
сессию.
- `Covers` содержит exact
`` `capability-path` — `Requirement heading` `` pairs либо
`` `N/A` — reason ``. Каждый Delta Requirement покрыт хотя бы одной task;
parallel requirement IDs не вводятся.
- `N/A` reason объясняет отсутствие самостоятельного observable behavior,
техническую необходимость и связь с утверждённым Design или delivery.
Не оставляй template placeholder. Смысл проверяется owner review, а не
text heuristic.
- Owner repository обязан быть `affected` в Delivery Map. Cross-repository
implementation разделяй. `workspace` владеет только orchestration или
verification и всегда использует содержательный `N/A`.
- Для каждой affected area добавь owned implementation и canonical gate.
Не создавай empty commit. Planned Verification задаёт command,
observable check или delivered artifact, но не будущий result.
- Новое behavior возвращает change в Specs; новое architecture — в Design;
multi-owner или vague task исправляется в Tasks. Не добавляй commits,
archive path или post-archive Completion Evidence.
- После записи запусти planning verifier. Исправляй Tasks только при
`artifact-validation`; `invocation` и `environment` не разрешают менять
checklist.
Before writing tasks, check design.md for Open Questions. If any of them
would change what gets built, resolve them with the user first - do not
bake an unstated assumption into the task list.
Testing:
Автоматические tests обязательны для security/privacy, денежных расчётов,
data integrity/migration, concurrency, public contracts, critical journeys
и подтверждённых regressions. DTO без логики, declarative structure, thin
adapter, прямолинейная orchestration, hygiene script и third-party behavior
используют существующий integration/contract gate, если нет собственного
branching, transformation, invariant или regression. Перед custom work в
mandatory assessment area включи утверждённый Solution Assessment action.
**IMPORTANT: Follow the template below exactly.** The apply phase parses
checkbox format to track progress. Tasks not using `- [ ]` won't be tracked.
Правила:
- Группируй задачи под numbered `##` headings и располагай по dependencies.
- Каждая задача MUST иметь формат `- [ ] X.Y [area] action`, быть
выполнимой за одну рабочую сессию и иметь ровно одного owner из
`frontend`, `backend`, `specs`, `docs`, `workspace`.
- Сразу после checkbox добавляй ровно по одной indented metadata line:
`- **Covers:**` и `- **Verification:**`.
- `Covers` содержит одну или несколько пар
`` `capability-path` — `exact Requirement heading` `` либо
`` `N/A` — concrete reason ``. Каждый Delta Requirement должен быть
покрыт хотя бы одной task; собственные requirement IDs не вводятся.
- Owner repository не может иметь статус `N/A` в Delivery Map.
Cross-repository implementation разделяй; `workspace` используй только
для orchestration/verification и с конкретным `N/A` Covers rationale.
- Для каждой `affected` области Delivery Map должна существовать задача
реализации и её canonical local gate; пустые commits запрещены.
- Каждая задача MUST указывать planned verification action: команду,
проверку наблюдаемого поведения или delivered artifact.
- Автоматические тесты обязательны для security/privacy, денежных
расчётов, data integrity/migration, concurrency, public contracts,
critical journeys и подтверждённых regressions.
- Не требуй отдельный unit test только из-за изменения файла. DTO без
логики, declarative structures, thin adapters, прямолинейная
orchestration, hygiene scripts и third-party behavior проверяются
существующим integration/contract gate, если нет собственного
branching, transformation, invariant или regression.
- Перед custom implementation в обязательных областях включи действие по
утверждённому Solution Assessment из Design.
Artifact boundary — MUST NOT include:
- новое observable behavior или Requirement: сначала верни изменение в
Specs;
- новое архитектурное решение или отклонение от утверждённого Design:
сначала обнови Design;
- одну задачу с несколькими owner repositories: раздели её по delivery
areas;
- vague action без проверяемого результата: сформулируй конкретное DO и
planned Verification;
- ещё не наблюдённые результаты как выполненные, предполагаемые commit
identifiers, archive path или post-archive Completion Evidence: такое
evidence создаётся только после факта.
Example:
```
## 1. Delivery
- [ ] 1.1 [backend] Implement session rejection
- **Covers:** `user-authentication` — `Expired session is rejected`
- **Verification:** Run the backend canonical gate and the expiry contract test.
- [ ] 1.2 [workspace] Run cross-area semantic review
- **Covers:** `N/A` — verification only; no independent spec behavior.
- **Verification:** Compare delivery against every approved Requirement and Scenario.
```
Reference specs for what needs to be built, design for how to build it.
После записи выполни
`bash specs/scripts/verify-openspec-planning.sh <change>` и исправь
технические нарушения до запроса approval. Если Tasks требует новое
behavior или architecture, не расширяй scope: вернись к Specs или Design
и инвалидируй Tasks approval.
Group tasks под numbered `##` headings. Покажи Tasks Change Owner и
остановись до explicit approval. Если checklist требует новое behavior или
architecture, вернись к Specs или Design и инвалидируй Tasks approval.
requires:
- design
@@ -324,25 +185,25 @@ apply:
requires: [ tasks ]
tracks: tasks.md
instruction: |
Сначала проверь exact OpenSpec version contract. Работай только с change в
canonical store `wealth-ledger-specs` и не создавай parallel planning root.
Apply допустим только после явных approvals Proposal, Delta Specs, Design и
Tasks из разговора. До реализации выполни
`bash specs/scripts/verify-openspec-planning.sh <change>`.
Read context files, work through pending tasks, run each planned
Verification and mark a checkbox complete only after observed success.
Pause if you hit blockers or need clarification.
Feedback routing:
- intent/scope mismatch → Proposal;
- observable behavior mismatch → Delta Specs;
- architecture/rollback mismatch → Design;
- decomposition/ownership/coverage mismatch → Tasks.
Останови downstream work, сообщи наблюдаемое основание и инвалидируй
approvals начиная с самого раннего затронутого artifact. Только
механическое syntax/format исправление без изменения intent, behavior,
decisions или task scope можно исправить и повторно структурно проверить
без reapproval. Structural validation не заменяет semantic verification и
independent read-only review.
Critical Rules:
- Apply допустим только после explicit approvals Proposal, Delta Specs,
Design и Tasks. Проверь exact OpenSpec version, canonical store
`wealth-ledger-specs` и planning verifier до implementation.
- Прочитай каждый path из `contextFiles`, возвращённых native OpenSpec apply
instructions, затем applicable repository-local `AGENTS.md` affected areas.
Не вычисляй planning paths и не создавай второй context map.
- Выполняй pending tasks по dependencies. Запускай planned Verification и
отмечай checkbox только после observed success.
- Feedback routing: intent/scope → Proposal; observable behavior → Delta
Specs; architecture/rollback → Design; decomposition/ownership/coverage →
Tasks. Останови downstream work, сообщи evidence и инвалидируй approvals от
самого раннего затронутого artifact.
- Механическая правка ограничена Markdown heading, typo без изменения
нормативного смысла или table alignment. Requirement wording, Scenario,
architecture и planned Verification являются semantic changes и требуют
соответствующего reapproval.
- `artifact-validation` разрешает исправить указанную planning form;
`invocation` требует исправить вызов; `environment` — prerequisite.
Последние два класса не разрешают менять planning artifact.
- Structural validation не заменяет semantic verification и independent
read-only review.
@@ -1,11 +1,17 @@
## Purpose
<!-- New capabilities only: one or two sentences (50+ characters) on what this capability is for. Delete this section for an existing capability. -->
<!--
Choose only the sections this delta needs; delete this guide before approval.
## ADDED Requirements
New capability only: add `## Purpose` with 1–2 sentences (50+ characters).
Existing capability: do not add Purpose.
### Requirement: <!-- requirement name -->
<!-- requirement text -->
Supported operations:
- `## ADDED Requirements`: new complete Requirement blocks.
- `## MODIFIED Requirements`: full existing Requirement blocks with every
surviving Scenario, then edited behavior.
- `## REMOVED Requirements`: Requirement heading plus **Reason** and **Migration**.
- `## RENAMED Requirements`: `FROM:` and `TO:` heading pairs only.
#### Scenario: <!-- scenario name -->
- **WHEN** <!-- condition -->
- **THEN** <!-- expected outcome -->
Every Requirement uses `### Requirement: <name>`, SHALL/MUST, and at least one
`#### Scenario: <name>` with `- **WHEN**` and `- **THEN**`.
Do not leave empty operation sections.
-->