merge: wave 1 order 3 (plan and design) into main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
885d515c3b
24 changed files with 3115 additions and 61 deletions
114
templates/design-template.md
Normal file
114
templates/design-template.md
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
<!--
|
||||
The design part of a plan (plan_version 1.8). /trekplan Phase 8 writes it as
|
||||
the plan's `## Design` section, between `## Context` and
|
||||
`## Implementation Plan`, ONLY when the brief's `ceremony:` is
|
||||
`architectural` (an absent field means architectural: heaviest on doubt).
|
||||
`small` and `bounded` plans omit it.
|
||||
|
||||
The design lives in the PLAN, never in the brief: the brief format is a public
|
||||
contract (Handover 1), the plan contract is Voyage's own (Handover 4).
|
||||
|
||||
`plan-validator --strict` checks, for an architectural 1.8 plan: the eight
|
||||
`###` subsections below exist, the module map is a mermaid graph with no
|
||||
cycle, every architecture rule names its enforcer, a checked rule names the
|
||||
step that proves it, and an advisory rule names its `.claude/rules/` file.
|
||||
`### Decisions (ADR)` and `### Gotchas` are optional.
|
||||
|
||||
Borrowed, with credit:
|
||||
- Section list: Kiro's design.md (architecture, data flow, interfaces, data
|
||||
models, error handling, test strategy), and its requirements analysis asked
|
||||
as two-choice questions. Kiro's SMT engine is not borrowed.
|
||||
- Design questions: obra/superpowers@8ca22db brainstorming (MIT, © 2025 Jesse
|
||||
Vincent).
|
||||
- Module map with one dependency direction and no cycles, and "use the
|
||||
de-facto tool" (e.g. dependency-cruiser): addyosmani/agent-skills@9d0c60d
|
||||
(MIT, © 2025 Addy Osmani).
|
||||
- Vocabulary (deep module, seam, deletion test), the three-condition ADR bar,
|
||||
and pass → fail → pass: mattpocock/skills@c55ee46 (MIT, © 2026 Matt Pocock).
|
||||
- Rules that must pass: GitHub Spec Kit's constitution (MIT), changed so each
|
||||
rule names what enforces it; in Spec Kit the model ticks the boxes itself.
|
||||
- Gotchas and "Derived from <hash>": bashebr/ai-native-sdlc@11fb8d7 (MIT).
|
||||
-->
|
||||
|
||||
## Design
|
||||
|
||||
> Derived from: `{brief path}` @ sha256 `{first 12 hex of the brief's sha256}` · ceremony: architectural
|
||||
|
||||
### Architecture
|
||||
|
||||
The modules this change adds or alters, and what each one owns. Judge each by
|
||||
the deletion test: if deleting the module would only move its complexity into
|
||||
its callers, it earns its place; a deep module hides much behind a small
|
||||
interface. Name the seams where behaviour can be tested or swapped.
|
||||
|
||||
### Data Flow
|
||||
|
||||
How data enters, moves through and leaves the changed modules — one path per
|
||||
use case in the brief, in order.
|
||||
|
||||
### Interfaces
|
||||
|
||||
Every boundary this plan creates or changes: signature, inputs, outputs,
|
||||
errors. Steps cite these in `Interface in:` / `Interface out:`.
|
||||
|
||||
### Data Models
|
||||
|
||||
Types, schemas, files and their fields. Mark what is new and what changes shape.
|
||||
|
||||
### Error Handling
|
||||
|
||||
Each failure mode, what the system does about it, and what the user sees.
|
||||
Unreadable input, a missing dependency and a partial failure are always listed.
|
||||
|
||||
### Module Map
|
||||
|
||||
Dependencies point one way. The validator rejects a cycle.
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
cli[src/cli] --> core[src/core]
|
||||
core --> store[src/store]
|
||||
```
|
||||
|
||||
### Architecture Rules
|
||||
|
||||
Each rule names what enforces it. **checked by `<command>`** — a command the
|
||||
target repo already has (its own dependency-cruiser, import-linter, linter or a
|
||||
test); `lib/verification/arch-rules.mjs` runs dependency-cruiser and
|
||||
import-linter when the repo configures them, and installs nothing. **advisory —
|
||||
`.claude/rules/<file>.md`** — guidance Claude Code loads in the target repo; a
|
||||
plan step writes that file. A checked rule is accepted only once it has been
|
||||
seen to pass, fail on a planted violation, and pass again: the Proof column
|
||||
names the step that shows it (`arch-rules.mjs --prove --rule <name> --plant
|
||||
<file>=<dest>` does it in one command for the two supported tools; the planted
|
||||
run must trip that rule).
|
||||
|
||||
| Rule | Enforced by | Proof |
|
||||
|------|-------------|-------|
|
||||
| {core never imports cli} | checked by `{node_modules/.bin/depcruise --config .dependency-cruiser.cjs src}` | Step {N} |
|
||||
| {prefer pure functions in core} | advisory — `.claude/rules/{core}.md` | — |
|
||||
|
||||
### Requirements Check
|
||||
|
||||
Conflicts and gaps between the brief's requirements, each asked once as a
|
||||
two-choice question with the recommendation first: **keep** (the requirement as
|
||||
written) or **change like this** (a concrete proposal). Record the answer here.
|
||||
An answer that changes the brief's Intent, Goal or Success Criteria stops the
|
||||
plan: the brief is re-run through `/trekbrief`, never edited by the planner.
|
||||
|
||||
| # | Finding | Question | Answer |
|
||||
|---|---------|----------|--------|
|
||||
| 1 | {two requirements that cannot both hold / a case no requirement covers} | Keep, or change like this: {proposal}? | {keep / change} |
|
||||
|
||||
*If there is nothing to ask, write "No conflicts or gaps found" and say what was compared.*
|
||||
|
||||
### Decisions (ADR)
|
||||
|
||||
*Optional.* Only for a decision that is hard to reverse, surprising without
|
||||
context, AND the result of a real trade-off. One paragraph each: context,
|
||||
decision, alternatives rejected and why.
|
||||
|
||||
### Gotchas
|
||||
|
||||
*Optional.* Each place two constraints collide, the risky call made there, and
|
||||
who decided it.
|
||||
|
|
@ -18,13 +18,24 @@ source_findings:
|
|||
|
||||
> **Plan quality: {grade}** ({score}/100) — {APPROVE | APPROVE_WITH_NOTES | REVISE | REPLAN}
|
||||
>
|
||||
> Generated by trekplan v{version} on {YYYY-MM-DD} — `plan_version: 1.7`
|
||||
> Generated by trekplan v{version} on {YYYY-MM-DD} — `plan_version: 1.8` · `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
|
||||
|
|
@ -57,14 +68,25 @@ their relationships, and the data flow between them.*
|
|||
|
||||
## Implementation Plan
|
||||
|
||||
Each step targets 1–2 files and one focused change. Steps follow TDD structure
|
||||
when the project has tests.
|
||||
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 requires it), and one step runs the thing
|
||||
end to end (`End-to-end:`).
|
||||
|
||||
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). A field that is present is never empty.
|
||||
|
||||
### 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}
|
||||
|
|
@ -84,15 +106,17 @@ when the project has tests.
|
|||
must_contain: []
|
||||
```
|
||||
|
||||
### Step 2: {description}
|
||||
### 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:** `{the command that runs the product the way a user does — the app, the CLI, the simulator}` → expected: {what the user sees}
|
||||
- **Verify:** `{exact command}` → expected: `{output}`
|
||||
- **On failure:** {revert | retry | skip | escalate} — {specific instructions}
|
||||
- **Checkpoint:** `git commit -m "{conventional commit message}"`
|
||||
|
|
@ -110,8 +134,10 @@ when the project has tests.
|
|||
pattern: "expected content marker"
|
||||
```
|
||||
|
||||
*For projects without tests: omit "Test first" and keep "Verify" with a
|
||||
concrete command (e.g., run the app, check output, curl an endpoint).*
|
||||
*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 — without it the
|
||||
result can only be "not verified end to end", never green.*
|
||||
|
||||
### Manifest — objective completion predicate
|
||||
|
||||
|
|
@ -257,3 +283,10 @@ later waves depend on earlier waves completing first.*
|
|||
| # | 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. `plan-gate.mjs <plan>` exits 0 only when the plan
|
||||
validates, the block matches the current plan, and no BLOCKER is open. -->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue