codebyplan 1.13.39 → 1.13.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/cli.js +24631 -354
  2. package/package.json +4 -2
  3. package/templates/agents/cbp-cc-executor.md +4 -4
  4. package/templates/agents/cbp-round-executor.md +2 -10
  5. package/templates/agents/cbp-task-check.md +2 -0
  6. package/templates/agents/cbp-task-planner.md +2 -5
  7. package/templates/hooks/README.md +14 -2
  8. package/templates/hooks/cbp-session-start-hook.sh +32 -0
  9. package/templates/hooks/cbp-test-coverage-gate.sh +20 -6
  10. package/templates/hooks/cbp-test-hooks.sh +72 -0
  11. package/templates/hooks/hooks.json +11 -0
  12. package/templates/settings.project.base.json +10 -0
  13. package/templates/skills/cbp-checkpoint-check/SKILL.md +10 -10
  14. package/templates/skills/cbp-checkpoint-complete/SKILL.md +7 -7
  15. package/templates/skills/cbp-checkpoint-create/SKILL.md +11 -9
  16. package/templates/skills/cbp-checkpoint-end/SKILL.md +7 -10
  17. package/templates/skills/cbp-checkpoint-plan/SKILL.md +10 -10
  18. package/templates/skills/cbp-checkpoint-start/SKILL.md +6 -6
  19. package/templates/skills/cbp-checkpoint-update/SKILL.md +9 -9
  20. package/templates/skills/cbp-git-commit/SKILL.md +8 -4
  21. package/templates/skills/cbp-merge-main/SKILL.md +2 -5
  22. package/templates/skills/cbp-round-check/SKILL.md +12 -8
  23. package/templates/skills/cbp-round-complete/SKILL.md +16 -10
  24. package/templates/skills/cbp-round-end/SKILL.md +9 -10
  25. package/templates/skills/cbp-round-execute/SKILL.md +7 -6
  26. package/templates/skills/cbp-round-input/SKILL.md +24 -12
  27. package/templates/skills/cbp-round-start/SKILL.md +36 -16
  28. package/templates/skills/cbp-round-update/SKILL.md +14 -10
  29. package/templates/skills/cbp-session-end/SKILL.md +22 -12
  30. package/templates/skills/cbp-session-start/SKILL.md +20 -47
  31. package/templates/skills/cbp-ship/SKILL.md +4 -4
  32. package/templates/skills/cbp-ship-main/SKILL.md +4 -5
  33. package/templates/skills/cbp-supabase-migrate/SKILL.md +12 -9
  34. package/templates/skills/cbp-task-check/SKILL.md +10 -10
  35. package/templates/skills/cbp-task-complete/SKILL.md +11 -9
  36. package/templates/skills/cbp-task-create/SKILL.md +7 -5
  37. package/templates/skills/cbp-task-start/SKILL.md +15 -17
  38. package/templates/skills/cbp-task-testing/SKILL.md +18 -18
  39. package/templates/skills/cbp-todo/SKILL.md +21 -21
@@ -26,15 +26,15 @@ Source `repo_id` from `.codebyplan/repo.json` — every MCP call below that take
26
26
 
27
27
  | Shape | Resolves to |
28
28
  |-------|-------------|
29
- | `{chk}` (e.g. `138`) | CHK-{chk} via MCP `get_checkpoints` filtered by `number` |
30
- | _(empty)_ | Active/pending checkpoint via MCP `get_current_task`; if none in progress, the most recent `pending` checkpoint that has no `plan.steps` |
29
+ | `{chk}` (e.g. `138`) | CHK-{chk}: scan `.codebyplan/state/checkpoints/*.json` by `number` field (local-first; fallback MCP `get_checkpoints`) |
30
+ | _(empty)_ | Active/pending checkpoint: read `.codebyplan/state/session/current.json` (fallback MCP `get_current_task`); if none in progress, the most recent `pending` checkpoint with no `plan.steps` from local state |
31
31
 
32
32
  Malformed (non-numeric, contains `-`): surface `checkpoint-plan: invalid argument` and stop.
33
33
 
34
34
  ### Step 1: Load Checkpoint + Existing Tasks
35
35
 
36
- 1. Resolve the checkpoint (Step 0). Load `user_context`, `ideas[]`, `context` (decisions / discoveries / dependencies / constraints / qa_answers / alternatives), `research`, `plan`.
37
- 2. MCP `get_tasks(checkpoint_id)` — load existing tasks. This sets the mode:
36
+ 1. Resolve the checkpoint (Step 0). Read `.codebyplan/state/checkpoints/<id>.json` (local-first; if missing/stale run `npx codebyplan sync` once; break-glass: MCP `get_checkpoints`). Load `user_context`, `ideas[]`, `context` (decisions / discoveries / dependencies / constraints / qa_answers / alternatives), `research`, `plan`.
37
+ 2. Read task files under `.codebyplan/state/checkpoints/<id>/tasks/*.json` (fallback: MCP `get_tasks(checkpoint_id)`) — load existing tasks. This sets the mode:
38
38
  - **fresh** — zero tasks: full plan + create all tasks.
39
39
  - **additive re-plan** — tasks exist: gap-analyse against them; only ADD new tasks or refine requirements for gaps. NEVER delete or overwrite an in-flight task.
40
40
  3. Note whether `worktree_id` is set (claimed at create) — drives routing in Step 11.
@@ -45,7 +45,7 @@ Iterate ALL `ideas[]` (not just the first). For each:
45
45
 
46
46
  1. **Discovery level** — 0 (trivial) · 1 (check existing patterns) · 2 (read docs/APIs) · 3 (unfamiliar territory).
47
47
  2. **Codebase analysis** — Glob/Grep/Read the related code: existing patterns to follow, files that will change, integration points.
48
- 3. **Research (level 2+ only)** — spawn a single `cbp-research` subagent for web/library research. Persist findings to `checkpoint.research` via MCP `update_checkpoint` — never to local docs. In additive re-plan mode, read the existing `research` (loaded in Step 1) and append — do not replace the object.
48
+ 3. **Research (level 2+ only)** — spawn a single `cbp-research` subagent for web/library research. Persist findings to `checkpoint.research` via `codebyplan checkpoint update --id <id> --research <json>` (CLI write-through; break-glass: MCP `update_checkpoint`) — never to local docs. In additive re-plan mode, read the existing `research` (loaded in Step 1) and append — do not replace the object.
49
49
  4. **Cross-reference** ideas against each other: overlaps, conflicts, shared dependencies.
50
50
 
51
51
  Write each idea's analysis into `ideas[N].assessment` (Claude-authored; never touch `description`, which is the user's words).
