blog
Code consistency is the casualty of agent velocity
· updated · spec-driven-development · claude-code · ai-coding · benchmarks
TLDR
Agents write code faster than they stay coherent with themselves: by task ten the repo has multiple dialects of the same pattern, tests stay green, and the next session amplifies the drift.
spec-driven-dev keeps one SPEC.md at the repo root — telegraph-encoded, re-read every command — so task ten is built against the same constraints as task one.
A measured 41% mean token cut versus prose makes that re-read cheap enough to do on every turn.
The drift nobody decides on
Consistency fails first under agent velocity: inconsistent code passes tests and still rots the project, because the next agent learns the drift and amplifies it.
The failure mode is not usually the agent writing wrong code. It is the agent writing inconsistent code.
An LLM produces diffs faster than a human reviews them, and faster than the session stays coherent with earlier choices. Task one picks a pattern. By task ten the agent has invented two more. Nobody approved a second error-handling convention or a third response envelope. The codebase just accumulates dialects, one reasonable-looking change at a time.
Wrong code fails tests. Inconsistent code often passes every test and still taxes the next session: the agent reads the tree, samples every dialect, and multiplies them.
This is the same class of failure as a half-finished convention sweep.
On this site, a type-scale change once landed on one page and left the others on the old scale (§B.1 in lab5.ca’s own SPEC.md).
A voice rewrite updated the landing copy and left banned marketing phrases in older blog posts (§B.2).
Neither failure is “the code is wrong.”
Both are “the system no longer speaks one language.”
Agent sessions invent that class of drift continuously unless something outside the chat pins the rules.
One small spec, re-read every turn
A single small SPEC.md re-parsed on every command, with a stable cite on every row, is the defense: a cold agent reads the contract instead of reconstructing intent from chat it no longer has.
Keep one SPEC.md at the repo root, dense enough to sit in context, and have the agent re-parse it on every command.
Six fixed sections, fixed order:
§G GOAL— what the project is for, one short statement.§C CONSTRAINTS— hard rules: language, runtime, platform, external systems.§I INTERFACES— public surface: routes, CLI commands, file formats.§V INVARIANTS— properties that must always hold, numbered.§T TASKS— work rows: id, status, description, the invariants each task must respect.§B BUGS— incidents with date, cause, and the invariant that should have caught them.
Addressing is what makes this more than a notes file.
Every row has a stable cite: §V.3, §T.7, §B.2.
Code comments link the invariant they uphold.
Tests reference the bug they guard.
Commits cite the task they close.
The spec survives /clear, a week away, and a handoff.
When the agent comes back cold, it reads the contract — not a chat transcript it no longer has.
The spec is the only artifact that earns its tokens. Everything else has to save more tokens later, or get cut.
Spec, build, check as the slash-command loop
/sdd:spec is the only command that mutates the contract; build routes under-specified failures through backprop; check reports drift; condense and reorganize keep a long-lived spec inside budget.
spec-driven-dev maps that model onto slash commands (Claude Code is the reference host):
/sdd:spec— sole mutator ofSPEC.md. A gate turns free-form intent into new, distill, amend, fold-in, or backprop./sdd:build— plan and execute against the spec, single-thread for writes. On a test or build failure that looks under-specified, it routes through backprop before retrying./sdd:check— read-only drift report against the working tree. Writes nothing. May fan out to read-only sub-agents./sdd:explain— telegraph → prose for one cite when a human needs plain English.
Housekeeping is operator-triggered, not background magic:
/sdd:condense when the spec crosses the token budget (folds, trims, archives old §T/§B rows to SPEC.archive.md);
/sdd:reorganize to cluster §V by topic, renumber, and sweep cites in one commit.
Both land as a single atomic commit — rollback is git revert.
Design drafts (/sdd:design) stay outside SPEC.md until folded in.
Nothing else writes the contract.
How I verify agent behavior on real systems is a separate post: smoke-testing an LLM agent with a Claude Code skill. This post is how the authoring agent stays coherent while it writes.
Telegraph: the compression, benchmarked
A prose spec pays about 1.7× the tokens of the telegraph form for the same facts — and you pay that on every turn the agent re-reads it.
“Small enough to sit in context” only works if the encoding holds up.
SPEC.md is written in telegraph: dropped articles and filler, fragments where a fragment carries the meaning, unpadded pipe tables, and a small symbol set (→ ≥ ≤ ! ? §).
Heavier Unicode is avoided on purpose — fancy operators often tokenize into more pieces than the plain ASCII word.
“The middleware must verify the token on every request before the handler runs” becomes:
V12: every req → auth check before handler
Measurement: 30 rows of the SDD repo’s own SPEC.md, each run through Claude’s tokenizer against a minimal prose rewrite of the same row.
Telegraph lands a 41% mean reduction (median 39%, n=30).
Method and per-row numbers live in benchmarks/telegraph/, not a slide.
Inverted: prose costs roughly 1.7× the tokens for identical content. That cost is not paid once. It is paid on every re-read, which is exactly the path this design depends on.
Human readability is handled out of band:
steno for reviewer-facing prose, /sdd:explain for any row on demand.
The model keeps the dense form; you decompress when you need to.
Every failure tightens the spec
Backprop turns an under-specified failure into a permanent guard rail: a §B row, often a tighter §V, and a failing test written before the fix.
When /sdd:build fails in a way that is not a one-off typo — when the failure is a class of mistake — the loop does not silently patch and move on.
It records a §B bug row and, where warranted, adds or tightens a §V invariant that catches the class.
Then it writes the failing test first, ships the fix, and cross-cites the commits.
Real examples from the SDD plugin’s own history:
- A grant sweep fixed
Skillpermissions on some skills and leftGlobopen on others (§B.16,§B.17) — a partial convention that would have reappeared without an invariant. - Docs named
/sdd:backpropas a user command when the real route is/sdd:spec→ BACKPROP (§B.14) — naming drift that confuses the next session. - Compression claims in the README drifted from measured numbers (
§B.5,§B.20) until the claim itself became something the check process must keep honest.
Each incident becomes a permanent rail. The invariant set only grows. Drift already hit once has a named row that refuses to ship the same shape again.
What I gave up
Single-thread writes, a Claude Code-first plugin surface, and telegraph that is hard to skim cold — traded for code that still makes sense when I am the only reviewer six months later.
Builds serialize on one writer.
Read-only check work may fan out; code and SPEC.md mutations do not.
That is slower than parallel agent swarms.
I am the bottleneck on purpose: throughput is not the objective.
The reference host is Claude Code (slash commands and the plugin model). Other hosts can load the same skills where the runtime allows; the published install path is Claude’s marketplace.
Telegraph is hostile to skim until /sdd:explain becomes habit.
That cost is paid by the human occasionally, not by the model on every turn.
I am not optimizing for agent throughput. I am optimizing for one reviewer, one dialect, still legible in six months. Consistency is what that costs.
Install the plugin and scaffold a SPEC.md
Add the marketplace, install sdd, and run /sdd:spec in any repo to scaffold the first SPEC.md.
/plugin marketplace add kborovik/spec-driven-dev
/plugin install sdd@spec-driven-dev
Then in any repo, /sdd:spec scaffolds the first SPEC.md.
SDD is adapted from JuliusBrussee/cavekit and ships under MIT.