{
  "id": "2026-04-28-sdd-artifact-templates-43f185f9fa",
  "scope": "redkey",
  "source_of_truth": "repo",
  "source_path": "docs/specs/2026-04-28-sdd-artifact-templates.md",
  "source_kind": "markdown",
  "visibility": "internal",
  "renderer_id": "design_doc.dreamborn-forge.generated.v1",
  "design_system": "dreamborn-design-system:forge",
  "generated_at": "2026-05-09T13:00:55.692Z",
  "artifact_type": "design_doc",
  "schema_version": "design_doc.generated.v1",
  "title": "SDD Artifact Templates — Spec-Driven Development",
  "summary": "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...",
  "format_source": "markdown",
  "sections": [
    {
      "title": "SDD Artifact Templates — Spec-Driven Development",
      "level": 1,
      "body": "**Version:** 1.1\n**Date:** 2026-04-28\n**Status:** Approved\n\nThese 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.\n\n**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.\n\n---"
    },
    {
      "title": "Overview",
      "level": 2,
      "body": "Every project produces four artifacts before any agent writes a line of code:\n\n| Artifact | Granularity | Format | Author | Consumer |\n|---|---|---|---|---|\n| `INTENT.json` | One per project | JSON | Justin / Discovery Agent | All agents (via Priya extraction) |\n| `BLUEPRINT.json` | One per project (or `blueprint/` dir for large) | JSON | Vikram | Priya (brief extraction) |\n| `SPEC.json` | One per phase | JSON | Priya | Priya (brief extraction), Mindy (validation) |\n| `POLICY.json` | One per project | JSON | Justin / Vikram | Injected into every task brief, Mindy enforcement |"
    },
    {
      "title": "The Chain",
      "level": 3,
      "body": "```\nINTENT.json + BLUEPRINT.json + POLICY.json\n          ↓\n     Priya reads all three (field extraction, not markdown parsing)\n          ↓\n     Writes SPEC.json per phase (structured scenarios, completion contracts)\n          ↓\n     Extracts relevant fields → assembles each task brief\n          ↓\n     Quinn executes brief → Mindy validates against completion contract + POLICY\n```"
    },
    {
      "title": "Key Principle",
      "level": 3,
      "body": "**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.\n\n**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.\n\n---"
    },
    {
      "title": "Template 1 — INTENT.json",
      "level": 2,
      "body": "**Location:** `docs/specs/INTENT.json`\n**One per project. All agents read this before doing anything.**\n\n```json\n{\n  \"version\": \"1\",\n  \"project_id\": \"\",\n  \"updated_at\": \"\",\n  \"project_name\": \"\",\n  \"problem\": \"One paragraph. What is broken or missing? Why does this matter now? Be specific — name the pain, not the category.\",\n  \"goal\": \"One sentence. What does done look like from the outside? Must be testable. 'Users can do X' not 'we improve X'.\",\n  \"users\": [\n    {\n      \"type\": \"\",\n      \"description\": \"Who they are and what they are trying to accomplish.\",\n      \"success\": \"What success looks like for this user type.\"\n    }\n  ],\n  \"ux_philosophy\": {\n    \"feel\": \"How should this feel to use? What emotional response does it target?\",\n    \"non_negotiable_patterns\": [\n      \"Interaction pattern that must always be present\"\n    ],\n    \"explicitly_avoid\": [\n      \"Interaction pattern or feeling to never reproduce\"\n    ]\n  },\n  \"brand_voice\": {\n    \"tone\": [\"adjective\", \"adjective\"],\n    \"language_rules\": [\"what words or phrases are on-brand\"],\n    \"off_brand\": [\"what to explicitly avoid\"]\n  },\n  \"non_negotiables\": [\n    \"Testable constraint — not a vague value, a specific thing that cannot be compromised.\"\n  ],\n  \"what_wrong_looks_like\": [\n    \"Specific failure mode — concrete enough that an agent can self-check before submitting output.\"\n  ],\n  \"success_metrics\": [\n    { \"metric\": \"\", \"target\": \"\" }\n  ],\n  \"scope_boundary\": {\n    \"in_v1\": [\"What is explicitly in scope for this version\"],\n    \"out_v1\": [\"What is explicitly out of scope — things someone would assume are included\"]\n  }\n}\n```"
    },
    {
      "title": "Rules",
      "level": 3,
      "body": "- Must be written before Design stage begins\n- First draft by Justin at intake; Discovery Agent produces future versions from intake transcripts\n- Every field must have a real value — no empty strings, no placeholder text\n- `non_negotiables` entries must be testable — not vague values\n- `what_wrong_looks_like` entries must be concrete enough for an agent to self-check\n- Studio renders this as a human-readable summary for exec approval — Justin approves the rendered view, not the raw JSON\n\n---"
    },
    {
      "title": "Template 2 — BLUEPRINT.json",
      "level": 2,
      "body": "**Location:** `docs/specs/BLUEPRINT.json` (or `docs/specs/blueprint/` for large projects)\n**One per project. Priya extracts the relevant section into each task brief.**\n\n```json\n{\n  \"version\": \"1\",\n  \"project_id\": \"\",\n  \"updated_at\": \"\",\n  \"stack\": {\n    \"frontend\": \"\",\n    \"backend\": \"\",\n    \"database\": \"\",\n    \"hosting\": \"\",\n    \"external_services\": [\n      { \"name\": \"\", \"purpose\": \"\", \"auth\": \"\" }\n    ]\n  },\n  \"schema\": {\n    \"tables\": [\n      {\n        \"name\": \"\",\n        \"description\": \"\",\n        \"columns\": [\n          {\n            \"name\": \"\",\n            \"type\": \"\",\n            \"nullable\": true,\n            \"default\": null,\n            \"fk\": null,\n            \"description\": \"\"\n          }\n        ],\n        \"indexes\": [\n          { \"columns\": [], \"unique\": false }\n        ],\n        \"rls\": \"\"\n      }\n    ]\n  },\n  \"api\": {\n    \"base_url\": \"\",\n    \"auth\": \"\",\n    \"endpoints\": [\n      {\n        \"method\": \"\",\n        \"path\": \"\",\n        \"description\": \"\",\n        \"auth_required\": true,\n        \"request\": {\n          \"params\": {},\n          \"body\": {}\n        },\n        \"response\": {\n          \"200\": {},\n          \"errors\": [\n            { \"status\": 0, \"condition\": \"\", \"body\": {} }\n          ]\n        }\n      }\n    ]\n  },\n  \"services\": {\n    \"dependencies\": [\n      { \"name\": \"\", \"version\": \"\", \"purpose\": \"\" }\n    ],\n    \"env_vars\": [\n      { \"name\": \"\", \"required\": true, \"description\": \"\", \"example\": \"\" }\n    ]\n  }\n}\n```"
    },
    {
      "title": "Large Project Split",
      "level": 3,
      "body": "For projects with 15+ tables or 30+ endpoints, split into:\n\n```\ndocs/specs/blueprint/\n  schema.json      ← tables, columns, indexes, RLS\n  api.json         ← endpoints with full request/response shapes\n  services.json    ← dependencies, env vars, external services\n```"
    },
    {
      "title": "Rules",
      "level": 3,
      "body": "- Vikram authors this alongside his prose architecture doc (same knowledge, structured output)\n- Every column must have a `description` — not optional\n- All `fk` values must reference `table.column` format: `\"users.id\"`\n- No placeholder values — if unknown, mark the field `\"TBD\"` and add to open questions\n- Must be updated whenever schema changes — not optional\n\n---"
    },
    {
      "title": "Template 3 — SPEC.json (per phase)",
      "level": 2,
      "body": "**Location:** `docs/specs/phases/NN-[phase-name]-spec.json`\n**One per phase. Priya extracts the relevant feature object into each task brief.**\n\n```json\n{\n  \"version\": \"1\",\n  \"project_id\": \"\",\n  \"phase\": {\n    \"id\": \"phase-N\",\n    \"name\": \"\",\n    \"status\": \"draft | approved | complete\",\n    \"depends_on\": []\n  },\n  \"features\": [\n    {\n      \"id\": \"FEAT-N.N\",\n      \"name\": \"\",\n      \"scope\": \"What this feature covers. One sentence. What it explicitly does not cover.\",\n      \"scenarios\": [\n        {\n          \"name\": \"\",\n          \"given\": \"Precondition — system state before action\",\n          \"when\": \"Action — what the user or system does\",\n          \"then\": \"Outcome — what must be true after\"\n        }\n      ],\n      \"error_states\": [\n        { \"condition\": \"\", \"response\": \"Exact response — message, status code, system behavior\" }\n      ],\n      \"edge_cases\": [\n        { \"case\": \"\", \"expected\": \"Exact expected behavior\" }\n      ],\n      \"out_of_scope\": [\n        \"Thing that seems related but is not in this feature\"\n      ],\n      \"completion_contract\": {\n        \"type\": \"file | signal | none\",\n        \"criteria\": [\n          \"Binary check derived from a 'then' clause above\"\n        ]\n      }\n    }\n  ],\n  \"cross_feature_constraints\": [\n    \"Rule that applies across multiple features in this phase\"\n  ],\n  \"open_questions\": [\n    { \"id\": 1, \"question\": \"\", \"owner\": \"\", \"due\": \"\" }\n  ]\n}\n```"
    },
    {
      "title": "Rules",
      "level": 3,
      "body": "- One file per phase — not one per project, not one per feature\n- Feature IDs use dot notation: FEAT-1.1, FEAT-1.2, FEAT-2.1\n- Every scenario must have `given`, `when`, and `then` — no partial scenarios\n- Every feature must have `out_of_scope` — prevents Quinn from over-building\n- Every feature must have a `completion_contract` — this becomes Mindy's validation checklist\n- `open_questions` array must be empty before spec is used — non-empty means spec is not done\n- Priya reads this file and extracts the relevant feature object into each task brief by `id`\n\n---"
    },
    {
      "title": "Template 4 — POLICY.json",
      "level": 2,
      "body": "**Location:** `docs/specs/POLICY.json`\n**One per project. Injected in full into every task brief. Mindy checks every output against it.**\n\n```json\n{\n  \"version\": \"1\",\n  \"project_id\": \"\",\n  \"updated_at\": \"\",\n  \"rules\": [\n    {\n      \"id\": \"\",\n      \"category\": \"typography | security | performance | patterns | dependencies | accessibility\",\n      \"severity\": \"hard | warn\",\n      \"description\": \"Human-readable description of the rule\",\n      \"check\": \"Shell command or grep pattern Mindy can run to verify\",\n      \"applies_to\": \"all | frontend | backend | sql | config\",\n      \"rationale\": \"Why this rule exists\"\n    }\n  ]\n}\n```"
    },
    {
      "title": "Example Rules",
      "level": 3,
      "body": "```json\n{\n  \"rules\": [\n    {\n      \"id\": \"no-google-fonts\",\n      \"category\": \"security\",\n      \"severity\": \"hard\",\n      \"description\": \"No external font CDN references — all fonts must be self-hosted\",\n      \"check\": \"grep -r 'fonts.googleapis.com' {output_dir}/\",\n      \"applies_to\": \"frontend\",\n      \"rationale\": \"Privacy, performance, and offline reliability\"\n    },\n    {\n      \"id\": \"font-primary\",\n      \"category\": \"typography\",\n      \"severity\": \"hard\",\n      \"description\": \"Body text must use DM Sans, not any other sans-serif\",\n      \"check\": \"grep -r 'font-family' {output_dir}/css/ | grep -v 'DM Sans'\",\n      \"applies_to\": \"frontend\",\n      \"rationale\": \"Design system consistency\"\n    },\n    {\n      \"id\": \"no-raw-sql-in-app\",\n      \"category\": \"security\",\n      \"severity\": \"hard\",\n      \"description\": \"Application code must not contain raw SQL strings — use parameterized queries or ORM\",\n      \"check\": \"grep -r 'SELECT\\\\|INSERT\\\\|UPDATE\\\\|DELETE' {output_dir}/src/ --include='*.js'\",\n      \"applies_to\": \"backend\",\n      \"rationale\": \"SQL injection prevention\"\n    },\n    {\n      \"id\": \"env-vars-documented\",\n      \"category\": \"patterns\",\n      \"severity\": \"hard\",\n      \"description\": \"Every env var used in code must appear in BLUEPRINT.json services.env_vars\",\n      \"check\": \"manual — Mindy cross-references code against BLUEPRINT.json\",\n      \"applies_to\": \"all\",\n      \"rationale\": \"Deployment reliability — no surprise missing vars\"\n    }\n  ]\n}\n```"
    },
    {
      "title": "Severity Levels",
      "level": 3,
      "body": "| Severity | Meaning | Mindy action |\n|---|---|---|\n| `hard` | Output fails if rule is violated | Post task.blocked, create correction task |\n| `warn` | Flag for Justin's review but do not block | Note in phase health report |"
    },
    {
      "title": "Rules",
      "level": 3,
      "body": "- POLICY.json is project-specific but rules can be copied from a library\n- The `check` field must be a runnable shell command where possible — not a vague description\n- `{output_dir}` is a placeholder Mindy replaces with the actual output path\n- Hard rules are enforced before Mindy calls `mark_task_validated`\n- Warn rules are summarized in the phase health report to Justin\n- Add rules incrementally — start with the 3-5 non-negotiables, add more as patterns emerge\n\n---"
    },
    {
      "title": "How Priya Uses These Templates",
      "level": 2,
      "body": "When Priya writes a task brief for Quinn, she assembles it from four extractions:\n\n```json\n{\n  \"environment\": \"[auto-injected by dispatch.js]\",\n  \"context\": {\n    \"intent_ref\": \"docs/specs/INTENT.json\",\n    \"ux_philosophy\": \"[intent.ux_philosophy.feel — 2-3 sentences]\",\n    \"non_negotiables\": \"[intent.non_negotiables — full array]\"\n  },\n  \"what_to_build\": \"[full feature object from SPEC.json where id = FEAT-N.N]\",\n  \"schema\": \"[only tables/columns from BLUEPRINT.json that this task touches]\",\n  \"constraints\": \"[full POLICY.json rules where applies_to = 'all' or matches task domain]\",\n  \"output\": {\n    \"output_path\": \"[from PLAN.json]\",\n    \"completion\": \"[feature.completion_contract from SPEC.json]\"\n  }\n}\n```\n\nQuinn reads this brief. He does not read INTENT.json, BLUEPRINT.json, SPEC.json, or POLICY.json directly. The brief is self-contained.\n\n---"
    },
    {
      "title": "File Structure",
      "level": 2,
      "body": "```\ndocs/specs/\n  INTENT.json\n  BLUEPRINT.json          ← or blueprint/ for large projects\n  POLICY.json\n  phases/\n    01-[name]-spec.json\n    02-[name]-spec.json\n    ...\n```\n\n---"
    },
    {
      "title": "Validation Checklist (before Build starts)",
      "level": 2,
      "body": "Before any task is dispatched to Quinn, verify:\n\n- [ ] INTENT.json: all fields populated, no empty strings, non_negotiables are testable\n- [ ] BLUEPRINT.json: every column has a description, no TBD values in schema\n- [ ] SPEC.json (phase): open_questions array is empty, every feature has a completion_contract\n- [ ] POLICY.json: every hard rule has a runnable check command\n- [ ] Justin has reviewed and approved all four artifacts at exec gate (via Studio rendered views)"
    }
  ],
  "html_path": "artifacts/2026-04-28-sdd-artifact-templates-43f185f9fa.html",
  "json_path": "artifacts/2026-04-28-sdd-artifact-templates-43f185f9fa.json"
}