| name | oat-project-plan |
| version | 1.3.5 |
| description | Use when design.md is complete and executable implementation tasks are needed. Breaks design into bite-sized TDD tasks in canonical plan.md format. |
| disable-model-invocation | true |
| user-invocable | true |
| allowed-tools | Read, Write, Bash(git:*), Glob, Grep, AskUserQuestion |
Planning Phase
Transform detailed design into an executable implementation plan with bite-sized tasks.
Prerequisites
This skill is the plan authoring path for spec-driven projects only. Quick and import modes have dedicated entry skills that produce plan.md directly.
Read oat_workflow_mode from {PROJECT_PATH}/state.md (default: spec-driven):
spec-driven: Complete design document required (design.md with oat_status: complete). If missing, run the oat-project-design skill first. Proceed with planning.
quick: Stop. Plan is already produced by the quick workflow. Tell the user: "Plan already produced by quick workflow. Run oat-project-implement to begin execution."
import: Stop. If a normalized plan.md exists, tell the user: "Imported plan is ready. Run oat-project-implement to begin execution." If no plan.md exists, tell the user: "Run oat-project-import-plan to import and normalize the external plan first."
Plan Format Contract
When creating or editing plan.md, follow oat-project-plan-writing canonical format rules. This includes stable task IDs (pNN-tNN), required sections (## Reviews, ## Implementation Complete, ## References), required frontmatter keys (oat_plan_source, oat_status, oat_ready_for), and review table preservation rules. oat_plan_hill_phases remains optional until oat-project-implement confirms the checkpoint selection.
Mode Assertion
OAT MODE: Planning
Purpose: Break design into executable tasks with exact files, signatures/test cases, and commands. Spec-driven only — quick and import modes stop-and-route.
Progress Indicators (User-Facing)
When executing this skill, provide lightweight progress feedback so the user can tell what’s happening after they confirm.
-
Print a phase banner once at start using horizontal separators, e.g.:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
OAT ▸ PLAN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-
Before multi-step work (drafting/finalizing/reviewing/committing), print 2–5 short step indicators, e.g.:
[1/5] Reading design + context…
[2/5] Drafting phases + tasks…
[3/5] Finalizing plan + rollups…
[4/5] Running plan artifact review…
[5/5] Updating state + committing…
-
For any operation that may take noticeable time (e.g., reading large artifacts), print a start line and a completion line (duration optional).
-
Keep it concise; don’t print a line for every shell command.
BLOCKED Activities:
- No implementation code
- No changing design decisions
- No scope expansion
ALLOWED Activities:
- Breaking design into phases
- Creating bite-sized tasks (2-5 minutes each)
- Specifying exact files and interface signatures
- Defining test cases and verification commands
- Planning test-first approach
Self-Correction Protocol:
If you catch yourself:
- Writing actual implementation → STOP
- Changing architecture decisions → STOP (send back to design)
- Adding new features → STOP (flag for next cycle)
- Needing implementation details that aren't covered by the design → STOP (ask the user whether to update the design, then re-run the
oat-project-plan skill)
Recovery:
- Acknowledge the deviation
- Return to planning language ("Task N will...")
- Keep implementation details at pseudocode/interface level
- Keep code blocks short (signatures/outlines only)
Process
Step 0: Resolve Active Project
OAT stores active project context in .oat/config.local.json (activeProject, local-only).
PROJECT_PATH=$(oat config get activeProject 2>/dev/null || true)
PROJECTS_ROOT="${OAT_PROJECTS_ROOT:-$(oat config get projects.root 2>/dev/null || echo ".oat/projects/shared")}"
PROJECTS_ROOT="${PROJECTS_ROOT%/}"
If PROJECT_PATH is missing/invalid:
If PROJECT_PATH is valid: derive {project-name} as the directory name (basename of the path).
Step 1: Determine Workflow Mode and Route
WORKFLOW_MODE=$(oat project status --field project.workflowMode 2>/dev/null || echo null)
Mode: quick — STOP. Print:
⚠️ This project uses quick mode. Plan is produced by the quick workflow.
Run the `oat-project-implement` skill to begin execution.
Exit skill.
Mode: import — STOP. Check if "$PROJECT_PATH/plan.md" exists:
- If yes: Print: "Imported plan is ready. Run
oat-project-implement to begin execution."
- If no: Print: "Run
oat-project-import-plan to import and normalize the external plan first."
Exit skill.
Mode: spec-driven — Continue to Step 2.
Step 2: Check Design Complete
cat "$PROJECT_PATH/design.md" | head -10 | grep "oat_status:"
Required frontmatter: oat_status: complete, oat_ready_for: oat-project-plan.
If not complete: Block and ask user to finish design first.
Step 3: Read Design Document
Read "$PROJECT_PATH/design.md" completely to understand:
- Architecture overview and components
- Data models and schemas
- API designs and interfaces
- Implementation phases from design
- Testing strategy
- Security and performance considerations
Step 4: Read Knowledge Base for Context
Read for implementation context:
.oat/repo/knowledge/conventions.md - Code patterns to follow
.oat/repo/knowledge/testing.md - Testing patterns
.oat/repo/knowledge/stack.md - Available tools and dependencies
Step 5: Initialize Plan Document
Check whether a plan already exists at "$PROJECT_PATH/plan.md".
If "$PROJECT_PATH/plan.md" exists:
- Read it first (treat it as a draft).
- Ask the user:
- Resume (default): continue editing the existing plan in place
- View: show the existing plan and stop
- Overwrite: replace with a fresh copy of the template (warn about losing draft edits)
- If resuming: ensure the document contains the required sections from the template (at minimum:
## Reviews, ## Implementation Complete, ## References). If any are missing, add them using the template headings (do not delete existing content).
If "$PROJECT_PATH/plan.md" does not exist:
- Copy template:
.oat/templates/plan.md → "$PROJECT_PATH/plan.md"
Update frontmatter:
---
oat_status: in_progress
oat_ready_for: null
oat_blockers: []
oat_last_updated: { today }
oat_phase: plan
oat_phase_status: in_progress
oat_generated: false
oat_template: false
---
Step 6: Define Phases
Break design implementation phases into plan phases.
Phase structure:
- Each phase delivers a complete, testable milestone
- Phases should be 1-3 days of work
- Later phases can depend on earlier phases
- End each phase with verification
Step 7: Break Into Tasks
For each phase, create bite-sized tasks.
Task characteristics:
- 2-5 minutes to complete
- Single responsibility
- Clear verification
- Atomic commit
No implementation code (important):
- Prefer pseudocode, interfaces, and bullet steps over full implementations.
- If the task is a shell script, include function names + responsibilities and only minimal “shape” snippets (aim for <10 lines per code block).
- If a longer snippet would be useful, replace internals with
{...} placeholders and document behavior/edge cases in prose.
Task IDs: Use stable IDs in format p{phase}-t{task} (e.g., p01-t03).
Task template:
### Task p{NN}-t{NN}: {Task Name}
**Files:**
- Create: `{path/to/new.ts}`
- Modify: `{path/to/existing.ts}`
**Step 1: Write test (RED)**
{Test code or test case description}
**Step 2: Implement (GREEN)**
{Interface signatures or implementation outline}
**Step 3: Refactor**
{Optional cleanup}
**Step 4: Verify**
Run: `{command}`
Expected: {output}
**Step 5: Commit**
```bash
git add {files}
git commit -m "feat(p{NN}-t{NN}): {description}"
```
### Step 8: Apply TDD Discipline
For each task that involves code:
1. **Test first:** Write test before implementation
2. **Red:** Verify test fails
3. **Green:** Implement minimal code to pass
4. **Refactor:** Clean up while tests pass
**Task order for features:**
1. Write test file
2. Run tests (red)
3. Write implementation
4. Run tests (green)
5. Commit
### Step 9: Specify Exact Details
For each task, include:
- **Files:** Exact paths for create/modify/delete
- **Signatures:** Interface definitions, function signatures, type declarations
- **Test cases:** Test file paths and test descriptions (pseudocode OK for test bodies)
- **Commands:** Exact verification commands that match the claimed scope. If the task says "run this file" or "run this test target," use the real runner invocation that actually scopes to that target rather than a shortcut that may execute the full package suite.
- **Commit:** Conventional commit message with task ID (e.g., `feat(p01-t03): ...`)
**Avoid:**
- Vague instructions ("update the file")
- Missing verification steps
- Verification shortcuts that claim file-scoped coverage but actually run a broader suite
- Bundled unrelated changes
- Full implementation code (leave that for oat-project-implement)
### Step 10: Update Requirement Index
Go back to spec.md and fill in the "Planned Tasks" column in the Requirement Index:
For each requirement (FR/NFR):
- List the stable task IDs that implement it
- Example: "p01-t03, p02-t01, p02-t05"
This creates traceability: Requirement → Tasks → Implementation
### Step 10.1: Keep Reviews Table Rows
Follow the review table preservation rules from `oat-project-plan-writing`:
- Include both **code** rows (p01/p02/…/final) and **artifact** rows (`spec`, `design`, `plan`)
- Add additional rows as needed (e.g., p03), but never delete existing rows
**Why stable IDs:** Using `p01-t03` instead of "Task 3" prevents broken references when tasks are inserted or reordered.
### Step 11: Defer Plan Phase Checkpoints To Implementation Start
Do **not** ask the user to choose HiLL checkpoints during planning.
Unless the source artifact or user already supplied a confirmed `oat_plan_hill_phases` value that should be preserved, leave `oat_plan_hill_phases` unset in `plan.md` during planning. `oat-project-implement` will confirm the checkpoint choice at implementation start and write the chosen value before task execution begins.
**Required plan body update (do not skip):**
- In `## Planning Checklist`, mark:
- `[x] Defer HiLL checkpoint confirmation to oat-project-implement`
- If a legacy checklist item such as `Confirmed HiLL checkpoints with user` exists, replace it with:
- `[x] Defer HiLL checkpoint confirmation to oat-project-implement`
If `## Planning Checklist` is missing (older plans), add it before finalizing with the items above.
### Step 11.5: Resolve Dispatch Ceiling Before Implementation Readiness
Before marking the plan ready for implementation, resolve the dispatch ceiling.
Resolution order:
1. Config keys `workflow.dispatchCeiling.providers.<provider>` via the resolver CLI
2. Project `state.md` frontmatter key `oat_dispatch_ceiling`
3. Interactive planning prompt (below)
4. Leave unresolved for implementation preflight when non-interactive
If no ceiling resolves and the session is interactive, present the preset
prompt once before final plan review:
```text
Set the dispatch ceiling — the maximum subagent tier OAT may use.
1. Balanced (recommended) — Codex: high · Claude: sonnet
2. Maximum — Codex: xhigh · Claude: opus (reviews always run at this tier)
3. Cost-conscious — Codex: medium · Claude: sonnet
4. Advanced — set per provider
5. No ceiling
OAT applies this where the provider exposes a reliable mechanism (Codex: pinned
variants; Claude: Task model parameter). Other providers may treat it as advisory.
```
**Preset selection** persists `preset` + compiled per-provider values. On
selection, print the exact compiled result (e.g., "Ceiling set: balanced →
Codex: high · Claude: sonnet") before proceeding.
**Advanced (option 4)** prompts for each provider's value individually, then
persists `providers` + `source` only — no `preset` key.
**No ceiling (option 5)** leaves `oat_dispatch_ceiling` unset; implementer
subagents run at provider defaults.
Persist the answer in `"$PROJECT_PATH/state.md"` frontmatter using the
normalized shape:
```yaml
oat_dispatch_ceiling:
preset: balanced # omit when Advanced was chosen
providers:
codex: high
claude: sonnet
source: project-state
```
Do not prompt when `OAT_NON_INTERACTIVE=1` or when no user-response channel
exists. In that case, leave the value unresolved. `oat-project-implement`
must block before work starts if it still cannot resolve a ceiling.
Do not treat provider default effort as the OAT dispatch ceiling. Provider
default is informational for base/unpinned roles only.
### Step 12: Review Plan with User
Present plan summary:
- Number of phases
- Tasks per phase
- Key milestones
Also note that `oat-project-implement` will confirm the actual HiLL checkpoint selection at execution start and then write `oat_plan_hill_phases` into `plan.md`.
Ask: "Does this breakdown make sense? Any tasks missing?"
Iterate until user confirms.
### Step 12.5: Run Plan Artifact Review Loop
Invoke the shared `Auto Artifact-Review Loop` from `oat-project-plan-writing` with target `plan` before setting `plan.md` to implementation-ready.
Required payload:
- `target: plan`
- `type: artifact`
- `scope: plan`
- `artifact_path: "$PROJECT_PATH/plan.md"`
- `oat_output_mode: structured`
Apply the shared loop exactly:
- Resolve `workflow.autoArtifactReview.plan`; only an explicit `false` skips the loop.
- Resolve `oat_orchestration_retry_limit` from project state, defaulting to `2`.
- Dispatch `oat-reviewer` in structured mode using Tier 1 subagent when available and Tier 2 inline fallback otherwise.
- Apply Critical and Important artifact-local fixes when unambiguous; offer Medium and Minor fixes instead of silently applying them.
- Re-dispatch after rewrites until clean or the retry bound is exhausted.
- Update the `plan` artifact row in the `## Reviews` table to `passed` when clean. If residual findings remain, preserve the row and surface the residual findings before downstream handoff.
### Step 13: Mark Plan Complete
Before setting `oat_status: complete`, verify:
- `## Planning Checklist` exists
- the checklist records that checkpoint confirmation is deferred to implementation
- if `oat_plan_hill_phases` is already present, it is intentionally preserved and valid
- the `plan` artifact review row has been recorded by Step 12.5, unless `workflow.autoArtifactReview.plan` was explicitly disabled
Update frontmatter:
```yaml
---
oat_status: complete
oat_ready_for: oat-project-implement
oat_blockers: []
oat_last_updated: {today}
---
Step 14.5: Propose Parallel Groups (Optional)
After all phases are drafted, evaluate whether any phases have non-overlapping file boundaries:
-
For each pair of adjacent phases in the plan, check the Files: section of all tasks in each phase.
-
If no file appears in both phases' task files sections, they are candidates for a parallel group.
-
Propose to the user:
I noticed phases p02 and p03 have disjoint file boundaries (no overlap).
Declare them as a parallel group? This lets oat-project-implement run them
concurrently in worktrees, cutting wall-clock time.
-
If the user confirms, update oat_plan_parallel_groups in the plan frontmatter.
-
If no phases are obviously independent, skip this step silently — do not invent parallelism.
Never silently infer parallelism without explicit user confirmation.
Step 14: Update Project State
Update "$PROJECT_PATH/state.md":
Frontmatter updates:
oat_current_task: null
oat_last_commit: {commit_sha_from_step_15}
oat_blockers: []
oat_phase: plan
oat_phase_status: complete
oat_project_state_updated: "{ISO 8601 UTC timestamp}"
- If
"plan" is in oat_hill_checkpoints: append "plan" to oat_hill_completed array
Note: Only append to oat_hill_completed when the phase is configured as a HiLL gate.
Update content:
## Current Phase
Planning - Ready for implementation
## Progress
- ✓ Discovery complete
- ✓ Specification complete
- ✓ Design complete
- ✓ Plan complete
- ⧗ Awaiting implementation
Step 15: Commit Plan
git add "$PROJECT_PATH/"
git commit -m "docs: complete implementation plan for {project-name}
Phases:
- Phase 1: {description} ({N} tasks)
- Phase 2: {description} ({N} tasks)
Total: {N} tasks
Ready for implementation"
Step 16: Output Summary
Planning phase complete for {project-name}.
Phases:
- Phase 1: {description} ({N} tasks)
- Phase 2: {description} ({N} tasks)
Total: {N} tasks
Next: Run oat-project-implement to begin execution.
Success Criteria
- All design components covered by tasks
- Tasks are bite-sized (2-5 minutes)
- TDD discipline applied to code tasks
- Each task has clear verification
- Requirement Index updated with task mappings
- User confirmed plan is complete