Section-level spec maturity means tracking the state of each part of a document separately — stub, drafting, reviewed, locked — instead of assigning one status to the whole file. A checkout feature's auth section can be locked while its tax logic is still a stub, and building can start on the locked parts immediately.
Quick answer: Stop asking "is the spec done?" Ask "which sections are locked, which are still moving, and can engineering start on the locked ones today?" Maturity is a property of each section, not the document.
Why "Draft vs. Final" Is the Wrong Question
A spec is not one idea — it's a bundle of independent decisions bolted together under a single filename. Some of those decisions are settled on day one; others take weeks of back-and-forth with legal, finance, or a skeptical engineer. Forcing all of them under one status hides that reality.
Think about what actually happens when a senior PM writes a multi-week feature spec. The problem statement gets nailed down in the kickoff meeting. The primary user flow solidifies after a couple of design reviews. But the edge-case handling, the rollout plan, and anything touching a third-party dependency stay unsettled for much longer — sometimes until the week before launch.
A single "draft" or "final" label can't represent that. Two failure modes follow:
- Premature freeze — the team calls the whole doc "final" to unblock building, and the still-fuzzy rollout section quietly ships with untested assumptions baked in.
- Artificial bottleneck — the team refuses to call anything "final" until every section is settled, so engineers sit idle waiting on a tax-logic decision that has nothing to do with the auth work they could start today.
Both mistakes come from the same root cause: treating maturity as a document-level attribute when it's actually a section-level one. Our companion piece on why specs should behave like living documents makes the broader case for continuous evolution; this piece is about the specific mechanism — per-section status — that makes "living" operational instead of aspirational.
The Precedent Already Exists Outside Product
This isn't a novel idea invented for specs. Several disciplines already reject whole-document status in favor of per-unit status:
- Architecture Decision Records (ADRs), the format Michael Nygard popularized in 2011, assign each individual decision its own status field —
proposed,accepted,deprecated, orsuperseded— rather than stamping an entire architecture doc as "approved." - The IETF's RFC process has long used graduated maturity levels for specifications (Internet-Draft, Proposed Standard, Internet Standard) instead of a binary draft/final flag, precisely because different parts of a network protocol stabilize at different rates.
- Basecamp's Shape Up methodology, documented by Ryan Singer, tracks work with "hill charts" that plot each scope of work separately as either still uphill (figuring out the unknowns) or downhill (known execution) — never a single readiness state for the whole project.
Specs deserve the same treatment. A PRD is a collection of scopes, not a monolith.
What Section-Level Status Actually Looks Like
A workable status model needs four states, each with a clear owner and a clear unlock condition: stub, drafting, reviewed, and locked. The point isn't the exact labels — it's that every section carries its own value, and engineering can act on locked sections independently of what's happening elsewhere in the document.
Here's a status model that maps cleanly onto how a spec actually gets built:
| Status | What it means | Who can change it | Can engineering build against it? |
|---|---|---|---|
stub | Placeholder only — a heading and a one-line intent, no real content | Any contributor, any time | No |
drafting | Actively being written; open questions still outnumber answered ones | Section owner | No — informational only |
reviewed | Content is complete and has survived at least one structured critique | Section owner + at least one reviewer | Cautiously — for spikes or prototypes, not committed builds |
locked | Decision is final; changing it now requires a formal re-open, not a quiet edit | Section owner + accountable approver (e.g., eng lead, legal) | Yes — full commitment |
Two design choices matter here. First, locked is not "no changes ever" — it's "changes now cost more," because someone downstream has already started building against it. That asymmetry is exactly what a mid-flight status change should carry, the same way a merged pull request can still be reverted but the bar for doing so is higher than for an open branch.
Second, notice that reviewed is not the same as locked. A lot of teams collapse these into one state and pay for it later — a section gets a thumbs-up in a meeting, everyone treats it as settled, and then it turns out "reviewed" only meant "nobody objected in a 20-minute skim." Separating them forces an explicit second gate: has this actually been stress-tested, or just seen?
That second gate is where structured critique earns its keep. Before a section moves from reviewed to locked, it should survive a round of adversarial thinking — someone deliberately trying to break the assumption, not just nodding along. A section that's only ever been agreed with, never argued against, is not actually locked-ready no matter what the status field says.
Worked Example: A Checkout Feature With Uneven Maturity
Take a real multi-week feature: redesigning checkout for a subscription product. Six weeks in, the sections of that spec are nowhere near the same maturity — and that unevenness is normal, not a warning sign, provided the status field reflects it honestly.
Here's a realistic snapshot at week three of a six-week checkout build:
| Section | Status | Why it's there | Blocking engineering? |
|---|---|---|---|
| Auth & session handling | locked | Reuses an existing, already-audited auth flow; no new decisions needed | No — building since week 1 |
| Primary payment flow (card, wallet) | locked | Payment provider API is fixed, UX tested in two rounds of usability sessions | No — building since week 2 |
| Cart & pricing display | reviewed | Content is complete; one adversarial pass done, second scheduled | Prototype only |
| Tax logic (multi-region) | stub | Waiting on finance to confirm which jurisdictions launch in v1 | Yes, but isolated to tax module |
| Failed-payment retry policy | drafting | Two competing proposals (retry count vs. grace period) still being argued | Yes, but isolated to retry module |
| Post-purchase rollout plan | stub | Deliberately deferred — no one needs it until week 5 | No, not needed yet |
Look at what this table makes possible. Engineering has been building against auth and the primary payment flow since week one or two, even though a third of the document is still a stub. Nobody is waiting on finance's tax jurisdiction call to ship a login screen.
Compare that to the alternative: a single "Checkout Spec v0.3 — DRAFT" header. Under that model, either the team refuses to start building until finance decides on tax jurisdictions (artificial bottleneck), or someone declares the whole thing "final enough" and the retry-policy argument gets steamrolled by a launch date (premature freeze). Section-level status routes around both traps by making the actual, uneven state of knowledge visible instead of averaging it into one number.
There's a subtlety worth naming: the sections blocking engineering aren't blocking the same engineers. Tax logic and retry policy are isolated modules. A team that maps dependencies at the section level — not just at the document level — can tell a specific engineer "you're clear to build the retry module, just not against a locked tax number yet," which is a much more useful instruction than "the spec isn't done."
Why Tax Logic Stays a Stub Longer Than You'd Like
It's tempting to push finance for an early answer just so the section can move off stub. Resist that — a stub that honestly says "we don't know yet" is more useful than a drafting section full of assumptions.
Before committing engineering time to a specific tax implementation, it's worth running the harder question first: is multi-region tax logic even feasible to ship correctly in this timeframe, given jurisdiction-specific rules and rate changes? That's the kind of question a structured feasibility check is built to surface before a section graduates past stub — because a premature drafting status on a genuinely unfeasible plan wastes more time than an honest, longer-lived stub.
How Section Status Changes the Way Teams Actually Work
Per-section maturity isn't just a labeling convenience — it changes three concrete things: what engineering is allowed to start, what a review meeting is actually for, and how changes get proposed once a section is locked. Each of those changes independently, without touching the other two.
- It unblocks work instead of gating it. A locked section is a green light for a specific team, not a claim about the whole feature — multi-week features stop being all-or-nothing bets on one "spec sign-off" date.
- It turns review meetings into targeted conversations. Instead of a 90-minute walkthrough of an entire document, a review can be scoped to "we're moving the retry-policy section from
draftingtoreviewed— here's the decision and its two alternatives." - It makes re-opening a locked section a visible, deliberate act. Changing something in a
lockedsection should look and feel different from editing astub— closer to proposing a change to merged code than editing a shared doc.
That third point deserves its own emphasis: reviewing a change to a locked section works best when it's shown as an explicit diff against what was agreed, not a silent rewrite. That's the same discipline behind PR-style diffs for spec reviews, borrowed directly from how engineering teams already review code.
A fourth effect matters specifically for AI-assisted features. Once a section touching model behavior is locked, any claim about how well it performs needs a bar more rigorous than a demo. That's the role structured evals play — they give a locked AI-behavior section something concrete to clear, instead of treating "it worked in my test" as equivalent to "it's ready."
A Numbered Checklist for Moving a Section to locked
Use this as a gate, not a formality:
- Content is complete — no open bullet points, no "TBD," no bracketed placeholders.
- At least one adversarial pass is done — someone actively tried to find the failure mode, not just read it approvingly.
- Dependencies are named — if this section assumes something from another section, that dependency is written down, not implied.
- The accountable approver has signed off — not "the room seemed fine with it," an actual named person.
- Downstream teams know it's safe to build against — locking a section nobody told engineering about isn't locking, it's just writing.
Skip any one of these and you get a section that says locked but behaves like reviewed — which is worse than an honest reviewed label, because it invites people to build on a foundation that isn't actually settled.
Making Section Maturity Stick: Process, Ownership, and Tooling
Section-level status only works if it's visible where the team already looks — not buried in a separate tracker nobody opens. It also needs a single owner per section and a lightweight ritual for updating status, or it decays into the same stale "DRAFT" header it was meant to replace.
A few practices make this durable rather than performative:
- Assign a named owner per section, not per document. The person accountable for tax logic maturing is rarely the same person accountable for the auth flow, and pretending one PM owns "the spec's maturity" hides that.
- Timestamp status changes. A section that's said
draftingfor five weeks without movement is a signal worth surfacing in standup, the same way a stale pull request gets flagged. - Keep the context each section depends on attached to it, not scattered across Slack threads. A locked decision is only as trustworthy as the reasoning behind it — losing that context is how "why did we decide this?" turns into a re-litigated argument three weeks later. This is the same discipline context engineering applies to keeping the right information attached to the right decision, instead of relying on someone's memory of a meeting.
- Review the whole board periodically, not just individual sections. Once a month (or at each milestone), look at the status distribution across the doc — if everything is stuck at
drafting, that's a different problem than one stubbornstub.
Locked sections show up as readiness gates the rest of the team can act on. Proposed edits to a locked section are surfaced as a diff against what was agreed, in the same PR-style review flow described above — so re-opening a decision is a visible, deliberate step rather than a quiet overwrite.
Key Takeaways
- Maturity is a section-level property, not a document-level one — a spec's problem statement can be
lockedwhile its rollout plan is still astub, and that's normal for a multi-week feature. - A four-state model —
stub,drafting,reviewed,locked— gives engineering a clear, section-by-section signal for what's safe to build against right now. reviewedandlockedare not the same thing. Keep them separate, and require an adversarial pass before a section graduates from one to the other.- The worked checkout example shows the payoff directly: auth and payment can be
lockedand under active development while tax logic sits atstubwaiting on a finance decision — with zero engineering time lost on either side. - Re-opening a
lockedsection should look like proposing a diff, not silently rewriting a shared doc — borrow the code-review discipline your engineers already trust. - Precedent for this pattern already exists outside product management: ADRs, the IETF's RFC maturity levels, and Basecamp's hill charts all reject single-status documents in favor of per-unit maturity.
- Tools matter less than the habit — but purpose-built tracking, like Prodinja's Spec Studio, makes per-section status visible without a separate tracker nobody maintains.
Frequently Asked Questions
What's the difference between a "draft" spec and section-level maturity tracking?
A "draft" spec applies one status to the entire document, hiding the fact that some decisions are settled and others aren't. Section-level maturity tracks each part — problem statement, user flow, edge cases, rollout — with its own status, so mature sections can move to building while immature ones stay visibly open.
How many maturity states should a spec section have?
Four works well for most teams: stub (placeholder only), drafting (actively being written), reviewed (complete and critiqued at least once), and locked (final, changes require a formal re-open). Fewer than four tends to collapse "reviewed" and "locked" into one state, which is where premature confidence creeps in.
Can engineering start building before the whole spec is finished?
Yes — that's the entire point of section-level status. If the auth and payment sections are locked, engineering can build against them regardless of whether the tax-logic or rollout sections are still stub, as long as dependencies between sections are explicitly named.
Who should own the status of a spec section?
Assign one named owner per section, not one owner for the whole document. The person accountable for tax logic maturing is often different from whoever owns the primary user flow, and a single "spec owner" title tends to obscure who's actually responsible for unblocking a stuck section.
What should happen when someone wants to change a "locked" section?
Treat it like proposing a change to merged code, not editing a shared doc: the change should be shown as an explicit diff against the locked version, reviewed by the original accountable approver, and only then re-locked. A quiet overwrite of a locked section defeats the purpose of locking it in the first place.