SDD Artifact Templates — Spec-Driven Development
internal prototype · canonical JSON + Dreamborn Forge HTML
internal generated
design_doc · markdown

SDD Artifact Templates — Spec-Driven Development

SDD Artifact Templates — Spec Driven Development Version: 1.1 Date: 2026 04 28 Status: Approved These four templates define the machine readable artifact chain for every project built on the RedKey platform. Agents consume these artifacts. Studio renders them for humans. The goal: eliminate interpretation at execution time. v1.1 change: INTENT.md → INTENT.js...

SDD Artifact Templates — Spec-Driven Development

Version: 1.1 Date: 2026-04-28 Status: Approved

These four templates define the machine-readable artifact chain for every project built on the RedKey platform. Agents consume these artifacts. Studio renders them for humans. The goal: eliminate interpretation at execution time.

v1.1 change: INTENT.md → INTENT.json, SPEC.md → SPEC.json. Prose content moves to string values inside JSON objects. Studio renders human views from these artifacts — agents never produce human-readable markdown as a primary artifact.

---

Overview

Every project produces four artifacts before any agent writes a line of code:

| Artifact | Granularity | Format | Author | Consumer | |---|---|---|---|---| | INTENT.json | One per project | JSON | Justin / Discovery Agent | All agents (via Priya extraction) | | BLUEPRINT.json | One per project (or blueprint/ dir for large) | JSON | Vikram | Priya (brief extraction) | | SPEC.json | One per phase | JSON | Priya | Priya (brief extraction), Mindy (validation) | | POLICY.json | One per project | JSON | Justin / Vikram | Injected into every task brief, Mindy enforcement |

The Chain

`` INTENT.json + BLUEPRINT.json + POLICY.json ↓ Priya reads all three (field extraction, not markdown parsing) ↓ Writes SPEC.json per phase (structured scenarios, completion contracts) ↓ Extracts relevant fields → assembles each task brief ↓ Quinn executes brief → Mindy validates against completion contract + POLICY ``

Key Principle

Quinn never fetches documents. The brief is his document. It is self-contained. Priya extracts the relevant SPEC scenario block, the relevant BLUEPRINT schema section, and the full POLICY into every brief. The upstream artifacts exist for Priya to read — not for Quinn.

Studio renders human views from these artifacts on demand. Justin never reads raw JSON directly. Studio translates INTENT.json into a readable summary, SPEC.json into a reviewable behavior contract, BLUEPRINT.json into a schema diagram or table. The JSON is the source of truth; Studio is the reading layer.

---

Template 1 — INTENT.json

Location: docs/specs/INTENT.json One per project. All agents read this before doing anything.

