The third time the agent proposed an architecture I had already rejected
The third time, I recognized the paragraph before I finished reading it. Mid-fix, an agent recommended reworking a storage decision settled weeks earlier. Same argument, same confidence, same trade-off table. The reasoning was fine. It was reasoning from zero, because nothing in its context said the debate had already happened.
The fix: goals, stories, and decisions as structured data the agent reads at every task start, plus automatic gap detection between spec and code. It is boring. That is the point.
One engineer, sixteen applications, teammates with no memory
I am one engineer. My monorepo spans, by the tooling's own count, 110 packages and 16 applications across 6 client workspaces — including a production real-estate platform for a client in Thailand. Coding agents (Claude Code) do most of the implementation, orchestrated through SBX, a Go framework I built for governed agentic development.
Every agent session starts stateless — no memory of past sessions, no colleague who remembers the meeting. Whatever the agent needs — the goal, the settled decisions, the rules — either arrives in its context at task start or it does not exist. Harsh, but clarifying.
The standard answers: bigger prompts, more memory, better tickets
A big instructions file. Claude Code reads a project CLAUDE.md file; you write your conventions there. It works for stable global rules — mine still carries the hard invariants.
Memory and retrieval. Persist notes between sessions, or point search at your docs folder. Recall beats re-explaining, and a searchable set of documents scales past one prompt.
Conventional project management. Tickets for scope, plus architecture decision records (ADRs — one short document per decision, with its reasons). Then hope the agent reads them. The instinct is right: Michael Nygard's ADR format has helped human teams avoid repeat debates since 2011.
I assumed the combination would be enough. It looked right because it is how you onboard a human contractor.
Where it broke: the agent reads everything and retains nothing
Each approach failed on a specific edge.
The instructions file failed by dilution. Every rule I added made every other rule weaker; past a certain size the model, in my experience, skims. One file cannot enforce deployment, styling, git discipline, and vocabulary mid-task, when the context is full of code. (The rules themselves: operating rules for running AI coding agents.)
Retrieval failed on staleness. A search over prose finds a deprecated design as easily as its replacement; nothing in a markdown file tells a ranking function "this was superseded." My agents did not hallucinate old designs — they faithfully retrieved them.
Tickets failed on why-not. A ticket records what to build, sometimes why. It never records the rejected alternatives and why each looked attractive. So an agent that hits friction does the honest thing: it re-derives the options and re-proposes the rejected one, because the rejection lived only in a conversation that no longer exists.
The repeat debate was not a memory failure but a traceability failure: the truth existed, but nothing connected it to the moment of decision. Prose loses its force when the reader is a stateless machine.
Spec-driven development: the spec is the source of truth
So I moved the truth out of prose into structured YAML (a plain-text format for structured data), with enforced lifecycles, wired into the task loop. This is spec-driven development in its plainest form: the spec is not documentation — it is the interface the agent works through. Four mechanisms.
Goals → stories → scenarios, declared, not narrated. Every task starts from a plan artifact the agent must read — roughly this shape:
goal: "Visitors self-serve answers before contacting an agent"
stories:
- id: faq-public
as: site visitor
want: browse answers by category
so_that: common questions never become support load
scenarios:
- story: faq-public
given: published entries exist
then: the public page renders them; the sitemap lists them
Implementation steps trace back to story IDs, and a trace command diffs the three layers: a story with no code is a gap; code serving no story is drift. Scope invention is caught mechanically. The gated task loop that walks this spec has its own post: the machine-checked SDLC for AI agents.
Decision records that preserve the wrong answer. I have 349 of them (tool-reported). The most valuable field is wrong_pattern — the rejected approach and why it seemed right:
question: "Where do per-request secrets resolve?"
recommendation: "At the adapter boundary, from env, injected at container start"
wrong_pattern: |
Persist resolved secrets in config storage.
Why it seemed right: one place to read, fewer moving parts.
Why it's wrong: config gets exported, cloned, diffed — secrets leak.
status: active # deprecation points to a successor; records are never deleted
The workflow requires a search over related records before it opens a new decision, so a returning debate surfaces its own history first.
Knowledge injected, not hoped for. 231 curated artifacts (52 rules, 143 guidelines, 36 smells, tool-reported) are injected at the step where they apply. The testing guideline arrives at the testing step, not hoped to be remembered from page 40 of a long file.
Memory hygiene. One rule lives in exactly one home. When a correction graduates into the canonical rule table, the old memory entry is deleted the same turn; stale entries are deleted on contact. Duplication breeds staleness.
The cost is real: SBX is roughly 270k lines of Go (tool-reported), built over months, and curation is ongoing manual work. I have no clean A/B test on "repeat debates prevented." What I can say honestly is qualitative: settled debates now come back as citations of the record, not as fresh proposals.
Where this applies: stateless workers against accumulated intent
One level up: any system where a worker with no durable memory makes decisions against accumulated intent.
- teams rotating contractors through a legacy codebase;
- platform teams whose runbooks are consumed by automation;
- multi-agent pipelines, where one agent's output is another agent's context.
The move is the same: stop writing intent as prose for a reader who retains; declare it as structure for a reader who does not.
For a weekend project or a short-lived prototype, a well-kept instructions file is enough. The governance layer pays off only when the codebase outlives many sessions.
Still ugly: I measured my own ceremony, and 82% of tasks were force-closed
My own process data (436 recorded task runs, tool-reported) showed planning steps with a median dwell under one minute, and 82% of tasks force-closed. My agents and I were approving my own gates without doing the work. The full data, and the redesign it forced, is in the machine-checked SDLC post. The fix: plans produced in discussion now auto-satisfy the planning gates instead of demanding repeat ceremony.
Still open: curation does not scale past one disciplined person yet, and the counts above are tool-reported, not independently audited. The trace command verifies structure, not intent — it cannot tell a well-traced bad idea from a good one. Next: specs that generate their own acceptance tests, closing the loop from story to proof.
Takeaways
- Write for the reader you actually have. My reader is stateless; prose onboarding assumes retention it does not have.
- Record why-not, not just why. The
wrong_patternfield kills repeat debates in a way plain decisions never did. - Inject knowledge at the moment of use. Rules delivered at the relevant step beat a long file the model skims.
- One rule, one home. Every duplicate is a future contradiction; delete stale entries the moment you touch them.
- Measure your own ceremony. Without the 82% force-close number I would still believe my gates were working.
Notes and references
SBX write-ups live at shredbx.com. None of this requires my tooling — the practices port to any stack.
- Anthropic — Claude Code: Best practices for agentic coding
- Anthropic — Effective context engineering for AI agents
- Michael Nygard — Documenting Architecture Decisions
- Architectural Decision Records — community formats