diff --git a/.claude/agents/executor.md b/.claude/agents/executor.md index e4c1b41..f4c5215 100644 --- a/.claude/agents/executor.md +++ b/.claude/agents/executor.md @@ -14,8 +14,8 @@ Before editing: 1. Read `CLAUDE.md` and obey its invariants and working agreements. 2. Read the assigned task and only the docs and code needed for it. 3. Confirm the checkout is not on the default branch (`main`/`master`); never change files there. -4. Confirm the scope, the files you may touch, the success criteria, the verification and the - escalation conditions. +4. Confirm the scope, the success criteria and the verification, and the files you may touch and + the escalation conditions where the brief names them. While working: diff --git a/.claude/agents/planner.md b/.claude/agents/planner.md index 4315632..5de64c6 100644 --- a/.claude/agents/planner.md +++ b/.claude/agents/planner.md @@ -23,18 +23,22 @@ say so and give the new reason. Follow `docs/plans/_template.md`. At minimum: -1. **Approach**: the architecture in a few sentences: what changes, where the seams are, and any - shared contract whose sides must change together. -2. **Alternatives considered**: at least one, and why it lost. Flag decisions that meet the bar - for a decision record. +1. **Goal**: what it delivers and the scope boundary. Call out anything the request would have + you build ahead of where it belongs. +2. **Approach**: the architecture in a few sentences: what changes, where the seams are, and any + shared contract whose sides must change together. When there was a real choice, name the + approach that lost and why. Flag decisions that meet the bar for a decision record. 3. **Risks and open questions**: anything that needs the owner's decision before work starts. - Ask; don't assume. Get the scope boundary right: call out anything the request would have you - build ahead of where it belongs. -4. **Tasks**: small, separately verifiable units in order, each with files, dependencies, - complexity class (ROUTINE / STRONG / FRONTIER), success criteria, verification, escalation - conditions, and the owner's hours it needs (reviews, live checks, labelling, decisions). -5. **Execution strategy**: what runs at the same time and in which worktree, which - single-instance resources it claims, the approval gates, and the owner-only actions involved. + Ask; don't assume. +4. **Tasks**: small, separately verifiable units in order, each with dependencies, success + criteria and verification. When the work needs the owner's time (reviews, live checks, + labelling, decisions), give the total hours in the header. +5. **For larger plans** (several delegated tasks, or work that runs at the same time), the + template's optional task fields: a **Model** when a task needs more than its agent's default + (for example `executor` on Opus for a subtle concurrency or data-migration change), + **Escalate if** for conditions specific to one task, and **Parallel with**. +6. **Concurrency**, only when tasks will run at the same time: the table from the + `parallel-work` skill. Make the plan concrete enough that a fresh session, possibly on another model, can execute it from the text alone. For a large plan, name the path it should be saved to diff --git a/.claude/agents/reviewer.md b/.claude/agents/reviewer.md index 558c70f..de9fb6f 100644 --- a/.claude/agents/reviewer.md +++ b/.claude/agents/reviewer.md @@ -61,6 +61,12 @@ Rank findings by impact: should be fixed before completion. - **Minor:** worth doing, does not block. +A missing or stale record is Minor: a `Missed by:` line, a plan's `Status:` line or log, a +decision record, release notes, a deviation the plan does not mention. It is Major only when the +gap would let something ship that nobody approved, or hide a known bug from the people who would +fix it. The code a record describes is judged on its own: a record that says a case is handled is +a claim to check in the code, not evidence that it is. + The verdict is CHANGES_REQUIRED when FINDINGS has a Critical or Major item; Minor findings and unresolved questions alone allow PASS. diff --git a/.claude/review-checklists.md b/.claude/review-checklists.md index bc8aabc..0a4e5e4 100644 --- a/.claude/review-checklists.md +++ b/.claude/review-checklists.md @@ -32,21 +32,25 @@ stages. 1. List the states and every place that writes each one. Is there a state the code reaches but never names, or are there two flags that can disagree (for example "not stopped" while the core says "failed")? -2. For each outside event (a reply, a close, a timeout, a message, a click), what happens if it +2. Which states are final (done, verified, rejected, consumed, expired)? For every writer, read + its code: does it check the current state before it writes, so that nothing leaves a final + state or overwrites an outcome already recorded? A plan or comment that lists the states and + their transitions is not proof that the code enforces them. +3. For each outside event (a reply, a close, a timeout, a message, a click), what happens if it arrives twice, late (after its owner was replaced), out of order, or never? -3. If the work fails or crashes midway, what state is left? Does a retry or a restart recover +4. If the work fails or crashes midway, what state is left? Does a retry or a restart recover from it, or does it skip or repeat work? -4. Does every handler that acts for an owner (a socket, worker, request or generation) check +5. Does every handler that acts for an owner (a socket, worker, request or generation) check that the owner is still the current one? Search for every place that sets or uses that owner, including handlers the diff did not change, and compare them: if three check and one doesn't, the odd one out needs a reason, even when a comment gives one. -5. On teardown and on every failure path, is everything released: timers, workers, sockets, +6. On teardown and on every failure path, is everything released: timers, workers, sockets, listeners, slots, tickets? -6. Can a failure turn into an apparent success, such as an empty result treated as fine or a +7. Can a failure turn into an apparent success, such as an empty result treated as fine or a failure counter reset by a reply that did nothing? -7. Retries: is there one timer per thing, is the backoff reset only by real success, and is +8. Retries: is there one timer per thing, is the backoff reset only by real success, and is there a state where it gives up and says so? -8. Do sequence numbers, versions and expiry times survive a reconnect, restart or restore the way +9. Do sequence numbers, versions and expiry times survive a reconnect, restart or restore the way their readers assume? Does restored state keep its original expiry, or restart it? Does any timer or ordering read the wall clock where a step backwards would break it? @@ -146,8 +150,8 @@ revert left the check to it. was missing or too narrow, a lint rule that was off, a review question nobody asked, a review that was skipped, or a live check that wasn't run. `Missed by: none ()` is a valid answer when no reasonable check would have caught it. Before a PR exists, look for the line in the plan, - the brief or the commit message. A missing line is a Minor finding before the PR is opened and a - Major one after, because the PR description is where it is collected. + the brief or the commit message. A missing line is a Minor finding: it records how the bug got + through, and the fix itself is judged on its own. 2. Does the diff add that check, or say where it went? A regression test must fail without the fix, so answer checklist 6, item 1 for it. A lint rule counts. A revert may leave the check to the PR that lands the change again, if the revert's `Missed by:` line says so. A new review question diff --git a/.claude/skills/handoff/SKILL.md b/.claude/skills/handoff/SKILL.md index ab767cd..5b3e7d2 100644 --- a/.claude/skills/handoff/SKILL.md +++ b/.claude/skills/handoff/SKILL.md @@ -57,7 +57,7 @@ size, offer this skill at the next natural break. 5. **Print the starting prompt** in one code block, at most ten lines, for the owner to paste into a new session: - repository and branch; - - the model and effort the role runs on, if `CLAUDE.md` names one (its model routing); + - the model and effort the role runs on, from its agent file or the lead line in `CLAUDE.md`; - where to read: the plan and its section, the role's handoff file, or the handoff commit by its short hash; - the next step, in one line; diff --git a/.claude/skills/parallel-work/SKILL.md b/.claude/skills/parallel-work/SKILL.md index 092cf60..ca979ea 100644 --- a/.claude/skills/parallel-work/SKILL.md +++ b/.claude/skills/parallel-work/SKILL.md @@ -7,8 +7,8 @@ description: Rules for concurrent work — worktrees for code-writing workers th ## Concurrency and worktrees -- A parallel group in a plan is eligibility, not a schedule: the plan says which tasks actually - run at the same time. +- Tasks that could overlap are not a schedule: the plan says which ones actually run at the same + time, in the table below. - **Every concurrent code-writing worker gets its own worktree**, including when the lead and one worker both write. Different files do not make one checkout safe: the branch, index, working tree, generated files and running commands are shared. Read-only workers, sequential work and a @@ -28,6 +28,26 @@ description: Rules for concurrent work — worktrees for code-writing workers th are "not found". Dispatch `general-purpose` (or `Plan` for read-only planning), set the model the agent file names, and make the brief's first line "read `.claude/agents/.md` first". +## In the plan + +Add this to a plan whose tasks will run at the same time; a sequential plan leaves it out. Name +only the tasks that actually overlap. + +| Task | Concurrent with | Worker/session | Writes files? | Base ref | Isolation | Shared mutable resources | Integration | +|---|---|---|---:|---|---|---|---| +| T2 | T3 | Executor | Yes | `` | Worktree | None | Cherry-pick | +| T3 | T2 | Research worker | No | `` | Read-only shared checkout | None | Report only | + +For each task in the table, confirm: + +- **Reason:** why running it at the same time is useful or necessary. +- **Isolation:** main checkout, read-only shared checkout, worktree, or an external environment. +- **Base ref:** the exact branch or commit. +- **Tracked inputs available:** yes, or how they are provisioned. +- **Shared resources:** none, or the datasets, caches, GPUs, ports, databases or accounts it uses. +- **Output ownership:** the directories, files or artifacts this task owns. +- **Integration method:** direct, merge, cherry-pick or artifact handoff. + ## Parallel lead sessions More than one lead session can run at once (for example one on research beside one on the product). diff --git a/.claude/workflow.lock.json b/.claude/workflow.lock.json index a364def..0dba265 100644 --- a/.claude/workflow.lock.json +++ b/.claude/workflow.lock.json @@ -2,20 +2,20 @@ "excluded": [], "files": { ".claude/agents/architect.md": "48fe7a09c04c46670265be39dab3c2f1152f84ee8e36875f0c7aabd99db91631", - ".claude/agents/executor.md": "06765095210290ade870df7d5d20eda1138e427be3023f4656784e0863708c92", + ".claude/agents/executor.md": "d1c1bf254aeb68450899a65a5ef7de7d35f0c4227ec749b192d7fd5b649f98bf", ".claude/agents/explore.md": "5ad8a5c9ea6d6975e572c0faaff6db9bc1345393eb1cce23392be2c3fc7c6693", - ".claude/agents/planner.md": "229e070a31315ed476658d754712a6d065535933e7aae878dbbf4de28d0891af", - ".claude/agents/reviewer.md": "f04f1e4d823724f21c977fd87ec35e4cfc74c9bac9344a0f14c526907de57e4d", + ".claude/agents/planner.md": "685d62426ea902bd723706d0af7d8a4f66adcaf0151a162542e53fcefa5cf21d", + ".claude/agents/reviewer.md": "d5552125d326b75723f1c1305daac077cd2c46128ef7c2c734e5b1619e803957", ".claude/hooks/guard-default-branch.py": "8788b877187d802eb87d316d47ae0bb43ebb67782bb1d4f55bd24b643a1b2fc9", - ".claude/review-checklists.md": "fbbcfa915376edcf21d7ba990c96c558a9795fd8a874b9f72f57ff15c52d04f1", + ".claude/review-checklists.md": "7723146d149447b74cfe51ac77c371aaec3a048b0a39b19e90e74b6cec5ef94c", ".claude/skills/checkpoint/SKILL.md": "e773f095fca977e9872d0b7c13cc7918b065443de8095896d0097aeb07c1e739", ".claude/skills/gc/SKILL.md": "abfb7282d3000eb30b872df8313a17aa2c60a54e5951034c0bdfaa3da59bde71", - ".claude/skills/handoff/SKILL.md": "1289ffc479b7761066212b576d1a22c8c134e3aeed7bff5945642acc439a3eab", - ".claude/skills/parallel-work/SKILL.md": "94fbb922cf88fc005fd8cfa033c1c3559adbfde04fd759ca5f3c696f2afd9afe", + ".claude/skills/handoff/SKILL.md": "34b2db6edd429bb973969142d00619f4943b61ecd7f55d4a88e5a097edc5b669", + ".claude/skills/parallel-work/SKILL.md": "afedd666e0fe65d46642f00502f3d986291a78f7ee4e67cd2dd637122e30e5dc", ".claude/workflow/check.py": "f2e69f3c29d75e116ed3812bc3a33af7129a82c8d32b17d8782d8d4aed7ce29a", ".claude/workflow/gc.py": "30b0191f1171a1fe9d5f6bf10579a8eaa8a06db49da9a8437376df5bebb70af4", - "docs/plans/_template.md": "9178c6a0a9807241ecd8d5624f9e07f94f6b5181e4a2290f44fd49f0c8b08d3f" + "docs/plans/_template.md": "075ca3feeb148907c8d21d56c592376d447eb16eea0e6045d209f117cb0eba35" }, - "kit": "9a00ece 2026-11-06", + "kit": "1fa72c4 2026-11-09", "level": "full" } diff --git a/CLAUDE.md b/CLAUDE.md index 1c2a266..637a371 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -70,17 +70,16 @@ and report formats live there. - **Milestone specs: do not edit files until the architecture and the first small change are explained and approved.** Inspect read-only first. -- Decompose work into tasks with dependencies, complexity class, success criteria, escalation - conditions and verification. **Price every task in the owner's hours**: they are the scarcest - resource. +- Decompose work into tasks with dependencies, success criteria and verification. **Price the + work in the owner's hours**: they are the scarcest resource. - Work directly when a task is small, tightly coupled or cheaper to do than to brief. Delegate when work can run concurrently, is self-contained, would flood the lead's context, or needs a fresh judgment. Every worker gets a bounded task and ends with SUCCESS, ESCALATE or BLOCKED; on ESCALATE or BLOCKED, stop the tasks that depend on it and update the plan. -- Present the task graph, delegation, model classes and approval gates **before dispatching - code-writing workers**, unless the owner has authorised autonomous work. Read-only workers need - no approval. Ask before anything that changes product behaviour, architecture, compatibility, - security or privacy posture, production data, scope or cost. +- Present the task graph, delegation and approval gates **before dispatching code-writing + workers**, unless the owner has authorised autonomous work. Read-only workers need no approval. + Ask before anything that changes product behaviour, architecture, compatibility, security or + privacy posture, production data, scope or cost. ### Owner-only actions (each time, never implied by plan approval) @@ -92,27 +91,14 @@ and report formats live there. price from a live read go in the plan's log before it is created, a watchdog stops it if the session is lost, and it is deleted when the job ends. -### Model routing +### Models -**The lead runs on Opus at high effort**, chosen at the start of a session. Plans name capability -classes; map them at dispatch: ROUTINE → Sonnet (Haiku for lookups), STRONG → Opus, FRONTIER → -Fable. Update the mapping when models change. - -| Agent | Default | Use | -|---|---|---| -| `Explore` | Haiku, low | code search; fetching one decision entry, plan task or doc section | -| `executor` | Sonnet, medium | ROUTINE tasks; override to Opus for STRONG | -| `reviewer` | Opus, high | every review; Sonnet only for ROUTINE-only work | -| `planner` | Fable, high | milestone plans, re-plans after an ESCALATE | -| `architect` | Fable, high | judgement calls mid-task; resume it with `SendMessage` for follow-ups | - -- Call FRONTIER where it pays: a milestone plan, a rule or bar set before measuring, a re-plan, a - result the lead cannot explain, a root cause after two strikes. +- **The lead runs on Opus at high effort**, chosen at the start of a session and not switched + during it. Each model has its own prompt cache, so a switch re-reads the whole conversation + uncached; ask `architect`, or start a session. Each agent's model and effort are set in its + agent file; when a plan task names a stronger model, dispatch it on that one. - **Keep the lead's context small.** The lead does not read a decisions theme file or a plan over ~30 KB itself; `Explore` fetches the entry or task it needs. -- **Don't switch the lead's model or effort mid-session**: each model has its own prompt cache, so - the next turn re-reads the whole conversation uncached. Ask `architect`, or start a session. -- Never set `CLAUDE_CODE_SUBAGENT_MODEL_FORCE`: it ignores the agent files' `model`. ### Concurrency @@ -140,8 +126,7 @@ Fable. Update the mapping when models change. - Weekly, at a handoff, or when `.claude/worktrees/` piles up: run `/gc` (the `gc` skill) to remove worktrees and branches whose work is already in the default branch. - **Close out:** the plan's `Status:` line and the active list; the execution log compressed into - the completion summary with its lesson or `NO_ENTRY`; decision lines that meet the index bar; a - short summary for the owner. + the completion summary; decision lines that meet the index bar; a short summary for the owner. diff --git a/docs/plans/README.md b/docs/plans/README.md index eed585f..844e59a 100644 --- a/docs/plans/README.md +++ b/docs/plans/README.md @@ -25,9 +25,5 @@ plan's `Status:` line disagree. the plan stays a lean spec. - **On Done**, compress the log into the completion summary (outcome, deviations, follow-ups, PRs), then delete the `-log.md` file. Git keeps the full log. -- **Write the lesson field** (at most one, or `NO_ENTRY`), then list earlier ones with - `rg -n '^- \*\*Lesson:\*\* cue' docs/plans`. When a lesson repeats one from an earlier plan, - promote it: a line in `CLAUDE.md` or an agent file, or better a hook or a check, which cannot be - skipped the way prose can. Small fixes and one-sitting features don't need a plan file. diff --git a/docs/plans/_template.md b/docs/plans/_template.md index aaf7c83..db84ef6 100644 --- a/docs/plans/_template.md +++ b/docs/plans/_template.md @@ -2,171 +2,62 @@ - **Date:** YYYY-MM-DD - **Status:** Draft | Approved | In progress | Blocked | Done | Closed | Superseded (by …) | Shelved -- **Planned by:** -- **Spec / source:** - **Branch:** `` +- **Source:** +- **Owner time, total:** ## Goal -Describe what this effort delivers in 2–4 sentences. State the scope boundary -explicitly: what this deliberately does **not** build yet, and why. +What this effort delivers, in 2–4 sentences. State the scope boundary: what it deliberately does +**not** build yet, and why. ## Approach -Describe the architecture, affected workspaces, important seams, repository invariants, -and any shared-type coupling that requires coordinated changes. Explain the intended -data/control flow where relevant. +The architecture in a few sentences: what changes, where the seams are, and any shared contract +whose sides must change together. -## Alternatives considered +- **Rejected:** -- **** — - -Promote decisions worth preserving beyond this effort to `docs/decisions.md`. +Promote decisions worth keeping beyond this effort to `docs/decisions.md`. ## Risks and open questions -- **** — - -Resolve questions requiring user input before changing the plan from Draft to Approved. - -## Dependency summary - -Replace the example with the actual task graph. Keep it small enough to scan quickly. +- ****: -```mermaid -flowchart LR - T1 --> T2 - T1 --> T3 - T2 --> T4 - T3 --> T4 -``` +Resolve questions that need the owner before the status moves from Draft to Approved. -- **Parallel group A:** -- **Parallel group B:** -- **Integration order:** +## Tasks -## Task graph - -Create independently understandable work units, not one task per file. Separate tasks do -not automatically imply separate agents. +Independently verifiable units, in order. Separate tasks do not imply separate agents. ### T1 — - **Status:** Pending | In progress | Complete | Escalated | Blocked -- **Dependencies:** None | T, ... -- **Parallel group:** | Sequential -- **Complexity:** ROUTINE | STRONG | FRONTIER -- **Execution:** Lead session | Executor | Research worker -- **Owner time:** None | -- **Expected files/workspaces:** `path/...` -- **Objective:** +- **Depends on:** None | T, ... +- **Objective:** - **Success criteria:** - - - - **Verification:** - `` -- **Escalate if:** - - - -### T2 — - -- **Status:** Pending | In progress | Complete | Escalated | Blocked -- **Dependencies:** T1 -- **Parallel group:** | Sequential -- **Complexity:** ROUTINE | STRONG | FRONTIER -- **Execution:** Lead session | Executor | Research worker -- **Owner time:** None | -- **Expected files/workspaces:** `path/...` -- **Objective:** -- **Success criteria:** - - -- **Verification:** - - `` -- **Escalate if:** - - - - - -## Execution strategy +- **Model:** +- **Escalate if:** +- **Parallel with:** , ...; the plan then needs the concurrency table> -- **Lead/orchestrator owns:** -- **Delegated tasks:** -- **Model routing:** -- **Owner time, total:** -- **Approval gates:** - - user approval before code-writing dispatch - - user approval before -- **Review strategy:** + -### Concurrency and isolation - -A parallel group identifies tasks that are eligible to overlap. It does not mean they -will automatically execute concurrently. For every parallelizable task, explicitly state -whether it will actually run concurrently or sequentially. - -| Task | Actually concurrent with | Worker/session | Writes files? | Branch/base | Isolation | Shared mutable resources | Integration | -|---|---|---|---:|---|---|---|---| -| T1 | None | Lead | Yes | `` | Main checkout | `` | Direct | -| T2 | T3 | Executor | Yes | `` | Worktree | None | Cherry-pick | -| T3 | T2 | Research worker | No | `` | Read-only shared checkout | None | Report only | - -For each task scheduled to run concurrently, confirm: - -- **Execution timing:** Concurrent | Sequential | Deferred -- **Reason:** -- **Isolation:** Main checkout | Read-only shared checkout | Worktree | External environment -- **Base ref:** `` -- **Tracked inputs available:** Yes | No; -- **Shared resources:** None | -- **Output ownership:** -- **Integration method:** Direct | Merge | Cherry-pick | Artifact handoff - -## Execution log - -Keep the log in a sibling file, `-log.md`, not here: the plan is the spec a -fresh session executes from, and the log grows with every task. Record material discoveries, -decisions, escalations, and deviations there while work proceeds, in this format. Keep routine -implementation detail out of it. - -- **YYYY-MM-DD — : ** - - **Evidence:** - - **Impact:** - - **Resolution:** - - **Permanent decision record needed:** Yes | No (the bar is in the `docs/decisions.md` header) - -## Integration and verification - -### Integrated checkpoint - -- [ ] `/checkpoint` completed (typecheck → test → build → verify) -- [ ] Any checkpoint failures resolved and the checkpoint rerun - -### End-to-end acceptance - -- [ ] -- [ ] -- [ ] - -### Independent review - -- **Reviewer:** -- **Verdict:** Pending | Pass | Changes required -- **Findings:** -- [ ] Material findings resolved -- [ ] Relevant verification rerun after fixes +The execution log lives beside this file, in `-log.md` (see the plans README). ## Completion summary -- **Delivered:** -- **Deviations from approved plan:** None | -- **Known risks / follow-up:** None | -- **Decision records updated:** None | `docs/decisions.md` entries +- **Delivered:** +- **Deviations from the approved plan:** None | +- **Follow-ups:** None | +- **Review:** - **Missed by:** n/a | -- **Lesson:** NO_ENTRY | cue: / lesson: / evidence: / confidence: - -