YAML Governance Reference¶
As of v0.12, specsmith uses YAML-first governance: requirements and test cases live in canonical YAML files; Markdown files are generated artifacts.
Quick start¶
# Check current mode
cat .specsmith/governance-mode # "yaml" = YAML-first, absent = legacy MD
# Full sync: YAML → JSON cache → Markdown
specsmith sync
# Strict schema validation
specsmith validate --strict
# Regenerate Markdown only (faster)
specsmith generate docs
Authority model¶
| Layer | Location | Role |
|---|---|---|
| Canonical source | docs/requirements/*.yml, docs/tests/*.yml |
Edit these |
| JSON cache | .specsmith/requirements.json, .specsmith/testcases.json |
Auto-generated |
| Markdown artifacts | docs/REQUIREMENTS.md, docs/TESTS.md |
Auto-generated — do NOT hand-edit |
The .specsmith/governance-mode flag controls which direction is authoritative:
governance-mode = yaml → YAML-first (v0.12+ default after migration)
governance-mode = markdown → Legacy Markdown-primary (backward compat)
(absent) → Legacy Markdown-primary
Domain YAML files¶
Requirements and test cases are split into domain files. Add a new requirement by editing the appropriate file and running specsmith sync.
Requirements¶
| File | REQ range | Domain |
|---|---|---|
docs/requirements/governance.yml |
REQ-001..064 | Core AEE governance |
docs/requirements/agent.yml |
REQ-065..129 | Nexus + CI |
docs/requirements/harness.yml |
REQ-130..160 | Slash commands + subagents |
docs/requirements/intelligence.yml |
REQ-161..220 | Instinct, eval, memory |
docs/requirements/context.yml |
REQ-244..247 | Context window |
docs/requirements/esdb.yml |
REQ-248..262 | ESDB + skills + MCP |
docs/requirements/ai_intelligence.yml |
REQ-263..299 | AI model intelligence |
docs/requirements/yaml_governance.yml |
REQ-300..399 | YAML governance layer |
Test cases¶
Mirror structure under docs/tests/ (e.g. docs/tests/governance.yml, docs/tests/agent.yml, …).
YAML schema¶
Requirements (docs/requirements/*.yml):
- id: REQ-NNN # required — stable numeric ID, e.g. REQ-305
title: Short title # required
status: implemented # required — implemented | planned | partial | deprecated
description: >-
Full description of what the system must do.
source: ARCHITECTURE.md §Section # optional but recommended
Test cases (docs/tests/*.yml):
- id: TEST-NNN # required
title: Short title # required
requirement_id: REQ-NNN # required — must reference an existing REQ
type: unit # optional — unit | integration | cli | e2e | build | manual
verification_method: pytest # optional
description: >-
What the test verifies.
input: "test input description"
expected_behavior: "what should happen"
confidence: 1.0
CLI reference¶
specsmith sync¶
Full pipeline: load YAML → write JSON cache → regenerate Markdown.
specsmith sync # run full sync
specsmith sync --check # exit 1 if JSON cache is out of sync (CI gate)
specsmith sync --project-dir /path/to/project
When to run: after editing any docs/requirements/*.yml or docs/tests/*.yml file.
specsmith generate docs¶
Regenerate REQUIREMENTS.md and TESTS.md from YAML without touching the JSON cache.
specsmith generate docs # regenerate Markdown
specsmith generate docs --check # dry-run: report what would change
specsmith generate docs --json # structured {ok, reqs, tests}
When to use: when you only want to refresh Markdown (e.g. after CI generates the cache).
specsmith validate --strict¶
Enforce 8 governance schema checks.
specsmith validate --strict # human-readable
specsmith validate --strict --json # structured output
Exit codes:
- 0 — clean (zero errors; warnings allowed)
- 1 — one or more schema errors
The 8 checks:
| # | Check | Severity |
|---|---|---|
| 1 | Duplicate REQ IDs | Error |
| 2 | Duplicate TEST IDs | Error |
| 3 | Missing required REQ fields (id, title, status) |
Error |
| 4 | Missing required TEST fields (id, title, requirement_id) |
Error |
| 5 | Orphaned TESTs (reference a non-existent REQ) | Error |
| 6 | Untested REQs | Warning |
| 7 | Duplicate REQ titles | Warning |
| 8 | Machine-state drift (YAML vs JSON cache) | Warning |
JSON output shape:
{
"ok": true,
"strict_errors": 0,
"strict_warnings": 2,
"details": [
{"type": "warning", "check": "untested_req", "id": "REQ-042", "message": "..."}
]
}
Migration from Markdown-primary¶
If your project has docs/REQUIREMENTS.md as the hand-edited source, migrate once:
python scripts/migrate_governance_to_yaml.py
This script is idempotent — re-running it on an already-migrated project produces no changes. It performs 4 steps in order:
- Remove duplicate REQs from
docs/REQUIREMENTS.md - Re-sync
.specsmith/JSON from the cleaned Markdown - Export JSON to grouped YAML domain files under
docs/requirements/anddocs/tests/ - Write
.specsmith/governance-mode = yaml
After migration, specsmith sync --check exits 0 and specsmith validate --strict reports no errors.
CI integration¶
The validate-strict and sync-check steps in .github/workflows/ci.yml enforce YAML governance on every push and PR:
governance:
name: Governance Audit
steps:
- name: Check machine state sync
run: python -m specsmith sync --check --project-dir .
- name: Validate governance schema (strict)
run: python -m specsmith validate --strict --json --project-dir .
Both steps block the build on failure. The sync-check step catches JSON cache drift (e.g. YAML edited but sync not run). The validate-strict step catches schema errors such as duplicate IDs or orphaned tests.
Python API¶
from specsmith.governance_yaml import (
is_yaml_mode, # is_yaml_mode(root: Path) -> bool
load_yaml_reqs, # load_yaml_reqs(root: Path) -> list[dict]
load_yaml_tests, # load_yaml_tests(root: Path) -> list[dict]
save_yaml_reqs, # save_yaml_reqs(root: Path, reqs: list[dict]) -> None
save_yaml_tests, # save_yaml_tests(root: Path, tests: list[dict]) -> None
generate_md_from_yaml, # generate_md_from_yaml(root: Path) -> None
validate_strict, # validate_strict(root: Path) -> dict
)
root = Path(".")
if is_yaml_mode(root):
reqs = load_yaml_reqs(root) # merged, sorted list of all REQs
result = validate_strict(root)
print(result["strict_errors"], "errors,", result["strict_warnings"], "warnings")
Workflow examples¶
Add a new requirement¶
# 1. Edit the appropriate domain YAML file
# e.g. docs/requirements/governance.yml
cat >> docs/requirements/governance.yml << 'EOF'
- id: REQ-065
title: My new requirement
status: planned
description: >-
The system must do X.
source: ARCHITECTURE.md §6
EOF
# 2. Sync to regenerate JSON cache and Markdown
specsmith sync
# 3. Validate schema
specsmith validate --strict
Add a test case¶
# Edit docs/tests/governance.yml (matching domain file)
# Then sync and validate
specsmith sync
specsmith validate --strict
Check before commit¶
specsmith sync --check # exits 0 if clean
specsmith validate --strict # exits 0 if clean
Troubleshooting¶
specsmith sync --check exits 1
Your JSON cache is out of sync with the YAML files. Run specsmith sync to regenerate it.
specsmith validate --strict reports orphaned TEST
A test case references a requirement_id that doesn't exist. Either add the missing REQ or fix the requirement_id in the test YAML file.
specsmith generate docs says "not in YAML mode"
The .specsmith/governance-mode file is missing or contains markdown. Run the migration script, or create the file manually:
echo "yaml" > .specsmith/governance-mode
After migration, REQUIREMENTS.md looks different
The migration regenerates REQUIREMENTS.md from the YAML sources. The content is the same, but formatting is normalised. This is expected — the Markdown file is now a generated artifact.