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...
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.
---
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 |
``
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
``
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.
---
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
- 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_negotiablesentries must be testable — not vague valueswhat_wrong_looks_likeentries 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
---
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
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
``
- Vikram authors this alongside his prose architecture doc (same knowledge, structured output)
- Every column must have a
description— not optional - All
fkvalues must referencetable.columnformat:"users.id" - No placeholder values — if unknown, mark the field
"TBD"and add to open questions - Must be updated whenever schema changes — not optional
---
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": [
- 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, andthen— 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_questionsarray 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
---
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"
}
]
}
``