Complete reference for using the SDD Dev Suite.
What changed in audit-v2 — see
docs/MIGRATION-v2.mdfor the consolidated user-facing summary: install presets, mode renumbering (Mode 1 = Simple), C5 scorecard, agent-browser default, JSON task sidecar, branch gate, 4-commit checkpoints, bugfix-pr Mode 7.
What changed in
feat/forge-token-cascade-refactor(Unreleased) — startup-token + cascade refactor. Most current-state info on these now lives indocs/HARNESS-GUIDE.md; this file is being consolidated.
- Default plugin set (W2): every install now opts into
engram, context7, agent-browser, rtkwhen--pluginsis unset/empty.rtkships an advisory Bash PreToolUse hook that hints when commands would benefit from rtk-prefixing (60-90% token reduction on the rtk coverage set:ls,cat,grep,find,git status|diff|log,pnpm test|lint|typecheck,jest,vitest,eslint,tsc,prettier).- Validation-cascade cap (W3):
src/scripts/sdd-cascade-cap.shhard-blocks the 2nd cascade Bash call after a failed validation step OR a banned mid-wave pattern (pnpm install, symlink probes, full-monorepo test without filter, repeatprettier --checkafter--write). Validator scorecard adds a 7th criterioncascade_discipline— total is now/21(was/18), thresholds PASS≥17 / WARN[14,16] / FAIL<14. Policy:src/agent_docs/cascade-policy.md.- Dispatch envelope (W4): every
Agent(...)invocation now carries explicitgoal: <≤25 words>+already_read_files: [...]headers (in addition to the existingengram_context: [...]cards). Honor-system + validator audit (no runtime hook). Seesrc/agent_docs/dispatch-rules.md§ Dispatch envelope (W4).- Per-mode
/compacttriggers (W5): each mode declares structured proactive/compactboundaries insrc/agent_docs/sdd-modes/mode-*.mdunder## Structured compaction triggers (W5). The global reactive fallbackCLAUDE_AUTOCOMPACT_PCT_OVERRIDE=75is unchanged.
For OS-specific tool installation, see docs/install/README.md.
- What is SDD?
- Four-Layer Architecture
- Installation
- First-time bootstrap
- SDD flow — mono-repo
- SDD flow — multi-repo
- Skills reference
- Profiles
- MCP infrastructure
- Local developer packs
- Org-wide rollout
- How the installer works
- Observability
- Governance
Spec-Driven Development means agreeing on what you're building before you build it. The spec is structured so both humans and agents can read it. Tooling ensures you built what the spec says.
Explore → Research → Propose → Implement → Verify → Archive
No code is written before a spec exists. No spec is implemented before a human approves it.
Why it works with AI:
- Agents work better with clear specs than with vague instructions
- Every feature has an audit trail: spec → tasks → code → verification
- Independent tasks run in parallel across sub-agents
- Verification always runs in a fresh context — no confirmation bias
Layer 1 — OpenSpec Upstream SDD framework. We consume, never fork.
opsx:explore / propose / apply / verify / archive
Layer 2 — Forge Baseline The shared delivery contract. Committed to every repo.
AGENTS.md sections + forge:* skills + OpenSpec config
Layer 3 — Repo Profiles Optional. Committed only to repos that need them.
frontend / backend-api / brownfield / high-risk
Layer 4 — Local Extensions Developer-local only. Never committed to repos.
Advanced MCP configs, personal memory, experimental tools
The separation matters:
- Layers 1–2: what the team builds and how
- Layer 3: how specific teams build
- Layer 4: how individual developers work
Conflating them causes bloat and fragility.
Agents, skills, and commands are authored once as Claude-format Markdown and translated at install time for each detected tool:
| Source | Claude Code | OpenCode | Codex CLI |
|---|---|---|---|
agents/claude/<name>.md |
.claude/agents/<name>.md |
.opencode/agents/<name>.md (subagent) |
.codex/agents/<name>.toml (subagent) |
skills/forge-<name>/SKILL.md |
.claude/skills/forge-<name>/ |
.opencode/agents/forge-<name>.md + .opencode/commands/forge-<name>.md |
.agents/skills/forge-<name>/SKILL.md (Codex-native location) |
skills/community/<name>/ |
.claude/skills/<name>/ |
.opencode/agents/<name>.md + .opencode/commands/<name>.md |
.agents/skills/<name>/SKILL.md |
.claude/commands/**.md |
.claude/commands/**.md |
.opencode/commands/**.md (dirs preserved) |
— (custom prompts deprecated; use skills) |
| Lifecycle hooks | .claude/settings.json |
— (not applicable) | .codex/hooks.json + [features] codex_hooks = true in .codex/config.toml |
| MCP servers | .claude/mcp.json (JSON) |
.opencode/mcp.json (JSON) |
.codex/config.toml (TOML, append-only) |
OpenCode translation (installer/install-opencode.js). Drops Claude-only frontmatter (name, color, model), converts the tools: [Read, Write, ...] array into OpenCode's tools: { write, edit, bash } object and permission: { webfetch }, and adds mode: subagent. File bodies are copied verbatim. Managed files carry a <!-- forge:<kind>:<name>:<ver> --> marker — re-runs force-update markered files and leave user-created files alone. One naming caveat: opencode filenames can't contain colons, so /forge:explore in Claude becomes /forge-explore in opencode. Subagent form (@forge-explore) also works for orchestrator-style delegation.
Codex translation (installer/install-codex.js). Emits TOML subagents with required Codex keys (name, description, developer_instructions). Codex subagents inherit parent sandbox + MCP allowlist by default, so per-agent tool restrictions are dropped (encoded in developer_instructions instead). The marker is a top-of-file TOML comment # forge:codex-agent:<name>:<ver>. Skills are copied verbatim to .agents/skills/<name>/SKILL.md — that path (NOT .codex/skills/) is the documented Codex discovery location, shared across OpenAI's agent toolchain. Hook scripts are referenced from .codex/hooks.json using Codex's Claude-compatible schema; Codex sends the same tool_name / tool_input JSON envelope as Claude, so the SDD scripts are portable as-is. The hook commands are anchored with cd "$(git rev-parse --show-toplevel)" so they work regardless of session cwd. The same repo_role filter applies. Codex only loads .codex/config.toml and project hooks for trusted projects — users accept this trust prompt once on first run.
The same repo_role filter (coordination, monorepo, frontend, backend, standalone) applies across all three translators.
# .github/workflows/sdd-sync.yml
- uses: iNBest-cloud/inbest-sdd-cycle@main
with:
agent_suite: 'true'
agent_suite_version: '1.0.0'
github_token: ${{ secrets.GITHUB_TOKEN }}With a profile:
gh workflow run sdd-sync-targeted.yml \
-f repos="my-frontend-repo" \
-f profile="frontend" \
-f dry_run="false"With a repo role (multi-repo setups):
# Coordination hub — orchestration agents only
gh workflow run sdd-sync-targeted.yml -f repos="my-hub" -f repo_role="coordination"
# Implementation repos — domain agents only
gh workflow run sdd-sync-targeted.yml -f repos="my-api" -f repo_role="backend"
gh workflow run sdd-sync-targeted.yml -f repos="my-ui" -f repo_role="frontend"Dry run first:
gh workflow run sdd-sync-targeted.yml -f repos="my-repo" -f dry_run="true"cp -r agents/claude/ <your-project>/.claude/agents/
cp -r skills/ <your-project>/.claude/skills/.claude/
agents/ ← 13 SDD Dev Suite sub-agents + 1 reference stub
skills/ ← 7 forge:* skills + 3 community skills
rules/ ← Orchestrator dispatch protocol (force override)
commands/sdd.md ← /sdd entrypoint
AGENTS.md ← SDD contract sections (non-destructive merge)
CLAUDE.md ← Orchestrator identity + @AGENTS.md import (section-marker merge)
schemas/ ← Format definitions (task-format, approval-gates, spec-frontmatter)
templates/openspec/ ← handoff.md (multi-wave / high-risk bridge)
openspec/
config.yaml
specs/
changes/
scripts/ ← sdd-preflight.sh, sdd-session-report.sh
Agent files that don't have the SDD version marker are never touched by future syncs. Customized agents are safe.
Open Claude Code in your repo and run /sdd. If no project-stack section exists in AGENTS.md, the main session (which IS the orchestrator) determines the bootstrap path:
If project-stack is absent AND no source code directories exist → GREENFIELD. Otherwise → BROWNFIELD.
The main session invokes forge:kickstart and outputs the 📥 PRD/backlog intake request:
1. Main session detects greenfield → outputs 📥 intake request
2. User provides PRD and/or backlog (markdown, XLSX, CSV, paste — any format)
3. Main session parses input → outputs structured summary (epics, stories, priorities)
4. Main session asks ❓ clarifying questions (tech stack, deployment, ambiguities)
5. Main session proposes openspec decomposition → 📋 approval gate
6. Main session proposes implementation waves → 📋 approval gate
7. agent-prep bootstraps AGENTS.md and project-stack
8. Implementation begins wave by wave with approval gates
This gate is non-skippable unless the user explicitly says "proceed without PRD."
agent-prep runs immediately (no PRD required):
- Scans the codebase — detects tech stack, architecture, ORM, test framework
- Generates a domain map — maps directories to agent domains:
frontend_paths: src/components/**, src/pages/** backend_paths: src/api/**, src/services/** database_paths: prisma/**, migrations/** test_frontend_paths: tests/e2e/**, tests/components/** test_backend_paths: tests/api/**, tests/integration/** - Writes
<!-- forge:section:project-stack -->to AGENTS.md - Runs
devstart— validates environment, probes MCP availability - Recommends external skills for your stack
After bootstrap, all agents read the domain map and project-stack from AGENTS.md. No agent operates blind.
Every session starts with /sdd. It runs scripts/sdd-preflight.sh and shows an MCP status report, then asks which mode you want.
╔═══════════════════════════════════════════════════╗
║ SDD Dev Suite — Ready ║
╠═══════════════════════════════════════════════════╣
║ ✓ engram Persistent memory ║
║ ✓ context7 Library docs ║
║ ✓ figma Design context (frontend) ║
║ ✓ playwright (CLI) Using npx directly ║
╠═══════════════════════════════════════════════════╣
║ engram DOWN: warning only (unless .engram/ exists)║
╚═══════════════════════════════════════════════════╝
| Mode | Use when |
|---|---|
| 1 — Plan + implement | Starting a new feature end-to-end |
| 2 — Implement from plan | You have an existing tasks.md ready to execute |
| 3 — Research | You need to explore or investigate before planning |
| 4 — Bugfix | Fixing a single-domain issue; minimal scope |
| 5 — Bootstrap | First-time project setup |
/sdd → Mode 1
researcher researches unknowns → openspec/changes/<n>/research.md
❓ may ask clarifying questions if scope is ambiguous
planner decomposes into:
proposal.md what and why
design.md architecture decisions
tasks.md task checklist with domain tags + acceptance criteria
automated plan checks:
✓ every task has domain tag + acceptance criteria
✓ no cross-domain file references without markers
✓ API contracts documented for frontend→backend dependencies
✓ test task exists for every implementation task
┌─────────────────────────────────────┐
│ 📋 PLAN APPROVAL GATE │
│ "Validation required before │
│ proceeding" — approve or feedback │
└─────────────────────────────────────┘
orchestrator dispatches implementation agents directly (no intermediary)
(main session) ❓ implementation agents may ask clarifications
Wave 1: frontend + backend + database (parallel, domain-isolated)
Wave 2: tester-front + tester-back (parallel)
Wave 3: github-ops (commits + PRs)
agent-sync updates AGENTS.md + task state
validator quality scorecard /18 (read-only, save-only Engram tier)
+ ✅ manual test checklist (at least 3 specific items)
receives prior context via orchestrator briefing cards
(engram_context: [...]) — never calls mem_search itself
┌─────────────────────────────────────┐
│ ✅ MANUAL TEST GATE │
│ "Before marking this feature │
│ complete, verify the following…" │
│ Reply ✅ to confirm or report issues│
└─────────────────────────────────────┘
opsx:archive
The workflow pauses for human input at four key moments:
| Gate | Emoji | When | Agent |
|---|---|---|---|
| Greenfield intake | 📥 | Start of a new greenfield project | main session |
| Plan/artifact approval | 📋 | After any spec, proposal, or tasks.md is written | planner / main session |
| Clarification | ❓ | When any agent encounters ambiguity | any agent |
| Manual test validation | ✅ | After validator issues a PASS | validator / main session |
All gates use standardized message formats defined in schemas/approval-gates.md. The 📋 and ✅ gates are non-skippable. The ❓ gate fires only for genuinely blocking ambiguity. The 📥 gate can only be bypassed with "proceed without PRD."
Every implementation agent owns its domain from the project-stack domain map. Agents don't read files outside their domain. agent-sync flags violations.
- frontend →
frontend_paths - backend →
backend_paths - database →
database_paths - tester-front →
test_frontend_paths - tester-back →
test_backend_paths
If no domain map exists (bootstrap not run), agents use hardcoded defaults with a [DOMAIN] WARNING.
After implementing any API endpoint, backend automatically:
- Updates the existing
*.postman_collection.jsonif one exists, or - Creates
postman/<project-name>.postman_collection.jsonusing Postman v2.1 format
All collections use {{base_url}} and {{auth_token}} variables.
database detects the ORM from project files before any work:
| Detected file | ORM |
|---|---|
prisma/schema.prisma |
Prisma |
drizzle.config.* |
Drizzle |
alembic.ini |
Alembic (Python) |
manage.py + */models.py |
Django ORM |
db/migrate/ + Gemfile |
ActiveRecord (Ruby) |
go.mod + migrations/*.sql |
golang-migrate |
| ... | 11 ORMs total |
All migration operations use the ORM's CLI directly — no MCP needed.
Playwright is always run via CLI, not MCP:
npx playwright test # all e2e
npx playwright test tests/e2e/feature.spec.ts
npx playwright test --ui
npx playwright test --debugThe Playwright MCP is only used for interactive browser debugging (screenshots, DOM inspection).
If GSAP is in package.json, the frontend agent references gsap-core, gsap-timeline, and gsap-scrolltrigger skills automatically.
Completeness: _/3
Correctness: _/3
Code quality: _/3
Test coverage: _/3
Standards compliance: _/3
Documentation: _/3
Total: _/18 pass threshold: 12/18
Any BLOCKER issue prevents the manual test gate from being skipped.
After the validator issues a PASS, it outputs a structured ✅ checklist:
- What was implemented — 1–3 sentence plain-English summary
- Manual test checklist — at least 3 specific, actionable items (not generic)
- Where to look — key files changed and entry point (URL, CLI command, or component)
- Known limitations — what automated tests did not cover
The developer must reply ✅ to confirm or report issues before the cycle can archive.
- Implementers mark tasks complete in
tasks.mdas they go agent-syncupserts state after each wave (mem_save topic_key=state/wave/<change>/<N>in Engram)- To resume:
/sdd→ main session readstasks.mdcheckboxes +mem_search topic_prefix:state/wave/<change>for the latest wave verdict, reports current state, continues - Cross-session portability: orchestrator runs
engram syncafter archive (or opportunistically) to export memories as a.engram/chunk that ships with the PR
For architectures with separate repos (e.g., api + frontend), all planning and orchestration happens from one coordination repo. Implementation repos are dispatched as Agent Teams teammates.
-
Sync roles:
gh workflow run sdd-sync-targeted.yml -f repos="my-hub" -f repo_role="coordination" gh workflow run sdd-sync-targeted.yml -f repos="my-api" -f repo_role="backend" gh workflow run sdd-sync-targeted.yml -f repos="my-ui" -f repo_role="frontend"
Role → agents installed:
Role Agents standaloneAll 14 coordinationorchestrator, planner, researcher, validator, agent-prep, agent-sync, devstart backendbackend, database, tester-back, github-ops frontendfrontend, tester-front, github-ops -
Enable Agent Teams in the coordination repo:
cp templates/settings/claude-settings.json .claude/settings.json
-
Configure
openspec/config.yamlin the coordination repo:repos: api: path: ../my-api branch_prefix: feat/ frontend: path: ../my-ui branch_prefix: feat/ contracts_dir: openspec/contracts
/sdd in coordination repo → Mode 1
planner tags every task with repo:
- [ ] [repo:api] POST /api/tickets — acceptance: returns 201
- [ ] [repo:frontend] TicketList — acceptance: renders from API
depends_on: [repo:api] POST /api/tickets
PLAN APPROVAL GATE
orchestrator detects MULTI_REPO=true (preflight)
(main session)
dispatch teammate → my-api (backend agent)
implements [repo:api] tasks
writes contracts → openspec/contracts/tickets.yaml
publishes mem_save topic_key=contract/<endpoint> to Engram
agent-sync upserts state/wave/<change>/<N>
dispatch teammate → my-ui (frontend agent)
polls bash scripts/engram-cross-project.sh contract/ <api-repo>
proceeds when the contract topic appears
implements [repo:frontend] tasks consuming contracts
testers run per repo (parallel)
github-ops opens PRs per repo
validator runs cross-repo verification
| Wave | Work |
|---|---|
| 1 | Database migrations |
| 2 | Backend endpoints + Postman collection + OpenAPI contracts |
| 3 | Frontend consuming contracts |
| 4 | Testers (per repo, parallel) |
| 5 | github-ops (per repo, parallel PRs) |
| 6 | Validator (cross-repo) |
Cross-repo wave state lives in Engram, not on disk. Each repo's agent-sync upserts mem_save topic_key=state/wave/<change>/<N> after every wave. The coordination repo's agent-sync aggregates per-repo state into state/wave/<change>/aggregate via bash scripts/engram-cross-project.sh state/wave <repo1> <repo2>. Frontend teammates poll for backend contract/<endpoint> topics before consuming them. See agent_docs/multi-repo.md.
Implementation repos (backend / frontend role) only support /sdd Mode 4 (bugfix) for local quick fixes. All planning, research, and orchestrated work goes through the coordination repo.
| Skill | Wraps | MCP needed | Purpose |
|---|---|---|---|
forge:explore |
opsx:explore |
engram, context7 | Codebase exploration + brownfield project memory under topic_key=project/memory |
forge:research |
— | engram, context7 | Multi-hop research, output to research.md + research/<slug> topic |
forge:propose |
opsx:new, opsx:ff |
engram, context7 | Spec creation + topic_key validation + 📋 gate audit |
forge:implement |
opsx:apply |
engram, context7 | Wave-based TDD with sub-agent isolation per domain |
forge:verify |
opsx:verify |
engram | Isolated quality gate, /18 scorecard, ✅ manual test handoff |
forge:orchestrate |
— | engram | DAG analysis, wave dispatch, multi-repo coordination via Engram |
forge:kickstart |
forge:explore, forge:propose |
engram, context7 | Greenfield project bootstrap: PRD/backlog intake → spec decomposition → wave planning |
Engram is required (memory persistence). Other MCP dependencies fall back gracefully when unavailable — see agent_docs/mcp-integration.md.
Profiles are opt-in Layer 3 extensions. Applied at sync time, committed to repos that need them.
| Profile | When to use | What it adds |
|---|---|---|
frontend |
React/Vue/Angular | Playwright CLI conventions, GSAP skills, UI a11y checks |
backend-api |
REST/GraphQL APIs | Contract testing, OpenAPI spec integration |
brownfield |
Large existing codebases | Mandatory codebase scan before any work |
high-risk |
Auth, payments, PII | Human review gates, 2-reviewer PRs, audit trail |
Apply:
gh workflow run sdd-sync-targeted.yml -f repos="my-repo" -f profile="frontend"Profile files: profiles/
Engram is required. Everything else is conditional or local-pack-only.
| Server | Purpose | Required? | Fallback |
|---|---|---|---|
| engram | Persistent cross-session memory; topic_key contract per schemas/memory-topics.md |
Yes (plugin install) | If unreachable: continue with [MEMORY] WARNING. Block when .engram/ files exist in repo. See agent_docs/engram-install.md. |
| context7 | Up-to-date library documentation | Yes | WebSearch + project-stack manifest version; API calls marked needs-verification |
| figma | Design context for frontend tasks | Conditional — when frontend_paths non-empty |
Skip; more manual design-to-code iterations |
Always CLI-first (npx playwright test). Never a required MCP. Test runner is read from project-stack Test runner field — Playwright is one of several supported runners (Vitest, Jest, Cypress, pytest, RSpec, etc.).
No MCP. Uses the project's ORM CLI directly (npx prisma, alembic, rails db:migrate, dotnet ef, etc.). Eleven ORMs supported via auto-detection by agent-prep.
Engram only (read-only on verify/<change> writes). Otherwise uses Read, Glob, Grep, Bash.
Most-used operations:
mem_search topic_prefix:<ns>/ → search before save
mem_save topic_key=<ns>/<scope> → upsertable persist
mem_context → pull session-relevant context
mem_session_summary → end-of-session digest
See schemas/memory-topics.md for the namespace contract.
Advanced/optional MCP configs are never synced to repos. Install locally:
bash local-packs/bootstrap.sh --tool claude-codeThis installs to ~/.claude/mcp.json — the repo is never touched. Supported tools: claude-code, cursor, copilot, opencode, codex.
For Codex use --tool codex — the script writes TOML (~/.codex/config.toml for --scope global, .codex/config.toml for --scope project) using an append-only [mcp_servers.<name>] merge that preserves existing user keys.
Engram is installed as a Claude Code plugin (not via the local-packs script):
claude plugin marketplace add Gentleman-Programming/engram
claude plugin install engram
export CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 # add to your shell rcFor OpenCode: engram setup opencode. See agent_docs/engram-install.md.
The local-packs/ directory ships recipes for personal MCP add-ons such as Tavily, advanced search backends, and dev-only tools. These remain personal — never synced to repos.
.claude/mcp.json
.cursor/mcp.json
.vscode/mcp.json
.claude/state/# Dry run one repo
gh workflow run sdd-sync-targeted.yml -f repos="my-repo" -f dry_run="true"
# Apply to one repo
gh workflow run sdd-sync-targeted.yml -f repos="my-repo" -f dry_run="false"
# Multiple repos
gh workflow run sdd-sync-targeted.yml -f repos="repo-a,repo-b,repo-c"
# All repos
gh workflow run sdd-sync-targeted.yml -f repos="all" -f exclude="forge"- Org Settings → Rulesets → New ruleset
- Rule: Require workflows to pass
- Workflow:
iNBest-cloud/inbest-sdd-cycle/.github/workflows/sdd-sync-ruleset.yml@main - Start in Evaluate mode, switch to Active after pilot evidence
- Exclude:
forge, archived repos, infra-only repos
1. dry_run=true on one repo → review output
2. dry_run=false on one repo → open and review PR
3. Expand to 3-5 pilot repos
4. Validate results (cycle time, defect rate, team feedback)
5. Org-wide via ruleset
detect-tools.sh finds which AI tools are in use:
.claude/→ Claude Code.cursor/→ Cursor.vscode/or.github/copilot-instructions.md→ Copilot.codex/→ Codex.opencode/→ OpenCode
Versioned section markers:
<!-- forge:section:sdd-workflow:1.1.0 -->
...managed content...
<!-- /forge:section:sdd-workflow -->- Section missing → append
- Same version → skip
- Older version → update content between markers
- No markers → never touch
installer/merge-claude-agents.js filters agents by repo role. For each agent:
- Agent missing → install (with
<!-- forge:agent:<name>:<version> -->marker) - Agent has SDD version marker → force-override on every run
- Agent has no marker (user-customized) → skip
Skills use semver in frontmatter. The installer skips skills at the same or newer version. Downgrade never happens.
Copy templates/settings/hooks.json into .claude/settings.json:
{
"hooks": {
"PostToolUse": [{
"command": "echo \"[TRACE] $(date -Iseconds) tool=$TOOL_NAME\" >> .claude/state/agent-trace.log"
}],
"PreToolUse": [{
"matcher": "Write|Edit",
"agent": "validator",
"command": "echo \"BLOCKED\" && exit 1"
}],
"Stop": [{
"command": "bash scripts/sdd-session-report.sh 2>/dev/null || true"
}]
}
}- Trace log — every tool call logged to
.claude/state/agent-trace.log - Validator block — prevents validator from accidentally writing files
- Session report —
scripts/sdd-session-report.shprints tool usage summary and rotates the log
| Gate | Format | When | Skippable? |
|---|---|---|---|
| 📥 Greenfield intake | PRD/backlog request | Start of greenfield project | Only with explicit "proceed without PRD" |
| 📋 Plan/artifact approval | Validation request | After any spec/proposal/tasks.md written | Never |
| ❓ Clarification | Specific questions | When any agent encounters ambiguity | Never |
| ✅ Manual test validation | Checklist to verify | After validator issues PASS | Only Mode 4 bugfixes (logged) |
- Change touches auth, payments, PII, or infrastructure config
- A greenfield project begins planning without PRD/backlog input
- Any spec is written without presenting the 📋 validation gate
- Any agent proceeds through ambiguity without asking the ❓ clarification gate
- Validator passes without presenting the ✅ manual test checklist
- A sub-agent fails the same task twice
- A spec references external APIs with no reachable docs
high-riskprofile is active and scope exceeds one core module
See docs/GOVERNANCE.md for the full escalation model.