Feature plan
Produce a work plan and stub implementations from the brief and domain analysisFrom its SKILL.md
npx -y skills add telefrek/vallorcine --skill feature-planAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
35.3 KB, ~8.2k tokens by cl100k_base, as published. Nobody here has run it
/feature-plan "<feature-slug>"
Reads the brief, domain analysis, and governing ADRs to produce a work plan and stub implementations. Idempotent β if planning is complete, reports and stops.
Idempotency pre-flight (ALWAYS FIRST)
Read .feature/<slug>/status.md.
If Planning stage is complete:
Check status.md for substage escalated-to-work-planner. Also check
cycle-log.md for a recent test-to-planner-escalation entry.
If an escalation is pending: proceed to the Contract Revision section below instead of stopping.
Otherwise:
ποΈ WORK PLANNER Β· <slug>
βββββββββββββββββββββββββββββββββββββββββββββββ
Work planning is already complete for '<slug>'.
Work plan: .feature/<slug>/work-plan.md
Use AskUserQuestion with options:
- "Proceed to test writing"
- "Stop"
If "Proceed to test writing": invoke /feature-test "<slug>" as a sub-agent immediately.
If "Stop": display
Next: /feature-test "<slug>"and stop.
If Planning stage is in-progress:
Display opening header, then:
- Say: "Planning was in progress β resuming."
- If substage is
writing-stubsor later:- Read work-plan.md if it exists (may be partial or absent β the subagent may have been interrupted)
- Check which stub files from the design already exist vs. are missing
- If all stubs present AND work-plan.md exists AND status is
complete: jump to Step 4 (hand off) - Otherwise: re-launch the Step 3 subagent. Pass the full construct list but note which stubs already exist so the subagent skips them (idempotent). The subagent will write missing stubs AND write/rewrite work-plan.md.
- If substage is before
writing-stubs(e.g.loading-context,surveying-codebase,confirmed-design): resume from the appropriate earlier step (re-run design confirmation if needed, then proceed to Step 3 subagent)
If Planning stage is not-started:
- Verify
.feature/<slug>/domains.mdexists. If not: "Run /feature-domains first." - Check for spec infrastructure (
test -f .spec/CLAUDE.md || test -d .spec/registry). If spec infrastructure exists, check whether the Spec Authoring stage in status.md iscomplete. If Spec Authoring isnot-startedorin-progress, warn: "Spec infrastructure exists but specs haven't been authored for this feature." Use AskUserQuestion with options:- "Run /spec-author first" (description: stop and let user run spec-author)
- "Skip specs" (description: plan from brief and domains only) If "Skip specs": proceed normally (specs will be absent from context). If "Run /spec-author first": stop and let the user run spec-author.
- Set status.md: Planning β
in-progress, substage βloading-context - Display opening header and proceed to Step 1
Display opening header:
βββββββββββββββββββββββββββββββββββββββββββββββ
ποΈ WORK PLANNER Β· <slug>
βββββββββββββββββββββββββββββββββββββββββββββββ
Step 0a β Progress tracking
Use TodoWrite to show progress in the Claude Code UI (visible via Ctrl+T). Each TodoWrite call replaces the full list β always include all items.
Pipeline context: Include the full feature lifecycle as top-level items so
the user sees where this stage fits in the overall flow. Mark earlier stages as
completed, the current stage as in_progress, and later stages as pending.
Stage-level detail: Within the current stage, add granular items for each
piece of work. Use activeForm on in-progress items to show real-time detail
(e.g., "Reading domains.md β checking ADR links").
Example checklist at the start of planning:
[
{"id": "pipeline-scoping", "content": "Scoping", "status": "completed", "priority": "medium"},
{"id": "pipeline-domains", "content": "Domain analysis", "status": "completed", "priority": "medium"},
{"id": "pipeline-planning", "content": "Work planning", "status": "in_progress", "priority": "high",
"activeForm": "Loading context files"},
{"id": "pipeline-testing", "content": "Test writing", "status": "pending", "priority": "medium"},
{"id": "pipeline-implementation", "content": "Implementation", "status": "pending", "priority": "medium"},
{"id": "pipeline-refactor", "content": "Refactor & review", "status": "pending", "priority": "medium"},
{"id": "pipeline-pr", "content": "PR draft", "status": "pending", "priority": "medium"},
{"id": "load-context", "content": "Load context and survey codebase", "status": "in_progress", "priority": "medium"},
{"id": "design", "content": "Design confirmation", "status": "pending", "priority": "high"},
{"id": "work-units", "content": "Work unit analysis", "status": "pending", "priority": "medium"},
{"id": "stubs", "content": "Write stubs and work plan", "status": "pending", "priority": "high"},
{"id": "handoff", "content": "Hand off to test writing", "status": "pending", "priority": "medium"}
]
As the stage progresses, update both the stage-level items AND the pipeline
item's activeForm to reflect current work.
Step 0b β Pipeline mode detection
Read Pipeline mode from status.md (default: full).
If pipeline_mode: implementation:
- This feature skipped scoping and domains β specification artifacts were produced in a prior phase.
brief.mdwas generated by/work-startor/work-planfrom the work definition.domains.mdmay not exist β that's fine. The planner reads specs and ADRs directly instead of relying on domain analysis output.- Skip steps that reference domains.md if it doesn't exist.
Step 1 β Load context
Read in order:
-
.feature/project-config.md -
PROJECT-CONTEXT.mdβ if it exists, read Active entries (global + scoped to relevant modules). Constraints from context entries should be reflected in work plan contracts. -
Work group context β if
.work/exists, run:bash .claude/scripts/work-context.sh --feature "<slug>"If output is non-empty, read it and apply:
- Interface stability: When a construct's public API is produced by this feature and other WDs in the same work group consume it, add an interface stability constraint to the contract: "Public API consumed by WD-03, WD-05 β signature changes require coordinated updates."
- Planned work awareness: When other WDs will modify the same codebase areas, note it in implementation notes: "WD-04 also plans changes in this module β consider extension points."
- Do not restructure the work plan around work group concerns β just add awareness to contracts and implementation notes where relevant.
-
.feature/<slug>/brief.md -
.feature/<slug>/domains.md -
All ADR files linked in domains.md
-
Key sections of linked KB subject files (
#key-parameters,#implementation-notes) -
Resolve specs β check for spec infrastructure first:
test -f .spec/CLAUDE.md || test -d .spec/registryIf spec infrastructure exists, run the resolver and persist the bundle to
.feature/<slug>/spec-bundle.mdso downstream stages (test, implement, refactor 4a) can re-read the same artifact instead of re-resolving:bash .claude/scripts/spec-resolve.sh "<feature description>" 25000 \ > .feature/<slug>/spec-bundle.mdThen initialize the spec coverage table so every loaded requirement becomes an explicit obligation that test/implementation must annotate:
bash .claude/scripts/spec-coverage.sh init \ .feature/<slug>/spec-coverage.md \ .feature/<slug>/spec-bundle.mdinitis idempotent β re-running on an existing coverage file preserves any annotations or waivers already recorded by earlier substages.If the resolver returns specs, these are the primary context for work planning β alongside the brief and domains, specs are the authoritative source for behavioral requirements. The three documents serve different roles:
- Brief β describes why we're building and the user's intent
- Domains β describes what constraints exist (ADRs, KB, gaps)
- Specs β describes what must be true (behavioral requirements)
When specs exist, contracts in the work plan MUST trace to spec requirements. The brief and domains provide context and constraints; the spec provides the requirements that contracts must deliver.
If the brief contradicts a spec requirement, flag the contradiction for the user β the spec takes precedence unless the user explicitly overrides.
If spec infrastructure does not exist, or the resolver returns no specs for this feature's domains, proceed as before β derive contracts from the brief and ADRs. In this case, also write a vacuous coverage marker so the gate at
/feature-prknows there are no spec obligations to enforce:mkdir -p .feature/<slug> printf '# Spec Coverage\n\nNo specs loaded for this feature. Coverage gate is satisfied vacuously.\n' \ > .feature/<slug>/spec-coverage.mdConflict gate: After loading the resolved bundle, check if it contains a
## Conflictssection. If it does:Display:
β οΈ Spec conflicts detected in resolved bundle: <list each CONFLICT and INVALIDATES line from the section> These must be resolved before planning can proceed.Use AskUserQuestion with options:
- "Resolve via /spec-author"
- "Override and continue"
If "Resolve via /spec-author": stop and let them resolve. If "Override and continue": proceed with planning, but record the conflicts in work-plan.md under a
## Open Riskssection:## Open Risks - Spec conflict override: <each conflict line>These are carried forward as open risks in the work plan.
Displacement gate: After the conflict gate, check if the bundle contains a
## Displacement Resolutionsection. If it does:Parse the resolution table. For each row with Decision = "Accept":
Display:
π Displacement accepted β removal work required: <existing_spec_id>.<req_id> will be invalidated by this feature. <Show the existing requirement text>These accepted displacements become removal work units in the work plan. For each one, identify the construct(s) in the existing codebase that implement the displaced behavior β these are the constructs to remove.
Add a
## Removal Worksection to the work plan (see Step 2).For rows with Decision = "Defer": record in
## Open Risks:- Deferred displacement: <new_id> vs <existing_id>.<req_id> β unresolved -
Read project coding conventions:
CONTRIBUTING.md,.claude/rules/, and any language-specific style guides. These constrain the design space for construct shapes.
Scan the source directory structure (names and module layout only β don't read every file). Read only files likely relevant to this feature.
Update status.md substage β surveying-codebase.
Step 2 β Map requirements to constructs
If specs were resolved in Step 1: translate each spec requirement into the construct(s) that will deliver it. The spec describes behavioral contracts (what must be true); the work planner designs the implementation structure (which constructs deliver those behaviors). Every spec requirement must map to at least one construct. If a requirement can't be mapped, add a construct or extend an existing one β do not present a gap to the user.
If no specs exist: derive contracts from the brief and ADRs as before.
If displacement was accepted in Step 1: for each accepted displacement, derive a removal contract. Read the existing codebase to identify which construct(s) implement the displaced behavior. For each:
- Add a removal entry to the
## Removal Worksection of the work plan:## Removal Work | ID | Displaced Spec | Requirement | Construct | Action | |------|----------------|-------------|-----------|--------| | RW-1 | <existing_id> | <req_id> | <construct name> | Remove | - The removal contract is: "Remove behavior described by <existing_id>.<req_id>. Assert the behavior no longer exists."
- Removal work units appear in the Implementation Order alongside addition work units. They are sequenced after the addition work that replaces the displaced behavior (remove old after new is proven working).
Self-check (before presenting to the user)
After generating the construct catalogue, verify the design before presenting:
-
Coverage: Every spec requirement must map to at least one contract. If any requirement has no contract, add a construct or extend an existing one to cover it.
-
Agent success shaping: For each contract, ask "how will the implementing agent misunderstand this?" If a contract is ambiguous or the construct boundaries make it easy to implement correctly-but-wrong, reshape the constructs. Split a large construct into two with clearer contracts. Merge two constructs that are too tightly coupled to implement independently. Respect the project's coding conventions β don't reshape into patterns that violate established architecture.
-
Dependency completeness: For each construct, verify it has access to all inputs its contract needs. If a dependency is missing from the graph, add it β don't flag it.
-
Shared state identification: For each pair of constructs, check whether their contracts reference shared mutable state or produce/consume the same data. Record these edges β they determine clustering in Step 2b.
Present the design
Produce a catalogue and display:
ββ Design ββββββββββββββββββββββββββββββββββββββ
Spec requirements mapped: <N>/<total>
Existing constructs to USE or EXTEND:
β <Name> at <src/path> β delivers: <spec requirement IDs>
New constructs to CREATE:
+ <Name> β <purpose> β <src/path> β delivers: <spec requirement IDs>
depends on: <list>
shares state with: <list or "none">
Use AskUserQuestion with options:
- "Approve" (description: design looks correct, proceed)
- "Needs changes" (description: user will describe corrections)
If "Approve": proceed. User corrections are not needed. If "Needs changes": ask the user what to change. User corrections become additional constraints on the design β the work planner respects them while maintaining coverage of all spec requirements.
Update status.md substage β confirmed-design after confirmation.
Step 2b β Work unit analysis
After design is confirmed, cluster constructs into work units using the construct graph from Step 2.
Clustering rules
Work units are determined by construct relationships, not just token cost. The construct graph has three edge types (identified in Step 2's self-check):
- depends_on β construct A calls or imports construct B's interface
- shares_state β constructs A and B read/write the same mutable resource
- produces/consumes β construct A's output is construct B's input
Clustering constraints:
- Constructs connected by
shares_stateedges must be in the same work unit. They cannot be parallel β their TDD pass must see both constructs. - Constructs connected by
produces/consumesshould be in the same work unit when possible. If split, the consuming unit must include the producing construct as visible context. - Constructs connected only by
depends_oncan be in separate work units. The dependent unit loads the dependency's public interface, not its internals.
Token estimation
For each new construct estimate:
- Stub file: ~1K tokens
- Test file: ~2K tokens
- Work-plan contract section: ~0.5K tokens
Single-unit total load (what the Code Writer loads in one session):
N constructs Γ 3.5K = estimated Code Writer session size
Split-unit total load (per unit session):
(constructs in unit Γ 3.5K) + context from prior units + 0.5K status overhead
Decision rules
| Constructs | Shared state? | Recommendation |
|---|---|---|
| 1β3 | any | Never split β overhead exceeds savings |
| 4β5 | all share state | Single unit β can't split shared state |
| 4β5 | clean groups | Propose split β marginal but clean |
| 6+ | all share state | Single unit β but flag size for user awareness |
| 6+ | clean groups | Split β savings are real |
Work unit ordering
Units are ordered by dependency. When a later unit depends on an earlier
unit's constructs (via shares_state or produces/consumes), those
constructs are included as visible context in the later unit's TDD pass.
The work plan must state this explicitly:
WU-2 context includes: <construct A from WU-1> (shares state with <construct C>)
This ensures the TDD agent has visibility into all constructs it needs.
Natural split signals (lower the threshold)
- Two constructs have zero intra-feature dependencies β free split
- Constructs span different source modules or packages β natural seam
- One construct group is a pure data/type layer (no logic) β always a good WU-1
Override rules (never split regardless of size)
- Feature has a single acceptance criterion that requires all constructs together
- User explicitly said "implement as single unit" during scoping
- All constructs share mutable state (no clean boundary exists)
Display the analysis
Always show the analysis, even when recommending no split:
ββ Work unit analysis ββββββββββββββββββββββββββββββ
Constructs: <n> new | Estimated single-unit load: ~<N>K
<If not splitting:>
Recommendation: single unit
Reason: <"only <n> constructs β split overhead not worth it" |
"no clean dependency boundary" |
"all constructs are tightly coupled">
Proceeding as single unit.
<If proposing split:>
Recommendation: split into <n> work units
Estimated savings: ~<N>K per session vs ~<N>K single unit
WU-1: <name> (<n> constructs, no intra-feature deps)
Constructs: <list>
Est. session load: ~<N>K
WU-2: <name> (depends on WU-1)
Constructs: <list>
Dependency interface loaded: <WU-1 public API> ~0.5K
Est. session load: ~<N>K
WU-3: <name> (depends on WU-1 + WU-2) [if applicable]
...
Execution strategy prompt
After the work unit analysis display, determine the execution strategy.
If feature doesn't qualify for splitting (1β3 constructs, no boundaries):
set execution_strategy: cost implicitly in status.md, skip the prompt.
If feature qualifies for splitting, show the analysis then ask:
Use AskUserQuestion with options:
- "Cost" (description: sequential execution β splits only when a single session exceeds ~15K tokens)
- "Balanced" (description: split at clean boundaries, independent units run in parallel in batches β moderate token overhead)
- "Speed" (description: split at every clean boundary, maximum parallelism β fastest wall-clock time, highest token cost)
Record execution_strategy: <choice> in status.md and in the
<!-- execution_strategy: --> comment under ## Work Units.
Strategy behaviour:
cost: use current split thresholds (>15K). If under threshold,work_units: none. If over, split but units run sequentially. No per-unit dirs.balanced: lower threshold to >8K OR 2+ independent groups. Split and create per-unit dirs (see below).speed: split at every clean boundary (still never split 1β3 total constructs). Create per-unit dirs.
If "cost" and under threshold: record work_units: none in status.md, proceed to Step 3.
If "cost" and over threshold: proceed with unit structure (sequential execution).
If "balanced" or "speed": proceed with unit structure and parallel setup.
Dependency graph (balanced/speed only)
After the Work Units table is confirmed, compute the dependency graph and critical path. Display:
ββ Dependency graph βββββββββββββββββββββββββββ
WU-1 βββ
βββ WU-3
WU-2 βββ
Critical path: WU-1 β WU-3 (2 sequential stages)
Max parallelism: 2 units simultaneously
Speed mode: units launch on dependency resolution, no batch waits
Balanced mode: Batch 1 {WU-1, WU-2} β Batch 2 {WU-3}
The critical path is the longest chain of dependent units β it determines the minimum wall-clock time regardless of how much parallelism is available. Display it so the user can see the theoretical minimum and compare against batch mode.
Per-unit directory creation (balanced/speed only)
Create .feature/<slug>/units/WU-N/ for each unit with:
Per-unit status.md:
---
feature: "<slug>"
unit: "WU-<n>"
unit_name: "<name>"
---
## Current Position
**Stage:** not-started
**Substage:** β
**Last successful checkpoint:** unit directory created
**Cycle:** 0
## TDD Cycle Tracker
| Cycle | Tests written | Tests passing | Refactor done | Missing tests |
Per-unit cycle-log.md:
# Cycle Log β <slug> / WU-<n>
<!-- Append-only. Each agent appends entries. -->
---
Write Work Units table
After confirmation, write the Work Units table to status.md:
## Work Units
| Unit | Name | Constructs | Depends On | Status | Cycle |
|------|------|------------|------------|--------|-------|
| WU-1 | <name> | <list> | β | not-started | β |
| WU-2 | <name> | <list> | WU-1 | blocked | β |
Units with unmet dependencies start as blocked. The first unit with no
dependencies starts as not-started (ready to begin).
Step 3 β Write stubs and work plan (subagent)
Delegate stub creation and work-plan assembly to a subagent to keep file I/O out of the main conversation context. The subagent runs autonomously β no user interaction is needed for the mechanical writing phase.
Launch a subagent with the following prompt, substituting the confirmed design data from Step 2:
**Subagent contract:** Honor `rules/completeness-contract.md` (load-bearing β
no silent deferrals; trigger phrases = escalation signals, not completion
modes). If you cannot complete assigned scope, escalate via AskUserQuestion
with user-validatable proof. A return claiming COMPLETE alongside deferred
items is a contract violation.
You are a Work Planner Agent completing the mechanical writing phase for
feature "<slug>".
## Your task
Write stub files and work-plan.md based on the confirmed design below, then
update status and cycle-log.
## Confirmed design
Feature slug: <slug>
Language: <language from project-config.md>
Existing constructs:
<paste the "Existing constructs to USE or EXTEND" list from Step 2>
New constructs:
<paste the "New constructs to CREATE" list from Step 2, including paths,
signatures, dependencies, and governing ADR references>
Work units: <"none" or paste the work unit assignments from Step 2b>
## Step A β Write stubs
Update `.feature/<slug>/status.md` substage β `writing-stubs`.
For each new or extended construct, write the stub. Check whether the file
already exists first β if it does and contains a stub for this construct,
skip it (idempotent). Only write missing stubs.
Every stub must have:
- Correct signature with types (where the language supports them)
- Docstring/comment block: what it receives, returns, side effects, governing ADR
- NotImplementedError or language equivalent for unimplemented body
**Python:**
```python
def function_name(param: Type) -> ReturnType:
"""
Contract: <what this does>
Params: param β <description>
Returns: <description>
Side effects: <or "none">
Governed by: <ADR path or KB section>
"""
raise NotImplementedError
```
**TypeScript:**
```typescript
function functionName(param: Type): ReturnType {
// Contract: <what this does>
// Governed by: <ADR path>
throw new Error("Not implemented");
}
```
**Go:**
```go
// FunctionName does <what>. Governed by: <ADR path>
func FunctionName(param Type) (ReturnType, error) {
return nil, errors.New("not implemented")
}
```
## Step B β Write work-plan.md
Write `.feature/<slug>/work-plan.md` using the Work Plan Template from
the feature-plan command. Include all sections: References, Existing Constructs,
New Constructs, Stub Files Written, Contract Definitions, Work Units (if any),
and Implementation Order.
## Step C β Update status and log
Update status.md: Planning β `complete`, last checkpoint β "work-plan.md written,
<n> stubs created".
Update the Stage Completion table: Planning row β Est. Tokens `~<N>K` (sum of files
loaded: brief ~2K + domains ~3K + ADRs + source scan).
Append `planned` entry to cycle-log.md:
```markdown
## <YYYY-MM-DD> β planned
**Agent:** ποΈ Work Planner
**Summary:** <n> new constructs, <n> extensions. Stubs written.
**Files read:** brief ~2K, domains ~3K, <ADR files>, <source files scanned>
**Token estimate:** ~<N>K
---
```
Update `.feature/CLAUDE.md`.
## Step D β Return summary
Return a structured summary:
```
Stubs written: <list of file paths>
Stubs skipped (already existed): <list or "none">
Work plan: .feature/<slug>/work-plan.md
Constructs: <n> new, <n> extensions
```
Wait for the subagent to return. Use the returned summary for the handoff display in Step 4.
Step 4 β Hand off
Use the subagent's returned summary (stubs written, stubs skipped, construct counts) for the display below. Do not re-read stub files β the subagent already confirmed them.
Display:
βββββββββββββββββββββββββββββββββββββββββββββββ
ποΈ WORK PLANNER complete Β· <slug>
Tokens : <TOKEN_USAGE>
βββββββββββββββββββββββββββββββββββββββββββββββ
Work plan: .feature/<slug>/work-plan.md
Stubs written: <list from subagent summary>
Review the stub contracts in work-plan.md β the Test Writer works from these
contracts and changing them later requires re-running tests.
Step 4a β Choose automation mode
Ask the user how they want to run the TDD loop. This choice is recorded now and persists for the lifetime of this feature β it will not be asked again.
When execution_strategy is balanced or speed:
Use AskUserQuestion with options:
- "Auto" (description: independent units run their full test/implement/refactor cycles in parallel β checkpoints happen at batch boundaries)
- "Manual" (description: pause between batches and wait for go-ahead)
When execution_strategy is cost (or not set):
Use AskUserQuestion with options:
- "Auto" (description: cycles run without stopping, pauses only if input needed)
- "Manual" (description: stop after each stage and wait for command)
Wait for input:
- "auto" (or "autonomous"): set
automation_mode: autonomousin status.md - "manual": set
automation_mode: manualin status.md
If auto, display:
Running autonomously. Type stop at any time to pause.
ββββββββββββββββββββββββββββββββββββββββββββββββββ
If manual, display:
Manual mode. I'll prompt you at each stage boundary.
ββββββββββββββββββββββββββββββββββββββββββββββββββ
Step 4b β Start test writing or coordinator
First β check for nested-dispatch context. Read status.md. If it
contains nested_in_dispatch: true (set by /work-start --nested
when this feature was dispatched as part of /work-start all,
/work-start --parallel, or /work-run), force
execution_strategy: cost regardless of any prior setting. The
dispatched sub-agent context cannot dispatch nested Agent tool
calls, so /feature-coordinate's parallel batching would fail at
runtime. The orchestrator already provides parallelism at the WD
level β sequential work-unit execution inside each WD is correct.
If nested_in_dispatch is true AND the existing execution_strategy
in status.md is balanced or speed, overwrite it to cost and
append a brief note to cycle-log.md:
- <iso-now> execution-strategy-forced β was: <prior>, now: cost (nested_in_dispatch)
Then fall through to the cost branch below.
If execution_strategy is balanced or speed (and
nested_in_dispatch is NOT true):
βββββββββββββββββββββββββββββββββββββββββββββββ
Launching parallel coordinator.
Run /feature-resume "<slug>" at any point to see batch status.
βββββββββββββββββββββββββββββββββββββββββββββββ
Invoke /feature-coordinate "<slug>" as a sub-agent immediately.
If execution_strategy is cost (or not set, or forced from
nested_in_dispatch):
If work units are defined:
βββββββββββββββββββββββββββββββββββββββββββββββ
Start with the first unit:
/feature-test "<slug>" --unit WU-1
Each unit runs its own test β implement β refactor cycle.
Run /feature-resume "<slug>" at any point to see which unit is next.
βββββββββββββββββββββββββββββββββββββββββββββββ
Invoke /feature-test "<slug>" --unit WU-1 as a sub-agent immediately.
If single unit (no work units):
Invoke /feature-test "<slug>" as a sub-agent immediately.
If the user types stop before test writing begins:
When you're ready:
/feature-test "<slug>"
Contract Revision (escalation entry point)
Entered when status.md substage is escalated-to-work-planner and cycle-log.md
contains a test-to-planner-escalation entry.
Step R1 β Load the escalation
Read the most recent test-to-planner-escalation entry from cycle-log.md. Extract:
- The contract/construct name
- The work plan section reference
- The conflict description
- The brief acceptance criterion that contradicts the contract
- The escalation count (N of 3)
Read the relevant contract section from work-plan.md, the referenced acceptance criterion from brief.md, and any governing ADRs linked in the contract.
Step R2 β Diagnose and revise
Determine the root cause. If specs exist for this feature, the spec is the tiebreaker. Check the contract against the spec requirement it claims to deliver β if the contract matches the spec, the escalation is wrong. If the contract deviates from the spec, the contract is wrong.
-
Contract contradicts spec β the contract does not satisfy the spec requirement it maps to. Revise the contract to deliver the spec requirement.
-
Contract contradicts brief β the work plan constraint does not satisfy the acceptance criterion. Check whether the brief or the spec is authoritative. If the spec exists and covers this behavior, align with the spec. If no spec exists, revise the contract to match the brief.
-
Contract contradicts ADR β the constraint conflicts with a governing architecture decision. Revise the contract to align with the ADR.
-
Contract is internally inconsistent β the signature, return type, or error conditions conflict with each other. Fix the inconsistency.
-
Brief is ambiguous β the acceptance criterion can be read multiple ways, and the contract chose the wrong reading. Revise the contract to match the intended reading. If the intended reading is unclear, ask the user.
For each case, make the minimal change to the contract that resolves the conflict. Do NOT rewrite unrelated contracts.
Update the contract section in work-plan.md:
- Revise the Contract Definition for the affected construct
- Update the stub signature if it changed
- Add a revision note:
<!-- Revised <YYYY-MM-DD>: <one-line reason> -->
If the stub signature changed, update the stub file to match. Preserve any implementation code the Code Writer has already written β change only the signature and contract docstring/comment.
Step R3 β Log and hand off
Append contract-revised to cycle-log.md:
## <YYYY-MM-DD> β contract-revised
**Agent:** ποΈ Work Planner
**Contract:** <construct name>
**Change:** <what was wrong β what it is now>
**Root cause:** <contradicts brief | contradicts ADR | internally inconsistent | brief ambiguous>
**Escalation count:** <N> of 3
---
Update status.md substage β contract-revised.
Display:
ποΈ WORK PLANNER Β· contract revision Β· <slug>
βββββββββββββββββββββββββββββββββββββββββββββββ
Revised: <construct name>
Root cause: <one sentence>
Change: <what changed in the contract>
Contract updated β resuming test β implement cycle.
Invoke /feature-test "<slug>"< --unit WU-<n>> as a sub-agent immediately.
Do not wait for user input β the contract is revised and the cycle can resume.
Work Plan Template
---
feature: "<slug>"
created: "<YYYY-MM-DD>"
language: "<language>"
---
# Work Plan β <slug>
## References
- Brief: [brief.md](brief.md)
- Domains: [domains.md](domains.md)
- Governing ADRs: <links>
- Specs: <spec IDs and paths from .spec/, or "none β contracts derived from brief">
## Existing Constructs
| Construct | File | Usage |
|-----------|------|-------|
| <n> | <path> | use / extend β <one line> |
## New Constructs
| Construct | File | Contract summary |
|-----------|------|-----------------|
| <n> | <path> | <one line> |
## Stub Files Written
| File | Status |
|------|--------|
| <path> | stubbed |
## Requirement Traceability
<!-- Every spec requirement must map to at least one contract. -->
| Spec Requirement | Contract(s) | Work Unit |
|-----------------|-------------|-----------|
| <F01.R1> | <ConstructName> | WU-1 |
## Contract Definitions
### <ConstructName>
**File:** `<path>`
**Delivers:** <spec requirement IDs, e.g. F01.R5, F01.R6>
**Governed by:** [<ADR or KB>](<link>)
**Signature:** `<stub signature>`
**Contract:**
- Receives: <params>
- Returns: <return>
- Side effects: <or "none">
- Error conditions: <what is raised/returned on failure>
- Shared state: <what mutable resources this construct accesses, or "none">
---
## Work Units
<!-- Omit this section if work_units: none in status.md -->
### WU-1: <name>
**Constructs:** <list>
**Depends on:** none
**Context from prior units:** none
**Est. session load:** ~<N>K
### WU-2: <name>
**Constructs:** <list>
**Depends on:** WU-1 public interface
**Context from prior units:** <constructs from WU-1 visible in this unit's TDD pass, with reason (shares state / produces-consumes)>
**Est. session load:** ~<N>K
## Implementation Order
<!-- Single-unit features: list constructs in dependency order -->
<!-- Multi-unit features: list units, then constructs within each unit -->
1. <construct or WU-N> β no dependencies
2. <construct or WU-N> β depends on: <1>
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.