324 lines
14 KiB
Markdown
324 lines
14 KiB
Markdown
<!--
|
||
Optional YAML frontmatter — include ONLY when the plan was generated from a
|
||
`type: trekreview` input (Handover 6). Lists the 40-char hex IDs of the
|
||
BLOCKER + MAJOR findings consumed from `review.md`. Use block-style YAML;
|
||
the frontmatter parser does not support flow-style arrays.
|
||
|
||
Plans generated from a `type: brief` input omit this block entirely. No
|
||
plan_version bump — the field is additive and backwards compatible.
|
||
|
||
---
|
||
source_findings:
|
||
- 0123456789abcdef0123456789abcdef01234567
|
||
- fedcba9876543210fedcba9876543210fedcba98
|
||
---
|
||
-->
|
||
|
||
# {Task Title}
|
||
|
||
> **Plan quality: {grade}** ({score}/100) — {APPROVE | APPROVE_WITH_NOTES | REVISE | REPLAN}
|
||
>
|
||
> Generated by trekplan v{version} on {YYYY-MM-DD} — `plan_version: 1.9` · `ceremony: {small | bounded | architectural}`
|
||
|
||
## Context
|
||
|
||
Why this change is needed. The problem or need it addresses, what prompted it,
|
||
and the intended outcome. Reference the spec file if one was used.
|
||
|
||
## Global Constraints
|
||
|
||
The brief's Constraints and Non-Functional Requirements that bind more than one
|
||
step, **quoted verbatim** — exact values, never paraphrased. A step that could
|
||
break one quotes it again in its `Review focus:`.
|
||
|
||
- > "{constraint, verbatim from the brief}" — brief § Constraints
|
||
|
||
<!-- ceremony: architectural (or absent) → insert the design part here, from
|
||
templates/design-template.md (## Design). small | bounded → omit it. -->
|
||
|
||
## Architecture Diagram
|
||
|
||
```mermaid
|
||
graph TD
|
||
subgraph "Changes in this plan"
|
||
%% C4-style component diagram showing what the plan touches
|
||
%% Highlight modified components, new components, and connections
|
||
end
|
||
```
|
||
|
||
*Replace with actual Mermaid diagram showing the components this plan modifies,
|
||
their relationships, and the data flow between them.*
|
||
|
||
## Codebase Analysis
|
||
|
||
- **Tech stack:** {languages, frameworks, build tools}
|
||
- **Key patterns:** {architecture patterns, conventions observed}
|
||
- **Relevant files:** {paths to files that will be read or modified}
|
||
- **Reusable code:** {existing functions, utilities, abstractions to leverage}
|
||
- **External tech (researched):** {technologies that were looked up via research-scout}
|
||
- **Recent git activity:** {relevant recent commits, active branches, code ownership}
|
||
|
||
## Research Sources
|
||
|
||
*Omit this section when no external research was conducted.*
|
||
|
||
| Technology | Source | Key Findings | Confidence |
|
||
|-----------|--------|--------------|------------|
|
||
| {name} | {URL} | {summary} | {high/med/low} |
|
||
|
||
## Implementation Plan
|
||
|
||
Each step targets 1–2 files and one focused change, and is a vertical slice:
|
||
a narrow but complete path through every layer it touches, verifiable on its
|
||
own. Preparatory refactoring comes first, as its own steps. Every step has
|
||
`Test first:` (plan_version 1.8 or later requires it), and one step runs the thing
|
||
end to end (`End-to-end:`). The test for a behaviour belongs in the step that
|
||
builds it: a step of only tests for behaviour an earlier step delivered passes
|
||
at its start point and can never be proven red (the validator warns:
|
||
`PLAN_STEP_TESTS_ONLY`). So `End-to-end:` rides on the last step that builds
|
||
behaviour, with its script in that step's `Files:`, not on a step of its own.
|
||
|
||
Optional per-step fields: `Interface in:` (what the step consumes, and which
|
||
earlier step or existing code produces it), `Interface out:` (what it produces
|
||
for later steps), `Review focus:` (inputs the brief implies but no test
|
||
exercises yet, each pinned to a test; and any Global Constraint the step could
|
||
break, quoted verbatim), and `Regression:` (ONE backticked command the criteria
|
||
runner allows, no pipe and no `&&` — usually `npm test` — that the executor
|
||
runs green before the checkpoint, on a step that can break existing tests;
|
||
`Verify:` stays the step's own red-first test). A field that is present is
|
||
never empty. `On failure:` opens with `revert`, `retry`, `skip` or `escalate`,
|
||
then the specifics.
|
||
|
||
From plan_version 1.9 the rule is the file first on every line: each `Files:`
|
||
entry and each `Test first:` `File:` line opens with its backticked path(s),
|
||
separated only by commas or spaces, and everything after the first other text
|
||
is description that is never read. A 1.9 step always names a file
|
||
(the bare word none or an empty `Files:` is refused). A line that is no list item
|
||
continues the entry above it (a list wrapped after a comma keeps its paths;
|
||
once the entry so far does not end with a comma, the wrapped line is description;
|
||
a `File:` line with nothing after it takes its first wrapped line),
|
||
the `File:` line may open with `1.` or `1)` and any list item ends it, and
|
||
a backticked placeholder (`TBD`, `TODO`, `TBA`, `N/A`, `NA`, `none`, `...`) or a
|
||
mixed-case bare name (`Parser`) is no path, so write `./Name` for such a file. In `Files:`,
|
||
every path stands before any annotation: `` `src/a.mjs`, `src/b.mjs` (new) ``,
|
||
never `` `src/a.mjs` (new), `src/b.mjs` `` (in 1.9 that second path is
|
||
description).
|
||
Several test files share one `File:` line the same way:
|
||
`` File: `a.test.mjs`, `b.test.mjs` *(new)* ``.
|
||
|
||
### Step 1: {description}
|
||
|
||
- **Files:** `path/to/file.ts`
|
||
- **Changes:** {exactly what to modify — no placeholders, no "update as needed"}
|
||
- **Reuses:** {existing function/pattern from codebase, with file path}
|
||
- **Interface out:** `{name(args) → result}` — read by Step 2
|
||
- **Review focus:** {untested input the brief implies} — pinned by `path/to/test.ts`
|
||
- **Test first:**
|
||
- File: `path/to/test.ts` *(existing | new)*
|
||
- Verifies: {what the test checks}
|
||
- Pattern: `path/to/existing-test.ts` *(follow this style)*
|
||
- **Verify:** `{exact command}` → expected: `{output}`
|
||
- **Regression:** `{npm test}` → expected: exit 0 *(optional)*
|
||
- **On failure:** {revert | retry | skip | escalate} — {specific instructions}
|
||
- **Checkpoint:** `git add {the step's Files and its test files} && git commit -m "{conventional commit message}"`
|
||
- **Manifest:**
|
||
```yaml
|
||
manifest:
|
||
expected_paths:
|
||
- path/to/file.ts
|
||
min_file_count: 1
|
||
commit_message_pattern: "^feat\\(scope\\):"
|
||
bash_syntax_check: []
|
||
forbidden_paths: []
|
||
must_contain: []
|
||
```
|
||
|
||
### Step 2: {description — the "run the thing" step}
|
||
|
||
- **Files:** `path/to/file.ts`
|
||
- **Changes:** {exactly what to modify}
|
||
- **Reuses:** {existing function/pattern}
|
||
- **Interface in:** `{name(args) → result}` from Step 1
|
||
- **Test first:**
|
||
- File: `path/to/test.ts` *(existing | new)*
|
||
- Verifies: {what the test checks}
|
||
- Pattern: `path/to/existing-test.ts`
|
||
- **End-to-end:** `{a command the criteria runner allows that runs the product the way a user does — the app, the CLI, the simulator; usually bash tests/e2e.sh}` → expected: {what the user sees} *(the same command also stands under ## Verification)*
|
||
- **Verify:** `{exact command}` → expected: `{output}`
|
||
- **On failure:** {revert | retry | skip | escalate} — {specific instructions}
|
||
- **Checkpoint:** `git add {the step's Files and its test files} && git commit -m "{conventional commit message}"`
|
||
- **Manifest:**
|
||
```yaml
|
||
manifest:
|
||
expected_paths:
|
||
- path/to/file.ts
|
||
min_file_count: 1
|
||
commit_message_pattern: "^feat\\(scope\\):"
|
||
bash_syntax_check: []
|
||
forbidden_paths: []
|
||
must_contain:
|
||
- path: path/to/file.ts
|
||
pattern: "expected content marker"
|
||
```
|
||
|
||
*A project without tests still gets `Test first:` on every step: the first step
|
||
adds the test runner (or a script under `tests/`) the later steps use. A plan
|
||
without an `End-to-end:` step is invalid at plan_version 1.8 or later — without
|
||
it the result can only be "not verified end to end", never green.*
|
||
|
||
### Manifest — objective completion predicate
|
||
|
||
Every step MUST have a Manifest block. This is the machine-checkable contract
|
||
that trekexecute verifies after the Verify command passes. A step is
|
||
not considered complete until its manifest verifies — regardless of Verify
|
||
command exit code.
|
||
|
||
- **expected_paths** — files that must exist after this step. Existing files
|
||
must be present in repo; new files must be marked `(new file)` in prose.
|
||
- **min_file_count** — minimum number of expected_paths that must exist.
|
||
Typically equal to `len(expected_paths)`.
|
||
- **commit_message_pattern** — regex that MUST match the HEAD commit message
|
||
after Checkpoint runs. Use escaped regex syntax (e.g., `\\(scope\\)`).
|
||
- **bash_syntax_check** — list of `.sh` files that must pass `bash -n`.
|
||
Auto-include any `.sh` in expected_paths.
|
||
- **forbidden_paths** — files this step must NOT modify (defense-in-depth
|
||
beyond Scope Fence).
|
||
- **must_contain** — optional grep assertions: `path` + `pattern` pairs that
|
||
must match in created/modified files.
|
||
|
||
### Failure recovery rules
|
||
|
||
- **On failure: revert** — undo this step's changes (`git checkout -- {files}`), do NOT proceed
|
||
- **On failure: retry** — attempt once more with the alternative approach described, then revert if still failing
|
||
- **On failure: skip** — this step is non-critical; continue to next step and note the skip
|
||
- **On failure: escalate** — stop execution entirely; the issue requires human judgment
|
||
- **Checkpoint** — after each step succeeds, commit changes so subsequent failures cannot corrupt completed work
|
||
|
||
## Alternatives Considered
|
||
|
||
| Approach | Pros | Cons | Why rejected |
|
||
|----------|------|------|--------------|
|
||
| {name} | ... | ... | ... |
|
||
|
||
## Test Strategy
|
||
|
||
- **Framework:** {test framework and runner}
|
||
- **Existing patterns:** {how tests are structured in this codebase}
|
||
- **New tests in this plan:** {N} tests across {N} steps
|
||
|
||
### Tests to write
|
||
|
||
| Type | File | Verifies | Model test |
|
||
|------|------|----------|------------|
|
||
| Unit | `path/to/test` | {what it tests} | `path/to/existing-test` |
|
||
|
||
*For projects without tests: describe manual verification approach instead.*
|
||
|
||
## Risks and Mitigations
|
||
|
||
| Priority | Risk | Location | Impact | Mitigation |
|
||
|----------|------|----------|--------|------------|
|
||
| {Critical/High/Medium/Low} | {description} | `file:line` | {what happens} | {how to handle} |
|
||
|
||
## Assumptions
|
||
|
||
*Things the planner could not verify from codebase or research. Each assumption
|
||
is a risk — review before executing.*
|
||
|
||
| # | Assumption | Why unverifiable | Impact if wrong |
|
||
|---|-----------|-----------------|-----------------|
|
||
| 1 | {what we assumed} | {why we couldn't check} | {what breaks} |
|
||
|
||
*If this list has 3+ items, the plan may need additional investigation
|
||
before execution.*
|
||
|
||
## Verification
|
||
|
||
*Per-step manifest verification runs automatically during execution (every
|
||
step's Manifest block is objectively checked by trekexecute before the
|
||
step is marked passed). This section is for end-to-end integration checks
|
||
that cross step boundaries — complete workflows, system-level behavior.*
|
||
|
||
- [ ] `{exact command}` → expected: `{exact output or behavior}`
|
||
- [ ] `{exact command}` → expected: `{exact output or behavior}`
|
||
|
||
## Estimated Scope
|
||
|
||
- **Files to modify:** {N}
|
||
- **Files to create:** {N}
|
||
- **Complexity:** {low | medium | high}
|
||
|
||
## Execution Strategy
|
||
|
||
*Include this section when the plan has more than 5 implementation steps.
|
||
Omit for small plans (≤ 5 steps) — trekexecute will run them sequentially
|
||
in a single session.*
|
||
|
||
*The execution strategy groups steps into sessions and organizes sessions
|
||
into waves. Sessions in the same wave can run in parallel. Sessions in
|
||
later waves depend on earlier waves completing first.*
|
||
|
||
### Session 1: {title}
|
||
- **Steps:** {step numbers, e.g., 1, 2, 3}
|
||
- **Wave:** {wave number}
|
||
- **Depends on:** {session numbers, or "none"}
|
||
- **Scope fence:**
|
||
- Touch: {files this session may modify}
|
||
- Never touch: {files reserved for other sessions}
|
||
|
||
### Session 2: {title}
|
||
- **Steps:** {step numbers}
|
||
- **Wave:** {wave number}
|
||
- **Depends on:** {session numbers, or "none"}
|
||
- **Scope fence:**
|
||
- Touch: {files}
|
||
- Never touch: {files}
|
||
|
||
### Execution Order
|
||
|
||
- **Wave 1:** {session list} (parallel)
|
||
- **Wave 2:** {session list} (after Wave 1)
|
||
|
||
### Grouping rules applied
|
||
|
||
- Steps sharing files → same session
|
||
- Steps in independent modules → separate sessions (parallelizable)
|
||
- 3–5 steps per session (target)
|
||
- Sessions ordered by dependency, waves by independence
|
||
|
||
## Plan Quality Score
|
||
|
||
| Dimension | Weight | Score | Notes |
|
||
|-----------|--------|-------|-------|
|
||
| Structural integrity | 0.15 | {0–100} | {step ordering, dependencies} |
|
||
| Step quality | 0.20 | {0–100} | {granularity, specificity, TDD} |
|
||
| Coverage completeness | 0.20 | {0–100} | {spec → steps, no gaps} |
|
||
| Specification quality | 0.15 | {0–100} | {no placeholders, clear criteria} |
|
||
| Risk & pre-mortem | 0.15 | {0–100} | {failure modes addressed} |
|
||
| Headless readiness | 0.10 | {0–100} | {On failure + Checkpoint per step} |
|
||
| Manifest quality | 0.05 | {0–100} | {all steps have valid, checkable manifests} |
|
||
| **Weighted total** | **1.00** | **{score}** | **Grade: {A/B/C/D}** |
|
||
|
||
**Adversarial review:**
|
||
- **Plan critic:** {verdict — findings count by severity, key issues}
|
||
- **Scope guardian:** {verdict — ALIGNED / CREEP / GAP / MIXED}
|
||
|
||
## Revisions
|
||
|
||
*Added by adversarial review. Omit if no revisions were needed.*
|
||
|
||
| # | Finding | Severity | Resolution |
|
||
|---|---------|----------|------------|
|
||
| 1 | {what was wrong} | {blocker/major/minor} | {how it was fixed} |
|
||
|
||
<!-- ## Critic Verdict — do NOT write this section. `lib/validators/plan-gate.mjs
|
||
--record` appends it after the first critic round (Phase 9) and replaces it on
|
||
each later round: one fenced json block with round, max_rounds, plan_sha256
|
||
(the plan minus its review log), verdict BLOCK | REVISE | PASS, and the
|
||
deduplicated findings. It may also carry the optional rule-A and rule-B
|
||
fields (DIFF_FIELDS in lib/review/critic-diff.mjs: diff_base, diff_note,
|
||
resolved, and per finding op_line, op_line_end, line_end, rule_keys,
|
||
original_severity, lowered_by, caught_by, lowering_refused, carried_from);
|
||
absent means round-1 behaviour. `plan-gate.mjs <plan>` exits 0 only when the
|
||
plan validates, the block matches the current plan, no BLOCKER is open, and
|
||
every open MAJOR was accepted by the operator. -->
|