Write a Sprint Plan
The sprint plan (plan.yaml) is the only input you write for each sprint. PRIME reads it daily and generates a focused Story Card with acceptance criteria, scope boundaries, and context for FORGE. A well-written plan produces better code and fewer HOLD decisions.
File location
your-repo/└── .pace/ └── plan.yaml ← your sprint plan lives hereMinimal structure
sprint: goal: "Add JWT authentication to the API" duration_days: 5
days: - day: 1 theme: "User model and password hashing" stories: - title: "Secure user creation" acceptance_criteria: - "User.create() stores bcrypt-hashed password" - "User.verify_password() returns True for correct password" - "Tests cover both happy path and incorrect password" out_of_scope: - "OAuth / social login" - "Email verification"Full field reference
sprint: goal: string # One sentence describing what ships by day N duration_days: int # Must match sprint.duration_days in pace.config.yaml
days: - day: int # 1-indexed theme: string # One-line description of today's focus area notes: string # Optional free-text context for PRIME (architecture decisions, constraints) human_gate: bool # Optional — if true, PACE pauses after this day for human review stories: - title: string # Short imperative title ("Add login endpoint") acceptance_criteria: - string # Testable, concrete conditions. Start with a verb. out_of_scope: - string # Explicitly deferred items — GATE can PARTIAL against these notes: string # Optional per-story context for PRIMEWriting good acceptance criteria
Each criterion should be:
- Testable — GATE must be able to verify it with test output or CI results.
- Specific — name the function, endpoint, or behaviour, not a vague quality.
- Atomic — one condition per criterion.
Good examples
acceptance_criteria: - "POST /auth/login returns 200 + JWT for valid credentials" - "POST /auth/login returns 401 for invalid password" - "JWT expires in 24 hours (exp claim verified in tests)" - "pytest exits 0 with all auth tests passing"Weak examples (avoid)
acceptance_criteria: - "Authentication works" # Not testable - "Good test coverage" # Not specific - "Handles errors correctly" # VagueUsing out_of_scope
out_of_scope lets GATE issue a PARTIAL verdict rather than FAIL for known deferred items. Without it, GATE will FAIL any criterion it cannot verify.
stories: - title: "User login" acceptance_criteria: - "POST /auth/login returns JWT" - "CI pipeline is green" out_of_scope: - "CI pipeline — not yet configured in this sprint"Now if GATE cannot find a green CI run, it marks “CI pipeline” as PARTIAL (mapped to out_of_scope) instead of FAIL.
Multi-story days
A day can have multiple stories. PRIME will include all of them in the Story Card, and FORGE will implement them sequentially:
- day: 2 theme: "Login + logout endpoints" stories: - title: "POST /auth/login" acceptance_criteria: - "Returns 200 + token for valid credentials" - "Returns 401 for invalid credentials" - title: "POST /auth/logout" acceptance_criteria: - "Invalidates token server-side" - "Returns 204 on success"Using notes for architectural context
Add notes when FORGE needs to know about constraints that aren’t expressed in the acceptance criteria:
- day: 3 theme: "Refresh token rotation" notes: > We store refresh tokens in the database (not in-memory) because we need to support multi-device sessions. The RefreshToken model is already stubbed in src/models/refresh_token.py from Day 2. stories: - title: "POST /auth/refresh" acceptance_criteria: - "Issues new access token given valid refresh token" - "Rotates the refresh token (old token invalidated)"Clearance days
On days where human_gate: true or when the orchestrator is configured with advisory clearance days, GATE, SENTINEL, and CONDUIT receive the full advisory backlog and must resolve every open item:
- day: 5 theme: "Final review and advisory clearance" human_gate: true stories: - title: "Resolve all open advisories" acceptance_criteria: - "All SENTINEL advisories from Days 1-4 are explicitly resolved" - "All CONDUIT advisories from Days 1-4 are explicitly resolved"See Set Human Gate Days for more on human gates.
Example: 10-day sprint plan
sprint: goal: "Ship user authentication with JWT and refresh tokens" duration_days: 10
days: - day: 1 theme: "User model" stories: - title: "User creation with hashed passwords" acceptance_criteria: - "User.create() stores bcrypt-hashed password" - "User.verify_password() returns True/False correctly" - "Unit tests pass for both cases"
- day: 2 theme: "Login endpoint" stories: - title: "POST /auth/login" acceptance_criteria: - "Returns 200 + signed JWT for valid credentials" - "Returns 401 for invalid credentials" - "Token payload includes user_id and exp"
- day: 3 theme: "Advisory clearance" notes: "Review and close all advisories from Days 1-2" stories: - title: "Clear advisory backlog" acceptance_criteria: - "All SENTINEL and CONDUIT advisories from Days 1-2 resolved"
- day: 4 theme: "Protected routes" stories: - title: "JWT middleware" acceptance_criteria: - "Protected routes return 401 for missing/invalid token" - "Protected routes return 200 for valid token"
- day: 5 theme: "Refresh tokens" stories: - title: "POST /auth/refresh" acceptance_criteria: - "Issues new access token from valid refresh token" - "Rotates refresh token on each use" - "Returns 401 for expired or revoked refresh token"