Plans
Plans define what should be built. Anvil validates how it's being built against that definition.
What is a Plan?
A plan is an APS (Anvil Plan Specification) document that describes:
- Modules — cohesive units of functionality
- Tasks — authorised work with validation criteria
- Steps — observable checkpoints within tasks
┌─────────────────────────────────────────┐
│ Index │
│ (Project-level, lists all modules) │
└───────────────────┬─────────────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐
│Module │ │Module │ │Module │
│ A │ │ B │ │ C │
└───┬───┘ └───┬───┘ └───┬───┘
│ │ │
┌───▼───┐ ┌───▼───┐ ┌───▼───┐
│Tasks │ │Tasks │ │Tasks │
└───────┘ └───────┘ └───────┘
Why Plans Matter
Determinism
Plans are hash-stable. Given the same plan, Anvil produces the same validation. This enables:
- Reproducible builds — same inputs, same outputs
- Audit trails — prove what was validated
- Caching — skip unchanged validations
Intent Declaration
Plans capture intent before execution. The AI (or developer) works within the plan's boundaries:
## Task: AUTH-001 — Implement login endpoint
Outcome: Users can authenticate with email/password
Validation: `pnpm test src/auth/login.test.ts`
The plan doesn't say how to implement login—that's up to the executor. It says what success looks like.
Bounded Context
Each module is a bounded context. Anvil can enforce that changes stay within their module's boundaries:
Module: auth
Files: src/auth/**
Module: payments
Files: src/payments/**
A task in auth modifying files in payments triggers a boundary warning.
Plan Structure
Index (index.aps.md)
The root document:
---
format: aps
version: 1.0
hash: sha256:abc123...
---
# Project Plan
## Modules
- [auth](modules/auth.aps.md)
- [payments](modules/payments.aps.md)
- [notifications](modules/notifications.aps.md)
Module (modules/auth.aps.md)
A cohesive feature area:
---
format: aps
module: auth
---
# Auth Module
## Tasks
### AUTH-001 — Login endpoint
### AUTH-002 — Registration endpoint
### AUTH-003 — Password reset
Task
A unit of authorised work:
### AUTH-001 — Login endpoint
**Outcome:** Users authenticate with email and password, receiving a JWT.
**Validation:** `pnpm test src/auth/login.test.ts`
**Steps:**
1. [ ] Endpoint accepts POST /auth/login
2. [ ] Invalid credentials return 401
3. [ ] Valid credentials return JWT
4. [ ] JWT contains user ID and expiry
Plans in Anvil
Validation Against Plans
When Anvil runs, it can validate that changes align with an active plan:
anvil run --plan plans/index.aps.md
Anvil checks:
- Are the modified files within an active task's scope?
- Does the change align with the task's stated outcome?
- Are steps being completed in order?
Plan-less Mode
Anvil works without plans too. In this mode, it only runs gate checks (architecture, anti-patterns, etc.) without plan validation.
Creating Plans
Plans can be created:
- Manually — write APS markdown
- Via CLI —
anvil plan create - From external formats — Anvil adapters convert SpecKit, BMAD, etc.
Learn more: APS Specification →