```json { "version": "1", "project_id": "", "updated_at": "", "project_name": "", "problem": "One paragraph. What is broken or missing? Why does this matter now? Be specific — name the pain, not the category.", "goal": "One sentence. What does done look like from the outside? Must be testable. 'Users can do X' not 'we improve X'.", "users": [ { "type": "", "description": "Who they are and what they are trying to accomplish.", "success": "What success looks like for this user type." } ], "ux_philosophy": { "feel": "How should this feel to use? What emotional response does it target?", "non_negotiable_patterns": [ "Interaction pattern that must always be present" ], "explicitly_avoid": [ "Interaction pattern or feeling to never reproduce" ] }, "brand_voice": { "tone": ["adjective", "adjective"], "language_rules": ["what words or phrases are on-brand"], "off_brand": ["what to explicitly avoid"] }, "non_negotiables": [ "Testable constraint — not a vague value, a specific thing that cannot be compromised." ], "what_wrong_looks_like": [ "Specific failure mode — concrete enough that

Rules
  • Must be written before Design stage begins
  • First draft by Justin at intake; Discovery Agent produces future versions from intake transcripts
  • Every field must have a real value — no empty strings, no placeholder text
  • non_negotiables entries must be testable — not vague values
  • what_wrong_looks_like entries must be concrete enough for an agent to self-check
  • Studio renders this as a human-readable summary for exec approval — Justin approves the rendered view, not the raw JSON

---

Template 2 — BLUEPRINT.json

Location: docs/specs/BLUEPRINT.json (or docs/specs/blueprint/ for large projects) One per project. Priya extracts the relevant section into each task brief.

```json { "version": "1", "project_id": "", "updated_at": "", "stack": { "frontend": "", "backend": "", "database": "", "hosting": "", "external_services": [ { "name": "", "purpose": "", "auth": "" } ] }, "schema": { "tables": [ { "name": "", "description": "", "columns": [ { "name": "", "type": "", "nullable": true, "default": null, "fk": null, "description": "" } ], "indexes": [ { "columns": [], "unique": false } ], "rls": "" } ] }, "api": { "base_url": "", "auth": "", "endpoints": [ { "method": "", "path": "", "description": "", "auth_required": true, "request": { "params": {}, "body": {} }, "response": { "200": {}, "errors": [ { "status": 0, "condition": "", "body": {} } ] } } ] }, "services": { "dependencies": [ { "name": "", "version": "", "purpose": "" } ], "env_vars": [ { "na

Large Project Split

For projects with 15+ tables or 30+ endpoints, split into:

`` docs/specs/blueprint/ schema.json ← tables, columns, indexes, RLS api.json ← endpoints with full request/response shapes services.json ← dependencies, env vars, external services ``

Rules
  • Vikram authors this alongside his prose architecture doc (same knowledge, structured output)
  • Every column must have a description — not optional
  • All fk values must reference table.column format: "users.id"
  • No placeholder values — if unknown, mark the field "TBD" and add to open questions
  • Must be updated whenever schema changes — not optional

---

Template 3 — SPEC.json (per phase)

Location: docs/specs/phases/NN-[phase-name]-spec.json One per phase. Priya extracts the relevant feature object into each task brief.

```json { "version": "1", "project_id": "", "phase": { "id": "phase-N", "name": "", "status": "draft | approved | complete", "depends_on": [] }, "features": [ { "id": "FEAT-N.N", "name": "", "scope": "What this feature covers. One sentence. What it explicitly does not cover.", "scenarios": [ { "name": "", "given": "Precondition — system state before action", "when": "Action — what the user or system does", "then": "Outcome — what must be true after" } ], "error_states": [ { "condition": "", "response": "Exact response — message, status code, system behavior" } ], "edge_cases": [ { "case": "", "expected": "Exact expected behavior" } ], "out_of_scope": [ "Thing that seems related but is not in this feature" ], "completion_contract": { "type": "file | signal | none", "criteria": [ "Binary check derived from a 'then' clause above" ] } } ], "cross_feature_constraints": [ "Rule that applies across multiple features in this phase" ], "open_questions": [

Rules
  • One file per phase — not one per project, not one per feature
  • Feature IDs use dot notation: FEAT-1.1, FEAT-1.2, FEAT-2.1
  • Every scenario must have given, when, and then — no partial scenarios
  • Every feature must have out_of_scope — prevents Quinn from over-building
  • Every feature must have a completion_contract — this becomes Mindy's validation checklist
  • open_questions array must be empty before spec is used — non-empty means spec is not done
  • Priya reads this file and extracts the relevant feature object into each task brief by id

---

Template 4 — POLICY.json

Location: docs/specs/POLICY.json One per project. Injected in full into every task brief. Mindy checks every output against it.

``json { "version": "1", "project_id": "", "updated_at": "", "rules": [ { "id": "", "category": "typography | security | performance | patterns | dependencies | accessibility", "severity": "hard | warn", "description": "Human-readable description of the rule", "check": "Shell command or grep pattern Mindy can run to verify", "applies_to": "all | frontend | backend | sql | config", "rationale": "Why this rule exists" } ] } ``