{"slug": "i-ran-3-months-of-spec-driven-development-without-ever-reading-the-code", "title": "I ran 3 months of spec-driven development without ever reading the code", "summary": "A developer known as a scrum master ran a three-month solo project using spec-driven development without ever reading the code, relying on LLMs to write specs and tests. The system, published as 'backlog-as-data', treats the backlog as YAML frontmatter in spec files, with lifecycle automation and fresh-context reviewers to avoid confirmation bias.", "body_md": "I'm a scrum master. I was a developer ten years ago. I have enough background to\n\ndiscuss design and trade-offs with an LLM — but three months ago I made a\n\ndeliberate bet on my solo project: **I would never read the code.**\n\nThe specs define the tests. The tests control the code. The code is a black\n\nbox.\n\nI'm not claiming this is what everyone should do. But it's *my* bet, and it\n\nforced a system into existence: when nobody reads the code, the **process** has\n\nto carry the trust that a code-reading human normally provides. I've just\n\npublished that system as a reference implementation:\n\n** backlog-as-data** — the full\n\nHere's the short version.\n\nMost agent task-management tools store tasks in a dedicated place — a\n\n`tasks.json`\n\n, a database, a `backlog/`\n\nfolder. My bet is different: **the\nbacklog is the YAML frontmatter of my spec files.** One file per ticket,\n\n``` python\n---\nid: PARSE-07\ntitle: Tolerate CRLF in decklist import\ntype: ticket\nstatus: todo\npriority: should\nexec:\n  model: sonnet\n  effort: think\n  review: light\n  matured: 2026-07-22\n---\n\n# PARSE-07 — Tolerate CRLF in decklist import\n\nThe spec body: design, contracts, test cases. The ticket file IS the spec.\n```\n\nEverything below the frontmatter is the spec — written by the LLM, after it\n\nhas challenged the need I expressed in conversation. The frontmatter is data —\n\nowned by a small CLI, mutated only through it. Same file, so they can never\n\ndrift apart.\n\nWhy it matters: \"move it to Done\" is not an operation. LLMs (and humans)\n\nmangle documents when a state change means relocating text. Making status a\n\nfield makes every transition a one-line, idempotent, testable mutation. The\n\nboard I look at (a small web page on my server, with GitHub deep links to each\n\nspec) and the readable markdown view are **generated projections**, locked by\n\na do-not-edit sentinel and covered by a coherence test.\n\nCommitting to a ticket and deciding *how hard to think about it* are separate\n\nacts. Before any agent runs, a ticket gets **matured** with a triplet:\n\n`model`\n\n— which model implements it (`haiku`\n\n→ `fable`\n\n)`effort`\n\n— reasoning depth injected into the prompt`review`\n\n— the review gate dosage: `none`\n\n, `light`\n\n(1 reviewer), `deep`\n\n(3)A trivial rename gets `haiku / none / none`\n\n. An irreversible data migration\n\ngets the most capable model, maximum reasoning, three reviewers. The decision\n\nis versioned with the ticket and auditable months later (`matured: <date>`\n\n).\n\nAnd the implementer sub-agent runs *exactly* the matured model — its report\n\nmust open with `Model used: …`\n\nso the decision is verifiable after the fact.\n\nThis is lean thinking applied to agent budget: pay for defect detection in\n\nproportion to the cost of a defect slipping through.\n\n`todo → wip → merged → shipped`\n\nis set by hooks attached to my workflow\n\ncommands — launch sets `wip`\n\n, integration sets `merged`\n\n(only for tickets\n\nwhose `feat(TICKET-ID):`\n\ncommit is *actually on the branch*), deploy sets\n\n`shipped`\n\n. Nobody — human or agent — moves the back half of the lifecycle by\n\nhand. The hooks always exit 0 (lifecycle automation must never block a\n\ndelivery) and commit surgically (a shared main checkout with 10+ parallel\n\nworktrees taught me that `git add specs/`\n\nsweeps up a neighbor session's\n\nwork — lesson learned the hard way, with a date on it).\n\nThis is the part I haven't seen elsewhere. When the implementer sub-agent\n\nfinishes (in its own isolated git worktree), the orchestrator spawns\n\n**fresh-context reviewers**: they get the ticket id, the spec path, the\n\nworktree, the commit SHA, and four review axes. *Nothing else.* No summary of\n\nwhat the implementer did, no hints of where to look. Contaminating a\n\nreviewer's context is the main vector for confirmation bias.\n\nThree details that took incidents to learn:\n\n`git status`\n\nis checked before and after the review.Does it work? The day before publishing, I ran the gate on the published repo\n\nitself: a fresh reviewer compared my English translations against the French\n\noriginals and raised 3 findings — including a mistranslated counter that would\n\nhave silently corrupted the review register of anyone following the English\n\nversion. The gate paid for itself on its first public outing.\n\nMy three touchpoints per ticket are all decisions, never mechanics: agreeing\n\non the need (in conversation — the LLM challenges me, then writes the spec),\n\nsaying \"mature it and run it\" (with the review dosage), and deciding to\n\ndeploy. Everything in between — the CLI calls, the spec writing, the agent\n\norchestration, the integration — is the agent's job. I never type a backlog\n\ncommand. The CLI is agent-facing: determinism comes from the agent having no\n\nhand-editing path, not from me doing the bookkeeping.\n\nIf you're running coding agents daily and your backlog is still a markdown\n\nto-do list that gets mangled every time an agent \"moves something to Done\" —\n\nthe data model alone might be worth the read:\n\n** github.com/giboulz/backlog-as-data**.\n\nHappy to answer anything in the comments — including whether the\n\nnever-read-the-code bet has burned me yet.", "url": "https://wpnews.pro/news/i-ran-3-months-of-spec-driven-development-without-ever-reading-the-code", "canonical_source": "https://dev.to/giboulz/i-ran-3-months-of-spec-driven-development-without-ever-reading-the-code-1nbc", "published_at": "2026-07-22 21:28:42+00:00", "updated_at": "2026-07-22 21:31:02.895700+00:00", "lang": "en", "topics": ["developer-tools", "artificial-intelligence", "large-language-models", "ai-agents"], "entities": ["GitHub", "LLM", "sonnet", "haiku", "fable"], "alternates": {"html": "https://wpnews.pro/news/i-ran-3-months-of-spec-driven-development-without-ever-reading-the-code", "markdown": "https://wpnews.pro/news/i-ran-3-months-of-spec-driven-development-without-ever-reading-the-code.md", "text": "https://wpnews.pro/news/i-ran-3-months-of-spec-driven-development-without-ever-reading-the-code.txt", "jsonld": "https://wpnews.pro/news/i-ran-3-months-of-spec-driven-development-without-ever-reading-the-code.jsonld"}}