@@ -90,7 +90,7 @@ Resolve every remaining ambiguity. Ask via AskUserQuestion (max 4 per batch). Af
90
90
 
91
91
  ### Step 8: Generate or Extend `plan.steps[]`
92
92
 
93
- Build an ordered `plan.steps[]` where each step is `{ title, description, scope }` (`scope` = which idea/requirement it addresses). Every `ideas[].requirements` item AND every kept gap finding must be covered by ≥1 step. In additive mode, append/refine steps — do not drop steps that map to existing tasks. Save via MCP `update_checkpoint(checkpoint_id, plan: { steps: [...] })` — `plan` is a top-level checkpoint field, so this write does not touch `context` or `research`; the context-replaces rule in Step 10 applies only to the `context` JSONB.
93
+ Build an ordered `plan.steps[]` where each step is `{ title, description, scope }` (`scope` = which idea/requirement it addresses). Every `ideas[].requirements` item AND every kept gap finding must be covered by ≥1 step. In additive mode, append/refine steps — do not drop steps that map to existing tasks. Save via `codebyplan checkpoint update --id <id> --plan <json>` (CLI write-through; break-glass: MCP `update_checkpoint`) — `plan` is a top-level checkpoint field, so this write does not touch `context` or `research`; the context-replaces rule in Step 10 applies only to the `context` JSONB.
94
94
 
95
95
  ### Step 9: Create Tasks as Vertical Slices
96
96
 
@@ -102,11 +102,11 @@ Each task is a complete, independently shippable vertical slice — group by the
102
102
 
103
103
  Sizing: with a 1M-token context, tasks can be large — group by coherent purpose; a single task touching 30+ files is fine if they serve one theme. Only split when themes are genuinely independent.
104
104
 
105
- For each task use MCP `create_task` (`checkpoint_id`, sequential `number` after the current max, `title`, `requirements`, `context` with the relevant decisions/discoveries). **Additive mode:** create only tasks for steps not already covered by an existing task; never delete in-flight tasks. **Coverage check** — a plan step counts as covered only when an existing task's requirements address its full scope; when uncertain, create the task and note in its requirements `may overlap with TASK-N — review before executing`.
105
+ For each task use `codebyplan task create --checkpoint-id <id> --number <n> --title <title> --requirements <json> --context <json>` (CLI write-through; break-glass: MCP `create_task`). **Additive mode:** create only tasks for steps not already covered by an existing task; never delete in-flight tasks. **Coverage check** — a plan step counts as covered only when an existing task's requirements address its full scope; when uncertain, create the task and note in its requirements `may overlap with TASK-N — review before executing`.
106
106
 
107
107
  ### Step 10: Persist Full Context
108
108
 
109
- Final write of the complete `checkpoint.context` JSONB via MCP `update_checkpoint`. Honor the **context-replaces-not-merges** contract: read the current context, merge your additions in memory, write the FULL object (`decisions` + `discoveries` + `dependencies` + `constraints` + `qa_answers` + `alternatives`). A partial write clobbers sibling keys. Phrase any database-verb words as prose in payloads (WAF gate).
109
+ Final write of the complete `checkpoint.context` JSONB via `codebyplan checkpoint update --id <id> --context <json>` (CLI write-through; break-glass: MCP `update_checkpoint`). Honor the **context-replaces-not-merges** contract: read the current context, merge your additions in memory, write the FULL object (`decisions` + `discoveries` + `dependencies` + `constraints` + `qa_answers` + `alternatives`). A partial write clobbers sibling keys. Phrase any database-verb words as prose in payloads (WAF gate).
110
110
 
111
111
  ### Step 11: Show Result + Route
112
112
 
@@ -129,8 +129,8 @@ This skill does **NOT** activate the checkpoint and does **NOT** claim a user/wo
129
129
 
130
130
  ## Integration
131
131
 
