Appearance
A Plan is a phased, file-manifested spec — the artifact whose exactness determines whether the builder produces the right code or a plausible hallucination.
Primitive
Plan
The whole game
Prose descriptions vs exact interfaces.
Prose spec
"Add session token validation"
Add a function that validates session
tokens. Return null if invalid.
Ambiguous. What's the signature? Which file? What type is the token? The builder fills gaps with guesses. Every gap is a potential mismatch against the next agent's expectations.
Exact-interface spec
Interface, path, behavior
export async functionvalidateSessionToken(
token: string
): Promise<SessionClaims | null>
Unambiguous. Builder knows exactly what to produce; validator knows exactly what to check; next agent knows exactly what to call. Zero interpretation gap.
This is why a Plan is the prompt. The plan's exactness becomes the agent's scope.
The spec file
Eight required sections. Skip none.
specs/issue-47-adw-cc73faf1-oauth2-provider.md
01
What We're Building
One paragraph. Outcome, not steps. The user-visible thing that changes.
02
Constraints
Hard rules — API contracts, perf budgets, compliance. What must NOT change.
03
File Manifest
Table of every file touched. Operation (CREATE / MODIFY / DELETE), symbols added or removed. The Stop hook checks this against disk.
04
Phases + Exact Changes
Each phase is a dependency-ordered group of tasks. Each task has a code block with the exact interface signature — not prose.
05
Acceptance Criteria
Checkboxes. Observable, binary. Either passes or doesn't. No subjective criteria.
06
Verification
Commands to run. Expected output. How the validator knows the build is done.
07
Integration Points
Where this touches other systems. Which callers change. Which downstream consumers need updating.
08
Out of Scope + Open Questions
What's explicitly NOT in this plan. Questions the planner couldn't resolve — flagged for humans to decide.
The contract at the core
File Manifest → Stop hook → disk verification.
File ManifestStop hook reads this at completion
create
src/auth/oauth2.ts
+OAuth2Provider, +validateToken
modify
src/auth/middleware.ts
+useOAuth2−legacyAuth
delete
src/legacy/token-util.ts
—
At Stop, the hook walks this manifest and checks disk state. Declared file not touched → block; undeclared file touched → block. Phantom edits become impossible.
What a phase looks like
Each task carries its own exact interface.
## Phase 1 — Auth Schema
Task 1.1 — SessionClaims type
export interface SessionClaims {
sub: string;
exp: number;
scopes: string[];
}
✓ Acceptance: TypeScript compiles without errors
✓ Verification: bunx tsc --noEmit passes
Task 1.2 — validateSessionToken function
export async function validateSessionToken(
token: string
): Promise<SessionClaims | null>
✓ Acceptance: returns null for expired tokens
✓ Verification: test auth.spec.ts::expired passes
The builder reads the plan and sees "this exact signature, here" — not "add auth handling." The plan is the prompt.
The discipline
The plan's exactness IS the agent's scope.
Ambiguous plan → ambiguous build. Prose description → hallucinated signature. The plan you couldn't hand to a stranger is a plan the agent will interpret — and interpretation is where bugs are born. Spend planning time to buy building time.