Why I Don't Persist Technical Specifications
In The Spec Is Permanent, the Plan Is Garbage, I introduced my core rule: keep a permanent Living Spec for customer-facing what and why, but discard implementation plans (how) the moment code lands.
Builders immediately asked the hard question:
That works for user-facing features. But what about massive technical refactors? When you rewrite infrastructure, change queue semantics, or rebuild service boundaries, where does the technical spec live?
The software industry’s default answer is a formal Technical Specification: a multi-page document detailing topologies, payloads, database schemas, and retry policies.
During the largest architectural overhaul in JupiterGoals’ history, I tested that assumption.
My conclusion? I wrote no technical spec. I kept no refactoring plan. I ban standalone technical specifications from the repository entirely.
Here is why standalone technical specs are an active liability, especially with autonomous AI agents, and where technical truth actually belongs.
The Real-World Test: A Major Refactor
Consider the largest refactor I just completed.
In How I Built a $0 AI-Powered SaaS: The 2026 Scale to Zero Blueprint, I broke down my bootstrap stack: a native Spring Boot backend communicating with Python inference workers over an Upstash Redis queue using list commands (BLMOVE / LMOVE):
While this kept idle costs low, pre-production stress tests exposed three critical flaws:
- The Idle Consumer Tax: Redis commands cost nothing while idle, but a consumer blocking on
BLMOVEmust run continuously. On Cloud Run (billed per request), an always-on worker eliminates the savings of scale-to-zero. - Transport Fragmentation: The boundary fractured across three separate transports: a synchronous reply key, an asynchronous HTTP callback, and a shared reply list.
- Lost Work Mid-Flight: Popping a job on pickup meant worker crashes or spot preemption lost paid customer generations with no recovery path.
I executed a ground-up overhaul to serverless, asynchronous HTTP tasks:
Recorded in an Architecture Decision Record (ADR), my new architecture anchors on five decisions:
- Push-based HTTP tasks: Cloud Tasks dispatches directly via HTTP POST, scaling containers from 0 to 1 on demand and idling to zero immediately.
- Idempotent settlement: The backend settles every generation exactly once (ready or refunded); a scheduled sweeper catches expired retries.
- Decoupled tiers: High-concurrency LLM text tasks are isolated from single-concurrency ffmpeg video renders.
- Zero-egress storage: Artifacts stream directly to Cloudflare R2 behind a CDN cache, eliminating cross-region egress fees.
- Provider-neutral core: Domain models run unchanged across clouds, isolated behind clean dispatch and authentication adapters.
By conventional standards, this overhaul was a prime candidate for a 30-page technical specification. Yet I persisted zero specs. Because what gets repeated is what goes stale.
The Core Law: What Gets Repeated Is What Goes Stale
In an engineering organization, documentation debt does not stem from a lack of discipline. It stems from duplication.
A functional Living Specification has a built-in survival mechanism: it anchors to a customer journey (such as asynchronous results delivery), a user who cares when it breaks, and acceptance criteria verified by automated tests.
A standalone technical specification has none of these protections. It is merely a derivative copy:
- Database columns copied from migrations.
- Endpoint signatures copied from API contracts.
- Architectural rationale copied from design discussions.
- Operational flags copied from environment files.
The moment code lands, drift begins. A migration adds two nullable columns that the tech spec omits. A retry backoff changes in code, leaving the document contradictory.
For a human engineer, doc rot is an annoyance: we learn to distrust stale wikis and inspect the code directly.
For an AI coding agent, doc rot is fatal. An autonomous agent lacks human skepticism. It accepts an outdated technical spec as ground truth, then confidently generates code against deprecated queues, deleted models, and nonexistent endpoints.
You cannot solve documentation rot by reminding humans or agents to keep wiki pages updated. The only structural solution is refusing to persist any technical document that lacks an automated gate keeping it true.
The 7 Homes of Technical Truth
Every piece of technical knowledge required to operate and refactor the platform already has an authoritative home. Crucially, each home is guarded by an automated gate that makes silent drift impossible:
| Kind of Technical Knowledge | Where It Already Lives | What Keeps It True |
|---|---|---|
| 1. Decisions and trade-offs | Architecture Decision Records (ADRs) | Automated CI consistency linter |
| 2. Architectural constraints | Agent Guidelines (AGENTS.md) | Pre-commit verification gates |
| 3. Payload shapes and endpoints | OpenAPI contracts | Generated code: drift breaks compilation |
| 4. Database schema and tables | Flyway migrations | Database engine validation on boot |
| 5. Customer invariants (refund on fail) | Living Spec Acceptance Criteria | Tests quoting criteria dynamically |
| 6. Configuration variables | .env.example | Strict startup validation at application boot |
| 7. Infrastructure topology | OpenTofu declarative modules | Executable infrastructure state |
When you map technical reality to these seven homes, a separate technical spec has nothing left to say.
Each home is self-policing:
- ADRs capture why: An ADR preserves the async migration trade-offs and latency calculations. A CI linter fails the build if any document cites an invalid or superseded ADR.
- Guidelines capture rules: Hard guardrails (like “never import a Redis client in the worker”) live in agent guidelines, enforced by pre-commit AST checks.
- Contracts capture APIs: Java and Python models generate directly from OpenAPI. If an endpoint payload drifts, compilation fails immediately.
- Flyway captures schema: Postgres validates migration checksums on boot; prose describing tables is instant debt.
- Living Specs capture promises: Business guarantees (such as refunding failed jobs) live in customer acceptance criteria, verified by automated tests quoting the specification text directly.
- Config captures environment: Application boot crashes if any required
.env.examplevariable is missing. - OpenTofu captures topology: Cloud Run, Cloud Tasks, and R2 buckets live in declarative files. The infrastructure is executable code.
Two Anti-Pattern Rules Enforced by Pre-Commit Gates
To ensure technical details remain in their proper homes, my pre-commit pipeline enforces two structural rules:
- “The schema is not the spec.” Living specifications describe customer experience, not database columns or endpoint signatures. Headings matching
Schema Implications,API & Database Details, orTechnical Specificationfail commit validation immediately:
$ git commit -m "feat: add worker retry semantics"
[FAIL] Living spec validation error:
Heading 'Database Schema & Tables' is banned.
The schema is not the spec. Put types in OpenAPI or Flyway.
- “Cite an ADR, never restate it.” When a spec or code comment requires architectural context, it references the ADR index in a single sentence. Duplicating rationale guarantees that one copy will eventually drift into a lie.
The Acid Test for Any Technical Document
Before I or any of my autonomous agents create a technical document, I apply one universal diagnostic:
The Acid Test: Would deleting this document let someone make a mistake that no contract, automated gate, test, ADR, or configuration validator would catch?
When I evaluated this serverless refactor against the test:
- Would deleting a tech spec let someone reintroduce a blocking queue? No. Pre-commit gates ban it.
- Would deleting it allow payload drift? No. Code generation breaks compilation.
- Would deleting it allow lost work without refunds? No. Acceptance criteria tests fail.
- Would deleting it erase why I chose Cloud Tasks over Redis? No. An Architecture Decision Record permanently preserves the rationale.
The answer was an unambiguous NO. A 30-page technical spec adds zero safety while introducing continuous maintenance drag.
What to Do When a Real Gap Appears
When I or an agent discover an uncaptured constraint, the temptation is to create a loose technical document.
Resist that urge. Route the knowledge into whichever home has the teeth to enforce it:
- Needs an agreed contract? Add it to OpenAPI.
- Needs data integrity? Add a database constraint in Flyway.
- Needs an architectural guardrail? Add a pre-commit verification gate.
- Needs a customer promise? Add an acceptance criterion to the Living Spec.
- Needs an architectural rationale? Record an ADR.
If a requirement does not fit into these seven homes, it is not an enduring rule. It is temporary scratchwork: execute it and delete it.
Summary: Blueprint for Builders
- Keep What and Why in Living Specs: Anchor them to customer value and automated acceptance tests.
- Treat Implementation Plans as Throwaway Scratchwork: Plan deeply in scratch files, build the code, and delete the plans when the change lands.
- Never Persist Standalone Technical Specs: Put technical truth where automated gates protect it: ADRs, agent guidelines, OpenAPI contracts, Flyway migrations, test-quoted acceptance criteria, startup configs, and OpenTofu modules.
- Apply the Acid Test: If deleting a document does not expose you to an uncaught failure, do not write it.
If your team or your AI agents keep getting misled by outdated architecture documentation, stop trying to write better technical specs.
Stop persisting them altogether.
Related Articles
The Spec Is Permanent, the Plan Is Garbage
How splitting the what from the how - and draining each plan back into the spec before deleting it - kept our specs true enough for AI agents to build from, and which automated gates actually hold the line.
Read article →Faster, Cheaper, and Totally Broken: Why We Abandoned Local AI
Our $0 local SLM stack beat cloud APIs on speed, but failed 68% of pre-launch tests. Here is why we pivoted to single-pass frontier models—and the 3-stage architecture lifecycle.
Read article →Achieve your goals without the burnout
Get early access to our dynamic re-routing habit system. Missed days trigger automatic recalibration instead of broken streaks.
Join the Waitlist (Free 8-Wk Beta Pass)