132
- - **Reads**: MCP `get_current_task`, `get_checkpoints`, `get_tasks`
133
- - **Writes**: MCP `update_checkpoint` (ideas assessment, context, plan, research), `create_task`
132
+ - **Reads**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/*.json`, `session/current.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_current_task`, `get_checkpoints`, `get_tasks`)
133
+ - **Writes**: `codebyplan checkpoint update` (ideas assessment, context, plan, research), `codebyplan task create` (break-glass: MCP `update_checkpoint`, `create_task`)
134
134
  - **Spawns**: `cbp-research` (level 2+ only), config-matched `cbp-e2e-*` specialist (opt-in discovery probe, `whole_checkpoint_mode` — see `context/testing/e2e.md` dispatch contract)
135
135
  - **Triggered by**: `/cbp-checkpoint-create` (auto), or user directly
136
136
  - **Triggers**: `/cbp-checkpoint-start` (auto when claimed at create; directive when left open)
@@ -24,14 +24,14 @@ Source `repo_id` from `.codebyplan/repo.json`. Resolve caller worktree once for
24
24
 
25
25
  | Shape | Resolves to |
26
26
  |-------|-------------|
27
- | `{chk}` (e.g. `138`) | CHK-{chk} via MCP `get_checkpoints` filtered by `number` |
28
- | _(empty)_ | The next `pending` checkpoint that already has tasks (planned but not yet started); if several, the lowest-numbered |
27
+ | `{chk}` (e.g. `138`) | CHK-{chk}: scan `.codebyplan/state/checkpoints/*.json` by `number` field (local-first; fallback MCP `get_checkpoints`) |
28
+ | _(empty)_ | The next `pending` checkpoint with tasks in local state (lowest-numbered); fallback MCP `get_checkpoints` |
29
29
 
30
30
  Malformed (non-numeric, contains `-`): surface `checkpoint-start: invalid argument` and stop.
31
31
 
32
32
  ### Step 1: Load Checkpoint + Tasks
33
33
 
34
- Load the checkpoint (`status`, `worktree_id`, `plan`) and its tasks via MCP `get_tasks(checkpoint_id)`.
34
+ Read `.codebyplan/state/checkpoints/<id>.json` for `status`, `worktree_id`, `plan` (local-first; if missing/stale run `npx codebyplan sync` once; break-glass: MCP `get_checkpoints`). Read task files under `.codebyplan/state/checkpoints/<id>/tasks/*.json` (fallback: MCP `get_tasks(checkpoint_id)`).
35
35
 
36
36
  ### Step 2: Planned-Gate
37
37
 
@@ -57,7 +57,7 @@ This mirrors the CHK-104 hard-lock model — never wrest a checkpoint from a liv
57
57
 
58
58
  If the checkpoint is already `active` AND `worktree_id` already equals `CALLER_WT` (the Step 3 no-op row), skip this step entirely and proceed to Step 5 — nothing to write.
59
59
 
60
- Otherwise set the checkpoint `active` via MCP `update_checkpoint(checkpoint_id, status: "active"`, plus `worktree_id: CALLER_WT` when claiming per Step 3. `caller_worktree_id` (CHK-140 TASK-7) identifies the calling worktree and is auto-injected by the `cbp-mcp-caller-worktree-inject.sh` PreToolUse hook (CHK-198 TASK-2); the server falls back to the repo `main` worktree only when it is absent. If the checkpoint was already `active` but a claim is still needed, skip the status write and only write `worktree_id`.
60
+ Otherwise set the checkpoint `active` via `codebyplan checkpoint update --id <checkpoint-id> --status active` (CLI write-through; break-glass: MCP `update_checkpoint`), plus `--worktree-id CALLER_WT` when claiming per Step 3. For MCP break-glass path: `caller_worktree_id` identifies the calling worktree and is auto-injected by the `cbp-mcp-caller-worktree-inject.sh` PreToolUse hook (CHK-198 TASK-2); the server falls back to the repo `main` worktree only when it is absent. If the checkpoint was already `active` but a claim is still needed, skip the status write and only write `worktree_id`.
61
61
 
62
62
  ### Step 5: Route
63
63
 
@@ -77,8 +77,8 @@ Show a one-line confirmation before routing:
77
77
 
78
78
  ## Integration
79
79
 
80
- - **Reads**: MCP `get_checkpoints`, `get_tasks`; `npx codebyplan resolve-worktree`
81
- - **Writes**: MCP `update_checkpoint` (status + worktree_id; `caller_worktree_id` auto-injected by the cbp-mcp-caller-worktree-inject.sh hook, CHK-198 TASK-2; server falls back to repo `main` only when absent)
80
+ - **Reads**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/*.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_checkpoints`, `get_tasks`); `npx codebyplan resolve-worktree`
81
+ - **Writes**: `codebyplan checkpoint update --status active [--worktree-id <id>]` (CLI write-through; break-glass: MCP `update_checkpoint`; `caller_worktree_id` auto-injected by cbp-mcp-caller-worktree-inject.sh hook on the MCP path)
82
82
  - **Triggered by**: `/cbp-checkpoint-plan` (auto when claimed at create), `/cbp-todo` (planned-but-pending gate), or user directly
83
83
  - **Triggers**: `/cbp-task-start` (auto when claimed), or `/cbp-checkpoint-plan` (when the checkpoint is unplanned)
84
84
  - **Never**: plans or creates tasks — that is `/cbp-checkpoint-plan`
@@ -19,7 +19,7 @@ Parse the argument:
19
19
  | Shape | Regex | Resolves to |
20
20
  |-------|-------|-------------|
21
21
  | `{chk}` (e.g. `108`) | `^[0-9]+$` | Target CHK-{chk} |
22
- | _(empty)_ | — | Use MCP `get_current_task` to find the active checkpoint |
22
+ | _(empty)_ | — | Resolve from local state per Step 1.5/2 (MCP `get_current_task` break-glass) the active checkpoint |
23
23
 
24
24
  Anything else is malformed — surface this error and stop:
25
25
 
@@ -42,8 +42,8 @@ Given the parse from Step 0.5:
42
42
 
43
43
  | Parse | Resolution path |
44
44
  |-------|-----------------|
45
- | `{chk}` | MCP `get_checkpoints(repo_id)` filter `number === {chk}` (must exist). |
46
- | _(empty)_ | MCP `get_current_task` with repo_id (and worktree_id resolved via `npx codebyplan resolve-worktree`) to find the active checkpoint. If no active checkpoint, use MCP `get_checkpoints` filtered by `pending` status to find pending ones. |
45
+ | `{chk}` | Scan `.codebyplan/state/checkpoints/*.json` for `number === {chk}` (local-first; if missing/stale run `npx codebyplan sync` once; break-glass: MCP `get_checkpoints`). |
46
+ | _(empty)_ | Read `.codebyplan/state/session/current.json` (with worktree_id from `npx codebyplan resolve-worktree`) to find the active checkpoint (fallback: MCP `get_current_task`). If no active checkpoint, scan local state for `pending` checkpoints (fallback: MCP `get_checkpoints` filtered by `pending`). |
47
47
 
48
48
  ### Step 1.5: Detect Entry Context (from `/cbp-task-complete` expand path)
49
49
 
@@ -76,17 +76,17 @@ When the entry context is "expand from task-complete", `Update context` is the r
76
76
 
77
77
  ### Step 3: Apply Update
78
78
 
79
- Use MCP `update_checkpoint` with the appropriate fields.
79
+ Use `codebyplan checkpoint update --id <checkpoint-id> [--field value ...]` (CLI write-through: updates `.codebyplan/state/checkpoints/<id>.json` + REST; break-glass: MCP `update_checkpoint`).
80
80
 
81
81
  **For activation:**
82
82
  ```
83
- update_checkpoint(checkpoint_id, status: "active")
83
+ codebyplan checkpoint update --id <id> --status active
84
84
  ```
85
85
 
86
86
  **For context updates:**
87
- Read current checkpoint to get existing context, merge new data, then:
87
+ Read current checkpoint from `.codebyplan/state/checkpoints/<id>.json` to get existing context, merge new data, then:
88
88
  ```
89
- update_checkpoint(checkpoint_id, context: merged_context)
89
+ codebyplan checkpoint update --id <id> --context <merged_context_json>
90
90
  ```
91
91
 
92
92
  ### Step 4: Show Result and Route
@@ -110,6 +110,6 @@ Otherwise, no follow-up directive — the user is back in control.
110
110
 
111
111
  ## Integration
112
112
 
113
- - **Reads**: MCP `get_current_task`, `get_checkpoints`
114
- - **Writes**: MCP `update_checkpoint`
113
+ - **Reads**: `.codebyplan/state/session/current.json`, `checkpoints/<id>.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_current_task`, `get_checkpoints`)
114
+ - **Writes**: `codebyplan checkpoint update --id <id> [--field value ...]` (CLI write-through; break-glass: MCP `update_checkpoint`)
115
115
  - **Triggered by**: User directly, OR `/cbp-task-complete` Step 9c (expand path) — see `task-complete/reference/checkpoint-done-branching.md`
@@ -44,7 +44,7 @@ When a scope flag is used:
44
44
  **`--scope-task` Behavior:**
45
45
 
46
46
  When `--scope-task` is used:
47
- 1. Read `task.files_changed[].path` via MCP `get_current_task`
47
+ 1. Read `task.files_changed[].path` from local state `.codebyplan/state/checkpoints/<id>/tasks/<id>.json` (on miss `npx codebyplan sync` once; MCP `get_current_task` as documented break-glass)
48
48
  2. Read currently-staged files via `git diff --cached --name-only`
49
49
  3. Compute intersection — only those paths are committed
50
50
  4. Foreign-staged files (in staged set but NOT in task) remain staged after the commit; user handles them in a separate commit
@@ -108,11 +108,14 @@ REPO_PATH="$(git rev-parse --show-toplevel)"
108
108
 
109
109
  **If `--files` provided:** Use the manual file list.
110
110
 
111
- **If `--scope-task`:** Resolve via MCP + intersection.
111
+ **If `--scope-task`:** Resolve via local state + intersection.
112
112
 
113
113
  ```bash
114
- # 1. Read task.files_changed[]
115
- task_paths=$(mcp get_current_task | jq -r '.files_changed[].path')
114
+ # 1. Read task.files_changed[] from local state (glob for active task file)
115
+ # On miss: npx codebyplan sync once, then re-read.
116
+ # MCP get_current_task as documented break-glass when state dir absent + sync fails.
117
+ task_paths=$(cat .codebyplan/state/checkpoints/*/tasks/*.json 2>/dev/null \
118
+ | jq -r 'select(.status=="in_progress") | .files_changed[].path' | head -n 200)
116
119
  # 2. Read staged paths
117
120
  staged_paths=$(git diff --cached --name-only)
118
121
  # 3. Compute intersection
@@ -263,6 +266,7 @@ Stage the missing files or use --all.
263
266
 
264
267
  ## Integration
265
268
 
269
+ - **Reads (--scope-task)**: Local state task file `.codebyplan/state/checkpoints/*/tasks/*.json` (in_progress); on miss `npx codebyplan sync` once; MCP `get_current_task` as documented break-glass when the state dir is absent and sync fails.
266
270
  - **Called by**: `/cbp-session-end`, `/cbp-task-complete`, `/cbp-checkpoint-complete`, manual
267
271
  - **Scope usage by commands**:
268
272
  - `/cbp-task-complete` -> `--no-push` (commit all staged)
@@ -122,10 +122,7 @@ This check is intentionally placed BEFORE Step 2's `git merge`: catching collisi
122
122
 
123
123
  1. List conflicted files and lock the count: `N=$(git diff --name-only --diff-filter=U | wc -l)`. `N` is the canonical conflict count used by Step 3.5 fallback message and Step 5 output; it stays fixed at the initial value across loop-backs.
124
124
 
125
- 2. Load cross-reference context. Via MCP, gather all active CHK/TASK file ownership:
126
- - `get_checkpoints(repo_id)` filtered to `status IN ('pending', 'active', 'in_progress')`.
127
- - For each active checkpoint, also call `get_tasks(checkpoint_id)` and collect every `task.files_changed[].path` — checkpoint-bound task file ownership lives here, NOT on the checkpoint itself.
128
- - `get_tasks(repo_id, standalone: true)` filtered to `status IN ('pending', 'in_progress')` — adds standalone-task file ownership.
125
+ 2. Load cross-reference context. Read local state files for per-task file ownership: `.codebyplan/state/checkpoints/<id>.json` (filtered to `status IN ('pending', 'active', 'in_progress')`) and `.codebyplan/state/checkpoints/<id>/tasks/*.json` (collect every `task.files_changed[].path`). On miss run `npx codebyplan sync` once and re-read. Use MCP `get_checkpoints` (active-filter multi-checkpoint scan) / `get_tasks` as documented break-glass when the state dir is absent and sync fails — the full cross-checkpoint scan requires MCP when local state is unavailable.
129
126
 
130
127
  Build a map `path -> [referencing CHK-NNN TASK-N + brief context]` by matching each conflicted path against:
131
128
  - `checkpoint.context.files_to_change[]` (checkpoint-level plan)
@@ -221,7 +218,7 @@ Return control to the caller. **This skill NEVER pushes** — the caller decides
221
218
  - `/cbp-task-complete` Step 5.5 (mandatory pre-push, after task commit)
222
219
  - `/cbp-checkpoint-end` Step 0 (mandatory pre-shipment)
223
220
  - User-invocable manually
224
- - **Reads**: `.codebyplan/git.json`, MCP `get_checkpoints`, MCP `get_tasks`, git state
221
+ - **Reads**: `.codebyplan/git.json`, local state `.codebyplan/state/checkpoints/<id>.json` + `.../tasks/<id>.json`; on miss `npx codebyplan sync` once; MCP `get_checkpoints` (active-filter multi-checkpoint scan) / MCP `get_tasks` as documented break-glass when the state dir is absent and sync fails (full cross-checkpoint scan). Git state.
225
222
  - **Writes**: git merge commit (no MCP writes; no remote push)
226
223
  - **Spawns**: none (`/cbp-git-commit` is inline-triggered at Step 0 dirty-tree handling)
227
224
  - **Network**: contacts `origin` via `git fetch`. Offline = abort.
@@ -15,14 +15,14 @@ Inspect the resolved identifier from argument parsing to determine the task kind
15
15
  |-----------------|------|
16
16
  | `{task}-{round}` (2-segment, e.g. `45-2`) | `standalone` |
17
17
  | `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
18
- | _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
18
+ | _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. (Kind-detection is MCP-unavoidable — no identifier yet means no local path to probe; subsequent operations are local-first per the rows below.) |
19
19
 
20
20
  Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
21
21
 
22
22
  | Operation | `checkpoint` KIND | `standalone` KIND |
23
23
  |-----------|------------------|-------------------|
24
- | Get task | `get_current_task(repo_id)` | `get_current_standalone_task(repo_id)` |
25
- | Get rounds | `get_rounds(task_id)` | `get_standalone_rounds(standalone_task_id)` |
24
+ | Get task | local state (break-glass: `get_current_task`) | `get_current_standalone_task(repo_id)` |
25
+ | Get rounds | local state (break-glass: `get_rounds`) | `get_standalone_rounds(standalone_task_id)` |
26
26
  | Add round | `add_round(task_id, ...)` | `add_standalone_round(standalone_task_id, ...)` |
27
27
  | Update round | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_id, ...)` |
28
28
  | Complete round | `complete_round(round_id, duration_minutes?)` | `complete_standalone_round(standalone_round_id, duration_minutes?, caller_worktree_id)` ⚠️ `caller_worktree_id` is REQUIRED for standalone |
@@ -38,8 +38,8 @@ Run automated checks independently with mandatory execution. Updates round QA. H
38
38
 
39
39
  Use Kind Detection above to set KIND. Then:
40
40
 
41
- - **checkpoint KIND**: MCP `get_current_task(repo_id)` to find active task, then `get_rounds(task_id)` to find the in-progress round.
42
- - **standalone KIND**: MCP `get_current_standalone_task(repo_id)` to find active task, then `get_standalone_rounds(standalone_task_id)` to find the in-progress round.
41
+ - **checkpoint KIND**: Read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>.json` (local-first) to find active task, then read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/<roundId>.json` to find the in-progress round. If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_current_task(repo_id)` + `get_rounds(task_id)` when state dir is absent and sync fails.
42
+ - **standalone KIND**: MCP `get_current_standalone_task(repo_id)` to find active task, then `get_standalone_rounds(standalone_task_id)` to find the in-progress round. (Standalone KIND still uses MCP until a later task.)
43
43
 
44
44
  ### Step 2: Determine Project Root
45
45
 
@@ -83,7 +83,9 @@ Scan all captured output for:
83
83
 
84
84
  ### Step 6: Save QA Results
85
85
 
86
- Update round QA via MCP `update_round(round_id, qa: ...)` (checkpoint KIND) or `update_standalone_round(standalone_round_id, qa: ...)` (standalone KIND):
86
+ Update round QA:
87
+ - **checkpoint KIND**: `codebyplan round update --id <round_id> --task-id <task_id> --checkpoint-id <checkpoint_id> --qa '<json>'` (CLI write-through: local state file + REST). Break-glass fallback: MCP `update_round(round_id, qa: ...)` when the CLI is unavailable.
88
+ - **standalone KIND**: MCP `update_standalone_round(standalone_round_id, qa: ...)`. (Standalone KIND still uses MCP until a later task.)
87
89
 
88
90
  ```json
89
91
  {
@@ -123,6 +125,8 @@ If soft failures only: `Run /cbp-round-start to trigger auto-fix, or fix manuall
123
125
 
124
126
  ## Integration
125
127
 
126
- - **Reads**: MCP `get_current_task` / `get_current_standalone_task`, `get_rounds` / `get_standalone_rounds` (per KIND)
127
- - **Writes**: MCP `update_round` / `update_standalone_round` (qa field) per KIND
128
+ - **Reads (checkpoint KIND)**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/<id>.json`, `checkpoints/<id>/tasks/<id>/rounds/<id>.json` (local-first; run `npx codebyplan sync` if missing; break-glass: MCP `get_current_task` / `get_rounds`)
129
+ - **Reads (standalone KIND)**: MCP `get_current_standalone_task` / `get_standalone_rounds` (standalone KIND still uses MCP until a later task)
130
+ - **Writes (checkpoint KIND)**: `codebyplan round update` (qa field). Break-glass: MCP `update_round`.
131
+ - **Writes (standalone KIND)**: MCP `update_standalone_round` (qa field). (Standalone KIND still uses MCP until a later task.)
128
132
  - **Standalone**: Can be run independently at any time
@@ -15,14 +15,14 @@ Inspect the resolved identifier from argument parsing to determine the task kind
15
15
  |-----------------|------|
16
16
  | `{task}-{round}` (2-segment, e.g. `45-2`) | `standalone` |
17
17
  | `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
18
- | _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
18
+ | _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. (Kind-detection is MCP-unavoidable — no identifier yet means no local path to probe; subsequent operations are local-first per the rows below.) |
19
19
 
20
20
  Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
21
21
 
22
22
  | Operation | `checkpoint` KIND | `standalone` KIND |
23
23
  |-----------|------------------|-------------------|
24
- | Get task | `get_current_task(repo_id)` | `get_current_standalone_task(repo_id)` |
25
- | Get rounds | `get_rounds(task_id)` | `get_standalone_rounds(standalone_task_id)` |
24
+ | Get task | local state (break-glass: `get_current_task`) | `get_current_standalone_task(repo_id)` |
25
+ | Get rounds | local state (break-glass: `get_rounds`) | `get_standalone_rounds(standalone_task_id)` |
26
26
  | Update round | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_id, ...)` |
27
27
  | Complete round | `complete_round(round_id, duration_minutes?)` | `complete_standalone_round(standalone_round_id, duration_minutes?, caller_worktree_id)` ⚠️ `caller_worktree_id` is REQUIRED for standalone |
28
28
 
@@ -69,9 +69,9 @@ Given the parse from Step 1:
69
69
 
70
70
  | Parse | Resolution path |
71
71
  |-------|-----------------|
72
- | `{chk}-{task}-{round}` | MCP `get_checkpoints(repo_id)` filter `number === {chk}`. MCP `get_tasks(checkpoint_id)` → filter `number === {task}`. MCP `get_rounds(task_id)` filter `number === {round}`. |
73
- | `{task}-{round}` | MCP `get_standalone_rounds` via `get_current_standalone_task` or direct task lookup → filter `number === {round}`. |
74
- | _(empty)_ | Use Kind Detection: checkpoint KIND → MCP `get_current_task(repo_id)` + `get_rounds(task_id)`; standalone KIND → MCP `get_current_standalone_task(repo_id)` + `get_standalone_rounds(standalone_task_id)`. |
72
+ | `{chk}-{task}-{round}` | **checkpoint KIND** — Read `.codebyplan/state/checkpoints/<checkpointId>.json` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_checkpoints(repo_id)` → `get_tasks` `get_rounds` when state dir is absent and sync fails. Filter by `number` fields to match `{chk}`, `{task}`, `{round}`. |
73
+ | `{task}-{round}` | **standalone KIND** — MCP `get_standalone_rounds` via `get_current_standalone_task` or direct task lookup → filter `number === {round}`. (Standalone KIND still uses MCP until a later task.) |
74
+ | _(empty)_ | Use Kind Detection: **checkpoint KIND**Read `.codebyplan/state/` local files for active task + latest round (break-glass: MCP `get_current_task(repo_id)` + `get_rounds(task_id)`); **standalone KIND** → MCP `get_current_standalone_task(repo_id)` + `get_standalone_rounds(standalone_task_id)`. |
75
75
 
76
76
  If no task found: `No active task. Nothing to complete.`
77
77
 
@@ -108,7 +108,7 @@ This is the **single** explicit reconcile owned by this skill. (The `cbp-mcp-rou
108
108
 
109
109
  Calculate duration from the round's `started_at` to now in minutes.
110
110
 
111
- - **checkpoint KIND**: MCP `complete_round(round_id, duration_minutes)`.
111
+ - **checkpoint KIND**: `codebyplan round complete --id <round_id> --task-id <task_id> --checkpoint-id <checkpoint_id>` (CLI write-through: local state file + REST). Break-glass fallback: MCP `complete_round(round_id, duration_minutes)` when the CLI is unavailable. Note: the CLI does not accept `duration_minutes`; the backend computes duration server-side.
112
112
  - **standalone KIND**: MCP `complete_standalone_round(standalone_round_id, duration_minutes, caller_worktree_id)`. ⚠️ `caller_worktree_id` is REQUIRED — resolve via `CALLER_WT=$(npx codebyplan resolve-worktree 2>/dev/null)`. If `CALLER_WT` is empty, surface this warning and ask the user to confirm before proceeding:
113
113
 
114
114
  ```
@@ -145,7 +145,11 @@ Calculate duration from the round's `started_at` to now in minutes.
145
145
  another round.
146
146
  ```
147
147
 
148
- Persist a breadcrumb on the round via `update_round` / `update_standalone_round` per KIND: `round.context.round_complete = { staged_count, unstaged_count, route, decided_at }`.
148
+ Persist a breadcrumb on the round:
149
+ - **checkpoint KIND**: `codebyplan round update --id <round_id> --task-id <task_id> --checkpoint-id <checkpoint_id> --context '<json>'` (CLI write-through). Break-glass fallback: MCP `update_round(round_id, ...)` when the CLI is unavailable.
150
+ - **standalone KIND**: MCP `update_standalone_round(standalone_round_id, ...)` (standalone KIND still uses MCP until a later task).
151
+
152
+ Payload: `round.context.round_complete = { staged_count, unstaged_count, route, decided_at }`.
149
153
 
150
154
  ## Key Rules
151
155
 
@@ -159,6 +163,8 @@ Persist a breadcrumb on the round via `update_round` / `update_standalone_round`
159
163
 
160
164
  - **Gates**: `ask`-tier `Skill(cbp-round-complete)` permission prompt — the harness confirms before the skill runs; a decline makes NO writes. There is no in-skill AskUserQuestion.
161
165
  - **Triggered by**: `/cbp-round-update` (auto, clean triage), or user manually
162
- - **Reads**: MCP `get_current_task` / `get_current_standalone_task`, `get_rounds` / `get_standalone_rounds` (per KIND); delegates git+approval sync to `npx codebyplan round sync-approvals`
163
- - **Writes**: MCP `complete_round` / `complete_standalone_round` (per KIND); `update_round` / `update_standalone_round` (`round_complete` breadcrumb); round+task `files_changed` written by the CLI
166
+ - **Reads (checkpoint KIND)**: `.codebyplan/state/checkpoints/<id>.json`, `.codebyplan/state/checkpoints/<id>/tasks/<id>.json`, `.codebyplan/state/checkpoints/<id>/tasks/<id>/rounds/<id>.json` (local-first; run `npx codebyplan sync` if missing; break-glass: MCP `get_current_task` / `get_rounds`). Delegates git+approval sync to `npx codebyplan round sync-approvals`.
167
+ - **Reads (standalone KIND)**: MCP `get_current_standalone_task` / `get_standalone_rounds` (standalone KIND still uses MCP until a later task).
168
+ - **Writes (checkpoint KIND)**: `codebyplan round complete` (Step 3); `codebyplan round update` (Step 4 breadcrumb). Break-glass: MCP `complete_round` / `update_round`. Round+task `files_changed` written by the CLI sync-approvals.
169
+ - **Writes (standalone KIND)**: MCP `complete_standalone_round` / `update_standalone_round` (standalone KIND still uses MCP until a later task).
164
170
  - **Triggers**: `/cbp-task-check` (checkpoint KIND, all files approved), `/cbp-standalone-task-check` (standalone KIND, all files approved), `/cbp-round-input` (some files unapproved — fires independent of staging count)
@@ -27,8 +27,9 @@ This skill operates on the **active** task/round resolved via MCP `get_current_t
27
27
 
28
28
  ### Step 1: Get Current Task and Round
29
29
 
30
- Use MCP `get_current_task` with repo_id (pass `checkpoint_id` if known to avoid disambiguation) to find the active task.
31
- Use MCP `get_rounds` for the task to find the in-progress round.
30
+ Read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>.json` (local-first) to find the active task. If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_current_task` when the state dir is absent and sync fails (daemon-dead + CLI-unavailable).
31
+
32
+ Read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/<roundId>.json` (local-first) to find the in-progress round. Same sync / break-glass pattern (MCP `get_rounds` as fallback).
32
33
 
33
34
  Load round context with all outputs (executor_output, testing_qa_output, reviewer_output).
34
35
 
@@ -70,11 +71,9 @@ Merge with previous rounds (supersede items for re-modified files, preserve veri
70
71
 
71
72
  ### Step 4: Update Task Files and QA
72
73
 
73
- Update via MCP:
74
-
75
- - `update_task(task_id, files_changed: [...])` merge with existing
76
- - `update_round(round_id, files_changed: [...], qa: {items: [auto_qa items + default_checklist items]})` — round-specific
77
- - `update_task(task_id, qa: {items: [auto_qa items + default_checklist items]})` — aggregated
74
+ - **Round files + QA**: `codebyplan round update --id <round-id> --task-id <uuid> --checkpoint-id <uuid> --files-changed <json> --qa <json>` (CLI write-through: local state at `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/<roundId>.json` + REST). Break-glass fallback: MCP `update_round` when the CLI is unavailable.
75
+ - **Task files_changed merge**: `codebyplan task update --id <task-id> --checkpoint-id <uuid> --files-changed <json>` (CLI write-through: local state at `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>.json` + REST). Break-glass fallback: MCP `update_task` when the CLI is unavailable.
76
+ - **Task QA aggregated**: `codebyplan task update --id <task-id> --checkpoint-id <uuid> --qa <json>` (same CLI write-through). Break-glass: MCP `update_task`.
78
77
 
79
78
  ### Step 5: Present Summary
80
79
 
@@ -149,7 +148,7 @@ Example tables and the in-scope/out-of-scope classification: see `reference/find
149
148
  Step 7 already auto-applied in-scope findings and logged them to `round.context.inline_fix_log`. Now record any out-of-scope findings and route:
150
149
 
151
150
  1. **Polish-spiral stop-gate** (round 2+ only): if this is round 2 or later AND the prior round also ended with code-review fixes, surface a one-line stop-gate via AskUserQuestion — *defer remaining polish to a follow-up task* vs *continue with another round*. This is a genuine user decision about scope (it guards against endless low-value polish loops), not a flow-control prompt. Skip on round 1.
152
- 2. Save out-of-scope findings (those NOT auto-applied in Step 7) to round context via MCP `update_round`:
151
+ 2. Save out-of-scope findings (those NOT auto-applied in Step 7) to round context via `codebyplan round update --id <round-id> --task-id <uuid> --checkpoint-id <uuid> --context <json>` (break-glass: MCP `update_round`):
153
152
  ```json
154
153
  {
155
154
  "context": {
@@ -169,7 +168,7 @@ Step 7 already auto-applied in-scope findings and logged them to `round.context.
169
168
  ## Integration
170
169
 
171
170
  - **Triggered by**: `/cbp-round-execute` (auto, after all waves + testing complete)
172
- - **Reads**: MCP `get_current_task`, `get_rounds`, round context
173
- - **Writes**: MCP `update_round`, `update_task` (files_changed, qa, findings)
171
+ - **Reads**: `.codebyplan/state/checkpoints/<id>/tasks/<id>.json`, `checkpoints/<id>/tasks/<id>/rounds/<id>.json` (local-first; `npx codebyplan sync` on miss; MCP `get_current_task` / `get_rounds` as break-glass)
172
+ - **Writes**: `codebyplan round update` (Step 4 round files/QA, Step 8 findings; break-glass: MCP `update_round`), `codebyplan task update` (Step 4 files_changed + QA aggregated; break-glass: MCP `update_task`)
174
173
  - **Spawns**: `cbp-improve-round` (code quality review)
175
174
  - **Triggers**: `/cbp-round-update` (auto, after findings handled)
@@ -27,8 +27,9 @@ This skill operates on the **active** task/round resolved via MCP `get_current_t
27
27
 
28
28
  ### Step 1: Get Current Task and Round
29
29
 
30
- Use MCP `get_current_task` with repo_id (pass checkpoint_id if known) to find the active task.
31
- Use MCP `get_rounds` for the task to find the in-progress round.
30
+ Read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>.json` (local-first) to find the active task. If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_current_task` when the state dir is absent and sync fails (daemon-dead + CLI-unavailable).
31
+
32
+ Read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/<roundId>.json` (local-first) to find the in-progress round. Same sync / break-glass pattern (MCP `get_rounds` as fallback).
32
33
 
33
34
  If no in-progress round: `No active round. Run /cbp-round-start first.`
34
35
 
@@ -182,7 +183,7 @@ Per-wave hard-fail signal — true when ANY hold:
182
183
  **All waves hard_fail: false** → proceed to Step 7. **Any wave hard_fail: true**:
183
184
 
184
185
  - **Simple fixes** (type errors, lint, missing imports, test assertion fixes, e2e `real`-category with clear code-side root cause, no prior re-trigger this round) → save failure details to round context; retrigger the failing wave's executor; re-run testing-qa AND the eligible `cbp-e2e-*` specialists for that wave.
185
- - **Structural OR already re-triggered once OR e2e preflight aborts OR `e2e_eligible_skipped`** → save failure context via MCP `update_round`; auto-trigger `/cbp-round-input`. STOP.
186
+ - **Structural OR already re-triggered once OR e2e preflight aborts OR `e2e_eligible_skipped`** → save failure context via `codebyplan round update` (break-glass: MCP `update_round`); auto-trigger `/cbp-round-input`. STOP.
186
187
 
187
188
  ## Inline execution fallback
188
189
 
@@ -194,7 +195,7 @@ When `cbp-testing-qa-agent` spawn fails OR the resolved `testing_profile` is `cl
194
195
 
195
196
  ### Step 7: Save Executor Output
196
197
 
197
- Update round context via MCP `update_round`:
198
+ `codebyplan round update --id <round-id> --task-id <uuid> --checkpoint-id <uuid> --context <json>` (CLI write-through: local state at `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/<roundId>.json` + REST). Break-glass fallback: MCP `update_round` when the CLI is unavailable.
198
199
 
199
200
  - `context`: { ...existing, executor_output, testing_qa_output, e2e_eligible, e2e_outputs, frontend_ui_review }
200
201
 
@@ -220,8 +221,8 @@ Trigger `/cbp-round-end`.
220
221
 
221
222
  ## Integration
222
223
 
223
- - **Reads**: MCP `get_current_task`, `get_rounds`
224
- - **Writes**: MCP `update_round` (context with executor_output + testing_qa_output + e2e_eligible + e2e_outputs + frontend_ui_review)
224
+ - **Reads**: `.codebyplan/state/checkpoints/<id>/tasks/<id>.json`, `checkpoints/<id>/tasks/<id>/rounds/<id>.json` (local-first; `npx codebyplan sync` on miss; MCP `get_current_task` / `get_rounds` as break-glass)
225
+ - **Writes**: `codebyplan round update --id <uuid> --task-id <uuid> --checkpoint-id <uuid>` (Steps 6+7 — context with executor_output + testing_qa_output + e2e_eligible + e2e_outputs + frontend_ui_review; break-glass: MCP `update_round`)
225
226
  - **Spawns**: `cbp-round-executor` (per wave or single), `cbp-testing-qa-agent` (per wave, parallel sibling of the `cbp-e2e-*` specialists), the `cbp-e2e-*` specialists (config-driven dispatch per `context/testing/e2e.md`, one per eligible framework in `.codebyplan/e2e.json`), `cbp-database-agent` (if DB work), `cbp-security-agent` (if security review needed)
226
227
  - **Skill invocations**: `cbp-frontend-ui` at Step 5b with `phase: 'screenshot_review'` (post-e2e)
227
228
  - **Triggers**: `/cbp-round-end` (auto)
@@ -14,14 +14,14 @@ Inspect the resolved identifier from argument parsing to determine the task kind
14
14
  |-----------------|------|
15
15
  | `{task}-{round}` (2-segment, e.g. `45-2`) | `standalone` |
16
16
  | `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
17
- | _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
17
+ | _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. (Kind-detection is MCP-unavoidable — no identifier yet means no local path to probe; subsequent operations are local-first per the rows below.) |
18
18
 
19
19
  Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
20
20
 
21
21
  | Operation | `checkpoint` KIND | `standalone` KIND |
22
22
  |-----------|------------------|-------------------|
23
- | Get task | `get_current_task(repo_id)` | `get_current_standalone_task(repo_id)` |
24
- | Get rounds | `get_rounds(task_id)` | `get_standalone_rounds(standalone_task_id)` |
23
+ | Get task | local state (break-glass: `get_current_task`) | `get_current_standalone_task(repo_id)` |
24
+ | Get rounds | local state (break-glass: `get_rounds`) | `get_standalone_rounds(standalone_task_id)` |
25
25
  | Add round | `add_round(task_id, ...)` | `add_standalone_round(standalone_task_id, ...)` |
26
26
  | Update round | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_id, ...)` |
27
27
  | Update task | `update_task(task_id, ...)` | `update_standalone_task(standalone_task_id, ...)` |
@@ -64,9 +64,13 @@ If the argument matches the numeric regex, resolve the target task/round from DB
64
64
 
65
65
  ### Step 2: Deep Analysis (MANDATORY — always runs)
66
66
 
67
- **2a:** Load task via KIND-appropriate MCP tool (`get_current_task` or `get_current_standalone_task`) — get `files_changed`, `requirements`, `context`, `qa`
67
+ **2a:** Load task:
68
+ - **checkpoint KIND** — Read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>.json` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_current_task(repo_id)` when state dir is absent and sync fails. Get `files_changed`, `requirements`, `context`, `qa`.
69
+ - **standalone KIND** — MCP `get_current_standalone_task(repo_id)`. (Standalone KIND still uses MCP until a later task.)
68
70
 
69
- **2b:** Load all rounds via MCP `get_rounds(task_id)` (checkpoint KIND) or `get_standalone_rounds(standalone_task_id)` (standalone KIND) — get previous round context, testing-qa output
71
+ **2b:** Load all rounds:
72
+ - **checkpoint KIND** — Read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/*.json` (local-first; break-glass: MCP `get_rounds(task_id)`). Get previous round context, testing-qa output.
73
+ - **standalone KIND** — MCP `get_standalone_rounds(standalone_task_id)`.
70
74
 
71
75
  **2c:** Identify unapproved files from `task.files_changed` where `user_approved === false`
72
76
 
@@ -144,10 +148,12 @@ Based on the analysis + user input, create detailed requirements that:
144
148
 
145
149
  If the new round requirements change the task direction:
146
150
 
147
- 1. Update task context via MCP `update_task(task_id, context: { ... })` / `update_standalone_task(standalone_task_id, context: { ... })` per KIND:
151
+ 1. Update task context per KIND:
152
+ - **checkpoint KIND**: `codebyplan task update --id <task_id> --checkpoint-id <checkpoint_id> --context '<json>'` (CLI write-through: local state file + REST). Break-glass fallback: MCP `update_task(task_id, context: { ... })` when the CLI is unavailable.
153
+ - **standalone KIND**: MCP `update_standalone_task(standalone_task_id, context: { ... })`. (Standalone KIND still uses MCP until a later task.)
148
154
  - Add new decisions to `context.decisions[]`
149
155
  - Update `context.discoveries[]` if applicable
150
- 2. If checkpoint-level changes needed (checkpoint KIND only), update checkpoint context via MCP `update_checkpoint`
156
+ 2. If checkpoint-level changes needed (checkpoint KIND only): `codebyplan checkpoint update --id <checkpoint_id> --context '<json>'` (CLI write-through). Break-glass fallback: MCP `update_checkpoint`.
151
157
 
152
158
  ### Step 7: Auto-trigger Round Start
153
159
 
@@ -166,14 +172,18 @@ Trigger `/cbp-round-start` with the round requirements as arguments.
166
172
  If this command is triggered **directly** (not via `/cbp-todo`) and no context is available in the session:
167
173
 
168
174
  1. Read `.codebyplan/repo.json` for `repo_id`
169
- 2. Use Kind Detection to determine KIND, then use the appropriate MCP tool to load checkpoint + task
170
- 3. Use MCP `get_rounds(task_id)` / `get_standalone_rounds(standalone_task_id)` per KIND to load round history
175
+ 2. Use Kind Detection to determine KIND, then:
176
+ - **checkpoint KIND**: Read local `.codebyplan/state/` files for checkpoint + task (break-glass: MCP `get_current_task`).
177
+ - **standalone KIND**: MCP `get_current_standalone_task`.
178
+ 3. Load round history:
179
+ - **checkpoint KIND**: Read `.codebyplan/state/checkpoints/<id>/tasks/<id>/rounds/*.json` (break-glass: MCP `get_rounds(task_id)`).
180
+ - **standalone KIND**: MCP `get_standalone_rounds(standalone_task_id)`.
171
181
  4. Continue from Step 2 (deep analysis handles all context loading)
172
182
 
173
183
  ## Key Rules
174
184
 
175
185
  - **Deep analysis is MANDATORY** — always runs, even if arguments provided (for context)
176
- - **Analysis reads from DB (MCP)**, not conversation history
186
+ - **Analysis reads from local state first**, falling back to MCP only when state files are absent and sync fails
177
187
  - **Follow-up rounds get same depth as round 1** — no quick-fix behavior
178
188
  - **Never ask to git add** — user file approval (git staging) is reconciled by `/cbp-round-complete`
179
189
  - **Update all context locations** — task, checkpoint, and round should all have consistent information
@@ -181,6 +191,8 @@ If this command is triggered **directly** (not via `/cbp-todo`) and no context i
181
191
  ## Integration
182
192
 
183
193
  - **Triggered by**: `/cbp-round-update` (auto, not-clean triage), `/cbp-round-complete` (auto, files left unapproved after completing the round), `/cbp-round-execute` (auto, on hard-fail after retry exhausted), `/cbp-todo` (after /clear), user manually
184
- - **Reads**: MCP `get_current_task` / `get_current_standalone_task`, `get_rounds` / `get_standalone_rounds` (per KIND), file contents (Read tool)
185
- - **Writes**: MCP `update_task` / `update_standalone_task` (context), `update_checkpoint` (context, if checkpoint KIND and needed)
194
+ - **Reads (checkpoint KIND)**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/<id>.json`, `checkpoints/<id>/tasks/<id>/rounds/*.json` (local-first; break-glass: MCP `get_current_task` / `get_rounds`), file contents (Read tool)
195
+ - **Reads (standalone KIND)**: MCP `get_current_standalone_task` / `get_standalone_rounds` (standalone KIND still uses MCP until a later task)
196
+ - **Writes (checkpoint KIND)**: `codebyplan task update` (context), `codebyplan checkpoint update` (context, if needed). Break-glass: MCP `update_task` / `update_checkpoint`.
197
+ - **Writes (standalone KIND)**: MCP `update_standalone_task` / (checkpoint via MCP `update_checkpoint` if needed). (Standalone KIND still uses MCP until a later task.)
186
198
  - **Triggers**: `/cbp-round-start` (auto)