Spec-driven development with AI agents: constitutions, checkpoints, and handoffs A developer has developed a spec-driven development workflow for AI coding agents that uses explicit checkpoints and structured handoffs to prevent context rot and unreviewable diffs on large features. The approach treats agents like brilliant but forgetful senior engineers, requiring them to stop at checkpoints, pass gates, and write briefs for a separate reviewer agent. The developer reports that on a recent AI-system backend feature, six different agent sessions touched the code across seven checkpoints without needing re-explanation of settled decisions. AI coding agents are strangely lopsided. Hand one a well-scoped task and it writes better code, faster, than I do. Hand it a large feature, the kind that takes days and touches a dozen files across several layers, and the failure mode changes. The context window fills up and quality quietly degrades AKA context rot . A fresh session, missing the history, confidently invents an API that never existed. And even when the code is good, you're left staring at a 3,000-line diff you can't meaningfully review. Those failures are not solved by the model alone. They are largely a process problem. The backbone I work inside isn't mine and isn't novel: a constitution, specs, and deliberately stabilized plans. It's spec-driven development, which has been around in various shapes for years. What I added from running it day to day were two operational mechanisms that made it survive long features: explicit checkpoints and structured handoffs . The mental model I use: treat the agent like a brilliant but forgetful senior engineer. Sharp in the moment, no long-term memory, occasionally overconfident. You wouldn't hand that person a two-week feature and walk away. You'd give them the ground rules, a spec, and a plan, then review their work in slices. That's the whole idea. Standard stuff, so I'll keep it short. That gives the agent rails. But rails aren't enough for long work. A plan might have 25 tasks. Executing all 25 in one shot lands you right back at the unreviewable-diff problem. So I slice the plan into checkpoints , review-sized groups of tasks, and the agent works one checkpoint at a time, then stops . At each stop it has to: get the gate green lint, types, architecture checks, tests , tick off the tasks, write a short note recording every deviation from the plan, and hand off for review. The review itself is two-stage. The coding agent doesn't send its work straight to me. It writes a brief for a separate reviewer agent , stating what changed and why. I read that brief first, because what the coder chooses to explain and what it leaves out tells me where to look. Then the reviewer agent goes to work on the diff, and I read its findings against my own. The slice is a few hundred lines, one coherent unit, so this is actually tractable. Approval is mine either way; nothing continues on an agent's say-so. Two things fall out of this: The idea of pausing between steps isn't new. What I've made repeatable is the artifact: a shared checkpoint tracker that both the human and the agent write to, so stopping-for-review is the default, not an afterthought. Long features outlive a single agent session. The context window fills, or I come back the next day, or I switch models. A fresh session starts with zero memory of the last three days of decisions. Left alone, it will re-litigate settled choices or hallucinate the current state. I learned this the tedious way. Fresh sessions reintroduced an API we'd deleted two days earlier, reopened architectural decisions that were already settled, quietly dropped an invariant because the reasoning behind it had scrolled out of the window. After the third time reviewing the same decision, I stopped waiting for it to happen. So I don't wait for a session to degrade. I retire it on purpose and have it hand the work to a fresh agent on my terms. Every feature carries a HANDOFF document, a living page that tells the next session exactly what it needs and nothing it doesn't: A fresh agent reads the handoff and the frozen plan, and it's grounded again. No rot, no invention, because the ground truth lives in the documents rather than in a context window that's about to overflow. On a recent AI-system backend feature, six different agent sessions touched the code across its seven checkpoints. Each started from a fresh context, some were different models, and none of them needed me to re-explain a decision that had already been made. I read every handoff as it was written, and tightened the template whenever a fresh session asked a question the document should have already answered. One more lever: not every step deserves the same horsepower. Planning and code review are the highest-leverage, hardest-to-reverse steps, and a bad plan poisons everything downstream. Implementation against a frozen, detailed plan is comparatively mechanical. So I tier: The human review at each checkpoint is the safety net that makes the cheaper coding pass safe. It's a nice cost/quality trade: spend where thinking matters, save where the rails are already in place. Request → Constitution → Spec → Frozen Plan │ └─ Checkpoint → Gate → Review × N ↑ │ └───── HANDOFF ◀─────┘ The surprising lesson: as agents get better at writing code , the bottleneck moves to keeping them grounded and keeping yourself in the loop . A constitution, checkpoints, and handoffs are how I do both, and honestly, they've made me a more disciplined engineer even on the parts I write by hand. I've templated the whole thing constitution, spec/plan templates, the checkpoint tracker, and the handoff doc as a starter kit I drop into new projects: hannody/spec-kit . It's language- and domain-agnostic; fork it and tune the constitution to your stack.