codebyplan 1.13.39 → 1.13.41

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 (86) 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-database-agent.md +15 -4
  5. package/templates/agents/cbp-round-executor.md +2 -10
  6. package/templates/agents/cbp-task-check.md +2 -0
  7. package/templates/agents/cbp-task-planner.md +2 -5
  8. package/templates/hooks/README.md +14 -2
  9. package/templates/hooks/cbp-session-start-hook.sh +32 -0
  10. package/templates/hooks/cbp-test-coverage-gate.sh +20 -6
  11. package/templates/hooks/cbp-test-hooks.sh +72 -0
  12. package/templates/hooks/hooks.json +11 -0
  13. package/templates/hooks/validate-structure-patterns.sh +5 -3
  14. package/templates/hooks/validate-structure.sh +3 -2
  15. package/templates/settings.project.base.json +12 -0
  16. package/templates/skills/cbp-checkpoint-check/SKILL.md +10 -10
  17. package/templates/skills/cbp-checkpoint-complete/SKILL.md +7 -7
  18. package/templates/skills/cbp-checkpoint-create/SKILL.md +11 -9
  19. package/templates/skills/cbp-checkpoint-end/SKILL.md +7 -10
  20. package/templates/skills/cbp-checkpoint-plan/SKILL.md +10 -10
  21. package/templates/skills/cbp-checkpoint-start/SKILL.md +6 -6
  22. package/templates/skills/cbp-checkpoint-update/SKILL.md +9 -9
  23. package/templates/skills/cbp-git-commit/SKILL.md +8 -4
  24. package/templates/skills/cbp-merge-main/SKILL.md +2 -5
  25. package/templates/skills/cbp-round-check/SKILL.md +12 -8
  26. package/templates/skills/cbp-round-complete/SKILL.md +16 -10
  27. package/templates/skills/cbp-round-end/SKILL.md +9 -10
  28. package/templates/skills/cbp-round-execute/SKILL.md +7 -6
  29. package/templates/skills/cbp-round-input/SKILL.md +24 -12
  30. package/templates/skills/cbp-round-start/SKILL.md +36 -16
  31. package/templates/skills/cbp-round-update/SKILL.md +14 -10
  32. package/templates/skills/cbp-session-end/SKILL.md +22 -12
  33. package/templates/skills/cbp-session-start/SKILL.md +20 -47
  34. package/templates/skills/cbp-ship/SKILL.md +4 -4
  35. package/templates/skills/cbp-ship-main/SKILL.md +4 -5
  36. package/templates/skills/cbp-supabase-branch-check/SKILL.md +1 -0
  37. package/templates/skills/cbp-supabase-migrate/SKILL.md +14 -9
  38. package/templates/skills/cbp-supabase-setup/SKILL.md +1 -0
  39. package/templates/skills/cbp-task-check/SKILL.md +10 -10
  40. package/templates/skills/cbp-task-complete/SKILL.md +11 -9
  41. package/templates/skills/cbp-task-create/SKILL.md +7 -5
  42. package/templates/skills/cbp-task-start/SKILL.md +15 -17
  43. package/templates/skills/cbp-task-testing/SKILL.md +18 -18
  44. package/templates/skills/cbp-todo/SKILL.md +21 -21
  45. package/templates/skills/supabase/CHANGELOG.md +35 -0
  46. package/templates/skills/supabase/PROVENANCE.md +50 -0
  47. package/templates/skills/supabase/SKILL.md +136 -0
  48. package/templates/skills/supabase/assets/feedback-issue-template.md +17 -0
  49. package/templates/skills/supabase/references/skill-feedback.md +17 -0
  50. package/templates/skills/supabase-postgres-best-practices/CHANGELOG.md +29 -0
  51. package/templates/skills/supabase-postgres-best-practices/PROVENANCE.md +52 -0
  52. package/templates/skills/supabase-postgres-best-practices/SKILL.md +65 -0
  53. package/templates/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
  54. package/templates/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
  55. package/templates/skills/supabase-postgres-best-practices/references/_template.md +34 -0
  56. package/templates/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
  57. package/templates/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
  58. package/templates/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
  59. package/templates/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
  60. package/templates/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
  61. package/templates/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
  62. package/templates/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
  63. package/templates/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
  64. package/templates/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
  65. package/templates/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
  66. package/templates/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
  67. package/templates/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
  68. package/templates/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
  69. package/templates/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
  70. package/templates/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
  71. package/templates/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
  72. package/templates/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
  73. package/templates/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
  74. package/templates/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
  75. package/templates/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
  76. package/templates/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
  77. package/templates/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
  78. package/templates/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
  79. package/templates/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
  80. package/templates/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
  81. package/templates/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
  82. package/templates/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
  83. package/templates/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
  84. package/templates/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
  85. package/templates/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
  86. package/templates/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
@@ -17,16 +17,18 @@ Inspect the resolved identifier from argument parsing to determine the task kind
17
17
  | `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
18
18
  | _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
19
19
 
20
- Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
20
+ Set `KIND` for the rest of this skill. Read/write sources 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)` |
26
- | Add round | `add_round(task_id, ...)` | `add_standalone_round(standalone_task_id, ...)` |
27
- | Update round | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_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
+ | Add round | `codebyplan round add` (break-glass: `add_round`) | `add_standalone_round(standalone_task_id, ...)` |
27
+ | Update round | `codebyplan round update` (break-glass: `update_round`) | `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 |
29
- | Update task | `update_task(task_id, ...)` | `update_standalone_task(standalone_task_id, ...)` |
29
+ | Update task | `codebyplan task update` (break-glass: `update_task`) | `update_standalone_task(standalone_task_id, ...)` |
30
+
31
+ > **Note**: The `standalone` KIND column uses MCP tools unchanged — standalone local-first migration is out of scope for this task and will be addressed in a later task.
30
32
 
31
33
  # Round Start Command
32
34
 
@@ -94,17 +96,23 @@ round-start: invalid argument `{value}`. Expected:
94
96
 
95
97
  ### Step 1: Get Current Task
96
98
 
97
- If Step 0 produced an identifier (`target_task` set): resolve directly per the identifier (bound or standalone) — use KIND-appropriate MCP tools per the Kind Detection table above.
99
+ If Step 0 produced an identifier (`target_task` set): resolve directly per the identifier (bound or standalone) — use KIND-appropriate sources per the Kind Detection table above.
98
100
 
99
- Otherwise: use Kind Detection to determine KIND, then use MCP `get_current_task` (checkpoint KIND) or `get_current_standalone_task` (standalone KIND) with repo_id to find the active task.
101
+ Otherwise: use Kind Detection to determine KIND, then:
102
+ - **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` when the state dir is absent and sync fails (daemon-dead + CLI-unavailable).
103
+ - **standalone KIND**: MCP `get_current_standalone_task(repo_id)` — standalone tools are NOT migrated this task; standalone KIND still uses MCP until a later task.
100
104
 
101
105
  If no in-progress task and Step 0 produced no identifier, show error: `No active task. Run /cbp-task-start first.`
102
106
 
103
107
  ### Step 2: Determine Round Number
104
108
 
105
- If Step 0 produced `target_round`: use that as the round number directly (may target an existing round for resume, or N+1 for a new round — disambiguate by checking MCP `get_rounds` / `get_standalone_rounds` per KIND).
109
+ If Step 0 produced `target_round`: use that as the round number directly (may target an existing round for resume, or N+1 for a new round — disambiguate by reading local round files or MCP per KIND below).
110
+
111
+ Otherwise:
112
+ - **checkpoint KIND**: list `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_rounds` when the state dir is absent and sync fails.
113
+ - **standalone KIND**: MCP `get_standalone_rounds(standalone_task_id)` — standalone still uses MCP.
106
114
 
107
- Otherwise: use MCP `get_rounds` (checkpoint KIND) or `get_standalone_rounds` (standalone KIND) for the task; count existing rounds; next is N+1.
115
+ Count existing rounds; next is N+1.
108
116
 
109
117
  ### Step 3: Gather Round Requirements
110
118
 
@@ -122,7 +130,11 @@ Otherwise: use MCP `get_rounds` (checkpoint KIND) or `get_standalone_rounds` (st
122
130
 
123
131
  ### Step 4: Create Round in DB
124
132
 
125
- Use MCP `add_round` (checkpoint KIND) or `add_standalone_round` (standalone KIND):
133
+ **checkpoint KIND**: `codebyplan round add --task-id <uuid> --checkpoint-id <uuid> --number <N> --status in_progress --started-at <ISO> --triggered-by <user|claude|auto_loop> [--requirements <text>] [--context <json>]` (CLI write-through: writes local state at `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/<roundId>.json` + REST). Break-glass fallback: MCP `add_round` when the CLI is unavailable.
134
+
135
+ **standalone KIND**: MCP `add_standalone_round(standalone_task_id, ...)` — standalone still uses MCP.
136
+
137
+ Fields to supply:
126
138
  - `task_id` (checkpoint) / `standalone_task_id` (standalone): current task ID
127
139
  - `number`: next round number
128
140
  - `status`: "in_progress"
@@ -138,7 +150,9 @@ Load from checkpoint and task:
138
150
  - Task context and requirements
139
151
  - Resources from checkpoint and task (documentation links, API docs, guides)
140
152
  - Previous round results (files_changed, QA results)
141
- - For round 2+: load the latest completed round's `context.testing_qa_output` and `context.executor_output` via `get_rounds` / `get_standalone_rounds` per KIND
153
+ - For round 2+: load the latest completed round's `context.testing_qa_output` and `context.executor_output`:
154
+ - **checkpoint KIND**: read `.codebyplan/state/checkpoints/<checkpointId>/tasks/<taskId>/rounds/<roundId>.json` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_rounds` when the state dir is absent and sync fails.
155
+ - **standalone KIND**: MCP `get_standalone_rounds(standalone_task_id)` — standalone still uses MCP.
142
156
  - Identify unapproved files from task.files_changed (where user_approved === false)
143
157
 
144
158
  ### Step 6: First Round Analysis (Round 1 only)
@@ -149,7 +163,8 @@ For the first round only:
149
163
  2. Identify any ambiguities or gaps
150
164
  3. If questions are needed, ask user via AskUserQuestion (max 4 per batch)
151
165
  4. If task context changes from Q&A answers:
152
- - Update task context via MCP `update_task(task_id, context: {...})` / `update_standalone_task(standalone_task_id, context: {...})` per KIND
166
+ - **checkpoint KIND**: `codebyplan task update --id <task-id> --checkpoint-id <uuid> --context <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.
167
+ - **standalone KIND**: MCP `update_standalone_task(standalone_task_id, context: {...})` — standalone still uses MCP.
153
168
  - Save Q&A decisions as `context.decisions[]`
154
169
 
155
170
  Skip this step for round 2+ (context already established via `/cbp-round-input`).
@@ -219,7 +234,10 @@ Single-wave plans present the existing flat plan view (no wave table) — backwa
219
234
 
220
235
  ### Step 9: Auto-trigger Round Execute
221
236
 
222
- Save planner output to round context via MCP `update_round` / `update_standalone_round` per KIND, then trigger `/cbp-round-execute`. The `ask`-tier permission prompt on `/cbp-round-execute` is the user's plan approval (see Step 8).
237
+ Save planner output to round context, then trigger `/cbp-round-execute`. The `ask`-tier permission prompt on `/cbp-round-execute` is the user's plan approval (see Step 8).
238
+
239
+ - **checkpoint KIND**: `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.
240
+ - **standalone KIND**: MCP `update_standalone_round(standalone_round_id, ...)` — standalone still uses MCP.
223
241
 
224
242
  ```
225
243
  Starting execution phase...
@@ -235,8 +253,10 @@ Starting execution phase...
235
253
 
236
254
  ## Integration
237
255
 
238
- - **Reads**: MCP `get_current_task` / `get_current_standalone_task`, `get_rounds` / `get_standalone_rounds` (per KIND)
239
- - **Writes**: MCP `add_round` / `add_standalone_round`, `update_round` / `update_standalone_round`, `update_task` / `update_standalone_task` (context only) — per KIND
256
+ - **Reads (checkpoint KIND)**: `.codebyplan/state/checkpoints/<id>.json`, `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)
257
+ - **Reads (standalone KIND)**: MCP `get_current_standalone_task`, `get_standalone_rounds` standalone still uses MCP
258
+ - **Writes (checkpoint KIND)**: `codebyplan round add` (Step 4), `codebyplan round update` (Step 9), `codebyplan task update` (Step 6 context only) — break-glass: MCP `add_round` / `update_round` / `update_task`
259
+ - **Writes (standalone KIND)**: MCP `add_standalone_round`, `update_standalone_round`, `update_standalone_task` — standalone still uses MCP
240
260
  - **Spawns**: `cbp-task-planner`
241
261
  - **Triggers**: `/cbp-round-execute` (auto, on plan approval)
242
262
  - **Triggered by**: `/cbp-task-start` (round 1), `/cbp-round-input` (round 2+)
@@ -17,13 +17,15 @@ Inspect the resolved identifier from argument parsing to determine the task kind
17
17
  | `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
18
18
  | _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
19
19
 
20
- Set `KIND` for the rest of this skill. round-update is **read + triage only** — it reads round state and routes; it never completes the round or writes file approvals. MCP read/audit tool names vary by KIND:
20
+ Set `KIND` for the rest of this skill. round-update is **read + triage only** — it reads round state and routes; it never completes the round or writes file approvals. Read/write sources 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)` |
26
- | Update round (audit only) | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_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
+ | Update round (audit only) | `codebyplan round update` (break-glass: `update_round`) | `update_standalone_round(standalone_round_id, ...)` |
27
+
28
+ > **Note**: The `standalone` KIND column uses MCP tools unchanged — standalone local-first migration is out of scope for this task and will be addressed in a later task.
27
29
 
28
30
  The completion + file-approval reconcile (`sync-approvals`, `complete_round` / `complete_standalone_round`) now lives in `/cbp-round-complete`.
29
31
 
@@ -72,9 +74,9 @@ Given the parse from Step 1:
72
74
 
73
75
  | Parse | Resolution path |
74
76
  |-------|-----------------|
75
- | `{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}`. |
76
- | `{task}-{round}` | MCP `get_standalone_rounds` via `get_current_standalone_task` or direct task lookup → filter `number === {round}`. |
77
- | _(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)`. |
77
+ | `{chk}-{task}-{round}` | Read `.codebyplan/state/checkpoints/` to find the checkpoint where `number === {chk}` (local-first; `npx codebyplan sync` on miss; break-glass: MCP `get_checkpoints(repo_id)`). Read `checkpoints/<id>/tasks/<taskId>.json` to find task where `number === {task}` (break-glass: MCP `get_tasks`). Read `checkpoints/<id>/tasks/<id>/rounds/<roundId>.json` to find round where `number === {round}` (break-glass: MCP `get_rounds`). |
78
+ | `{task}-{round}` | MCP `get_standalone_rounds` via `get_current_standalone_task` or direct task lookup → filter `number === {round}`. Standalone still uses MCP. |
79
+ | _(empty)_ | checkpoint KIND → read `.codebyplan/state/checkpoints/<id>/tasks/<id>.json` (local-first; sync on miss; break-glass: MCP `get_current_task` + `get_rounds`); standalone KIND → MCP `get_current_standalone_task(repo_id)` + `get_standalone_rounds(standalone_task_id)` — standalone still uses MCP. |
78
80
 
79
81
  If no task found: `No active task. Nothing to update.`
80
82
 
@@ -97,7 +99,7 @@ Display a one-line triage summary, e.g. `"ROUND-N triage: clean"` or `"ROUND-N t
97
99
 
98
100
  - **Auto-loop** (`round.context.auto_loop_mode === true`): compute `next_index = (round.context.auto_loop_index ?? 0) + 1`.
99
101
  - If `next_index > (round.context.auto_loop_cap ?? 5)`: surface the cap-exhausted prompt via AskUserQuestion (a genuine multi-option user decision — keep it). Options: extend cap, stop loop / drop into round-input, close task as-is. Persist `round.context.auto_loop_cap_exhausted = { user_choice, decided_at }` and route per choice.
100
- - Otherwise: persist `round.context.auto_loop_decision = { spawned_next: true, next_index, decided_at }` on the current round via `update_round` / `update_standalone_round` (audit trail), then auto-trigger `/cbp-round-input` with NO prompt. Pass `auto_loop_mode: true`, `auto_loop_index: next_index`, `auto_loop_cap: (prior cap ?? 5)` forward — round-start Step 4 persists them on the new round.
102
+ - Otherwise: persist `round.context.auto_loop_decision = { spawned_next: true, next_index, decided_at }` on the current round (audit trail) — **checkpoint KIND**: `codebyplan round update --id <round-id> --task-id <uuid> --checkpoint-id <uuid> --context <json>` (break-glass: MCP `update_round`); **standalone KIND**: MCP `update_standalone_round(standalone_round_id, ...)` standalone still uses MCP. Then auto-trigger `/cbp-round-input` with NO prompt. Pass `auto_loop_mode: true`, `auto_loop_index: next_index`, `auto_loop_cap: (prior cap ?? 5)` forward — round-start Step 4 persists them on the new round.
101
103
  - **Manual round**: auto-trigger `/cbp-round-input` directly (no prompt).
102
104
 
103
105
  ## Key Rules
@@ -111,6 +113,8 @@ Display a one-line triage summary, e.g. `"ROUND-N triage: clean"` or `"ROUND-N t
111
113
  ## Integration
112
114
 
113
115
  - **Triggered by**: `/cbp-round-end` (auto), or user manually
114
- - **Reads**: MCP `get_current_task` / `get_current_standalone_task`, `get_rounds` / `get_standalone_rounds` (per KIND); round context (`testing_qa_output`, `improve_round_findings`, `round_type`, `files_changed[].claude_approved`)
115
- - **Writes**: MCP `update_round` / `update_standalone_round` — audit only (`auto_loop_decision` / `auto_loop_cap_exhausted`). No completion, no file-approval writes.
116
+ - **Reads (checkpoint KIND)**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/<id>.json`, `checkpoints/<id>/tasks/<id>/rounds/<id>.json` (local-first; `npx codebyplan sync` on miss; MCP `get_current_task` / `get_checkpoints` / `get_tasks` / `get_rounds` as break-glass)
117
+ - **Reads (standalone KIND)**: MCP `get_current_standalone_task`, `get_standalone_rounds` — standalone still uses MCP
118
+ - **Writes (checkpoint KIND)**: `codebyplan round update` — audit only (`auto_loop_decision` / `auto_loop_cap_exhausted`; break-glass: MCP `update_round`). No completion, no file-approval writes.
119
+ - **Writes (standalone KIND)**: MCP `update_standalone_round` — audit only — standalone still uses MCP
116
120
  - **Triggers**: `/cbp-round-complete` (clean triage — `ask`-tier permission prompt is the user confirmation), `/cbp-round-input` (not-clean triage: outstanding findings, hard-fail, or unapproved Claude checks — fires independent of git staging; also the auto-loop dirty spawn), cap-exhausted prompt routes from Step 3b (any of the three options)
@@ -17,17 +17,17 @@ Always write a session log for this session — **even if empty**. `/cbp-session
17
17
 
18
18
  1. Resolve the current session log:
19
19
  - Preferred: use the log ID held in context from `/cbp-session-start`.
20
- - Fallback: MCP `get_session_logs` (limit 1, most recent open log for this `repo_id`).
21
- - If still none found (e.g. session-start was skipped), create one now with MCP `create_session_log`.
22
- 2. Pull facts from the DB rather than narrating from memory:
23
- - Rounds added/completed, tasks advanced/completed during this session
20
+ - Fallback: read `.codebyplan/state/session/current.json` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_session_logs` (limit 1, most recent open log for this `repo_id`) when the state dir is absent and sync fails.
21
+ - If still none found (e.g. session-start was skipped), create one now with `codebyplan session create-log` (break-glass: MCP `create_session_log`).
22
+ 2. Pull facts from local state files rather than narrating from memory:
23
+ - Rounds added/completed, tasks advanced/completed during this session (read from `.codebyplan/state/checkpoints/` subtree)
24
24
  - Decisions, blockers, or discoveries recorded in checkpoint/task context
25
25
 
26
26
  ### Step 1.3: Capture Handoff Snapshot
27
27
 
28
28
  Snapshot the current next-action so the next `/cbp-session-start` (Step 4.5) can auto-resume. The handoff write-path + payload shape are specified inline here and in `/cbp-session-start` Step 4.5 (freshness gate).
29
29
 
30
- 1. Call MCP `get_todos({ repo_id, worktree_id })` and take the queue head `rows[0]` (rows are ordered by `sort_order`; `rows[0]` is the current next-action). The worker stamps `command`, `instructions`, `state`, and the entity ids `checkpoint_id` / `task_id` / `round_id` on every row.
30
+ 1. Read `.codebyplan/state/todos.json` (local-first) and take the queue head `rows[0]` (rows are ordered by `sort_order`; `rows[0]` is the current next-action). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_todos({ repo_id, worktree_id })` when the state dir is absent and sync fails. The worker stamps `command`, `instructions`, `state`, and the entity ids `checkpoint_id` / `task_id` / `round_id` on every row.
31
31
  2. If `rows[0]` exists and its `command` is non-empty (active work in flight):
32
32
  ```yaml
33
33
  handoff:
@@ -46,7 +46,7 @@ Snapshot the current next-action so the next `/cbp-session-start` (Step 4.5) can
46
46
 
47
47
  Continuing Step 1:
48
48
 
49
- 3. Use MCP `update_session_log` to finalize:
49
+ 3. Run `codebyplan session update-log --id <log-id> --ended-at <now> --summary <text> --pending <text> --handoff <json>` (CLI write-through: updates `.codebyplan/state/session/current.json` + REST). Break-glass fallback: MCP `update_session_log` when the CLI is unavailable. Fields:
50
50
  - `ended_at`: now (maps to the `closed_at` column per TASK-2 alias)
51
51
  - `handoff`: from Step 1.3 (jsonb or `null`; MCP write surface aliases to the `content` column transparently per CHK-111 Migration A — `handoff` wins over `content` when both are passed)
52
52
  - `summary`: concise — may be empty if nothing happened
@@ -58,12 +58,12 @@ Same rule as `/cbp-session-start` Step 5.7 — only commit files that are **not*
58
58
 
59
59
  1. `git status --porcelain` — list all modified/untracked files. If empty → skip this step.
60
60
  2. Resolve **task-related files** (leave these uncommitted):
61
- - MCP `get_current_task(repo_id)` active task
62
- - If active task exists: MCP `get_rounds(task_id)`, filter to rounds with status not in `completed` / `cancelled`
61
+ - Read `.codebyplan/state/todos.json` (local-first; reuse result from Step 1.3 if already fetched) to identify the active task id. Break-glass fallback: MCP `get_current_task(repo_id)` when the state dir is absent and sync fails.
62
+ - If active task exists: read `.codebyplan/state/checkpoints/<checkpoint_id>/tasks/<task_id>/rounds/` directory and filter to rounds with status not in `completed` / `cancelled`. Break-glass fallback: MCP `get_rounds(task_id)`.
63
63
  - Collect `files[]` from those rounds → `task_files` set
64
64
  - If no active task exists, `task_files` is empty
65
65
  3. `infra_files = changed_files − task_files`
66
- 4. Re-run `git status --porcelain` immediately before showing the commit-prompt (after Steps 1–1.3 have completed their MCP round-trips). Recompute `infra_files` from the fresh listing — eliminates the race where files appear in the index only after the network round-trips complete.
66
+ 4. Re-run `git status --porcelain` immediately before showing the commit-prompt (after Steps 1–1.3 have completed their round-trips). Recompute `infra_files` from the fresh listing — eliminates the race where files appear in the index only after network round-trips complete.
67
67
  5. If `infra_files` is empty → skip. Otherwise present once:
68
68
 
69
69
  ```
@@ -145,9 +145,19 @@ Non-blocking — session end proceeds regardless of outcome.
145
145
 
146
146
  Non-blocking — if kill fails, warn and continue. Silent when no process found.
147
147
 
148
+ ### Step 2.5: Stop Watch Daemon
149
+
150
+ Stop this worktree's Realtime watch daemon, non-blocking and non-fatal:
151
+
152
+ ```bash
153
+ npx codebyplan watch stop 2>/dev/null || true
154
+ ```
155
+
156
+ This SIGTERMs the per-worktree pidfile daemon started by `cbp-session-start-hook.sh`. Silently ignored when no daemon is running for this worktree. If there is no daemon to stop (e.g. session-start was skipped), `watch stop` itself exits 0 — the `|| true` guard is defense-in-depth only, so Step 3's session-state write never sees a failure from this step.
157
+
148
158
  ### Step 3: Update Session State
149
159
 
150
- Use MCP `update_session_state` with action `deactivate`.
160
+ Run `codebyplan session update-state --action deactivate` (CLI write-through: writes `.codebyplan/state/session/state.json` + REST). Break-glass fallback: MCP `update_session_state` with action `deactivate` when the CLI is unavailable. Note: the CLI validates `--action` — only `activate`/`deactivate` are accepted; a missing, valueless, or invalid value exits 1 with a usage message.
151
161
 
152
162
  ### Step 4: Output
153
163
 
@@ -160,8 +170,8 @@ You can close this window.
160
170
  ## Integration
161
171
 
162
172
  - **Triggered by**: user invocation (prompted by `/cbp-todo` when no work remains)
163
- - **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.6 home-branch fast-forward), MCP `get_session_logs` (resolve current log), MCP `get_current_task`, MCP `get_rounds`, MCP `get_todos` (Step 1.3 handoff snapshot queue head `rows[0]`); `npx codebyplan version-status` (Step 1.7 package-freshness gate)
164
- - **Writes**: MCP `update_session_log` (with `ended_at` + `handoff` per TASK-2 alias surface; or `create_session_log` fallback), MCP `update_session_state` (deactivate)
173
+ - **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.6 home-branch fast-forward); local-first reads (with `npx codebyplan sync` + MCP break-glass): `.codebyplan/state/session/current.json` (Step 1 resolve log), `.codebyplan/state/todos.json` (Step 1.3 handoff snapshot + Step 1.5 active-task lookup), `.codebyplan/state/checkpoints/<id>/tasks/<id>/rounds/` (Step 1.5 task-file resolution); `npx codebyplan version-status` (Step 1.7 package-freshness gate)
174
+ - **Writes**: `codebyplan session update-log --id <id> ...` (Step 1 finalize — CLI write-through to `.codebyplan/state/session/current.json`; break-glass: MCP `update_session_log`), `codebyplan session create-log` (Step 1 fallback when no log exists; break-glass: MCP `create_session_log`), `codebyplan session update-state --action deactivate` (Step 3 — CLI write-through to `.codebyplan/state/session/state.json`; break-glass: MCP `update_session_state`)
165
175
  - **Spawns**: none
166
176
  - **Triggers**: none at the skill-contract level. Step 1.5 may invoke `/cbp-git-commit` inline on user approval; Step 1.7 may invoke `/cbp-git-commit` on the `newer:true AND guarded:false` update path (committing changed `.claude/` and `.codebyplan/` paths).
167
177
  - **Paired with**: `/cbp-session-start`
@@ -12,7 +12,7 @@ Activate the session, open a fresh session log, and surface the previous log's p
12
12
 
13
13
  ## Instructions
14
14
 
15
- Run Steps 0 through 5.8 silently (no intermediate output) — except Step 0 aborts the session on MCP failure, Step 1.4 may surface a one-line fast-forward note or warning, Step 1.5 may surface a one-line infra-drift nudge, Step 1.55 may surface a one-line architecture-map drift nudge, Step 1.6 may run an install-and-halt path, Step 1.7 may surface a one-line LSP binary nudge, Step 4.5 may auto-resume a handoff and exit session-start entirely (no Step 6 output), and Step 5.7 may surface an approval gate. (Step numbers are organizational labels; execution order is 0 → 1 → 1.4 → 1.5 → 1.55 → 1.6 → 1.7 → 3 → 4 → 4.5 → 5 → 5.7 → 5.8 → 6 → 7.) Produce ONE output block at Step 6, then auto-trigger or stop per Step 7.
15
+ Run Steps 0 through 5.8 silently (no intermediate output) — except Step 0 aborts the session on MCP failure, Step 1.4 may surface a one-line fast-forward note or warning, Step 1.5 may surface a one-line infra-drift nudge, Step 1.6 may run an install-and-halt path, Step 1.7 may surface a one-line LSP binary nudge, Step 4.5 may auto-resume a handoff and exit session-start entirely (no Step 6 output), and Step 5.7 may surface an approval gate. (Step numbers are organizational labels; execution order is 0 → 1 → 1.4 → 1.5 → 1.6 → 1.7 → 3 → 4 → 4.5 → 5 → 5.7 → 5.8 → 6 → 7.) Produce ONE output block at Step 6, then auto-trigger or stop per Step 7.
16
16
 
17
17
  ### Step 0: MCP Health Gate
18
18
 
@@ -91,34 +91,6 @@ Surface — never block — when this worktree's source-monorepo `.claude/` infr
91
91
 
92
92
  Fully non-blocking; every failure path falls through with no output.
93
93
 
94
- ### Step 1.55: Architecture-Map Drift Check
95
-
96
- Surface — never block — when this repo's generated `.claude/architecture/` maps have
97
- gone stale (a mapped module's source was committed past the SHA stamped in
98
- `.codebyplan/architecture.json`). Runs after the infra-drift check (Step 1.5) and may add
99
- one line to the Step 6 output. This is the freshness nudge for the architecture-map
100
- pipeline (mirrors the infra-drift pattern; the analog for first-party code maps):
101
-
102
- - **No manifest** — `.codebyplan/architecture.json` absent → skip silently (the repo has
103
- no maps yet; nothing to drift-check).
104
- - **Manifest present** — run the drift probe best-effort and count drifted modules:
105
-
106
- ```bash
107
- npx codebyplan arch-map drift 2>/dev/null | grep -c '^[[:space:]]*DRIFTED' || true
108
- ```
109
-
110
- If the count is `> 0`, hold this single line for Step 6:
111
-
112
- ```
113
- ⚠ .claude/architecture is N module(s) stale — run /cbp-refresh-arch-map
114
- ```
115
-
116
- A count of `0` (all maps fresh, no stamped modules, or any probe failure) emits nothing.
117
-
118
- Fully non-blocking; every failure path falls through with no output. The `arch-map` CLI is
119
- itself hook-safe (exits 0 on any internal error), so a missing or too-old `codebyplan`
120
- binary simply yields a zero count and no line.
121
-
122
94
  ### Step 1.6: Package Freshness Gate
123
95
 
124
96
  Check whether a newer `codebyplan` is published and safe to auto-install on this worktree's current branch. Runs AFTER the infra-drift check (Step 1.5) and BEFORE session activation (Step 3).
@@ -170,18 +142,22 @@ LSP_NUDGE=$(npx codebyplan lsp --check 2>/dev/null || true)
170
142
 
171
143
  ### Step 3: Update Session State
172
144
 
173
- Use MCP `update_session_state` with action `activate`. This deactivates all other repos automatically.
145
+ Run `codebyplan session update-state --action activate` (CLI write-through: writes `.codebyplan/state/session/state.json` + REST). This deactivates all other repos automatically. Break-glass fallback: MCP `update_session_state` with action `activate` when the CLI is unavailable. Note: the CLI validates `--action` — only `activate`/`deactivate` are accepted; a missing, valueless, or invalid value exits 1 with a usage message.
146
+
147
+ Note: Step 0 `health_check` stays MCP unconditionally — it tests MCP connectivity itself and must not be replaced.
174
148
 
175
149
  ### Step 4: Read Last Session Log
176
150
 
177
- Call MCP `get_session_logs({ repo_id, worktree_id, limit: 1 })` same inclusive-worktree call shape used by Step 4.5 below so the previous-session display and the handoff probe agree on which row is "most recent for this worktree". Take the first (and only) row.
151
+ Read `.codebyplan/state/session/current.json` (local-first). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_session_logs({ repo_id, worktree_id, limit: 1 })` when the state dir is absent and sync fails (daemon-dead + CLI-unavailable).
152
+
153
+ Take the first row — same inclusive-worktree scope as Step 4.5 so the previous-session display and the handoff probe agree on which row is "most recent for this worktree".
178
154
 
179
155
  - If a previous log exists, hold its title/summary/pending items for the Step 6 output so the user sees where they left off.
180
156
  - If none exists (first session ever for this worktree), skip silently.
181
157
 
182
158
  ### Step 5: Create This Session's Log
183
159
 
184
- Use MCP `create_session_log` to open a new session log for the current session. Create it **even if empty** — this establishes the record for session-end to finalize.
160
+ Run `codebyplan session create-log --started-at <now> --repo-id <repo_id> --worktree-id <WORKTREE_ID>` (CLI write-through: writes `.codebyplan/state/session/current.json` + REST). Create it **even if empty** — this establishes the record for session-end to finalize. Break-glass fallback: MCP `create_session_log` when the CLI is unavailable.
185
161
 
186
162
  Minimal seed content:
187
163
 
@@ -195,7 +171,7 @@ Hold the new log's ID in context so `/cbp-session-end` can update the same recor
195
171
 
196
172
  Probe the most-recent closed session log for a structured handoff payload (the handoff freshness-gate contract is specified inline in this step) and auto-resume directly into the captured command when fresh. Additive — placed BEFORE the existing `/cbp-todo` auto-trigger; ALL failure paths fall through silently to Step 7.
197
173
 
198
- 1. Reuse the row held from Step 4 (same `get_session_logs({ repo_id, worktree_id, limit: 1 })` call shape no extra MCP round-trip).
174
+ 1. Reuse the row held from Step 4 (held from Step 4 in memory — do NOT re-read from disk here; at this point `session/current.json` still holds the previous session row, which Step 5 will overwrite).
199
175
  2. **Defensive gates** (any failure → silent fall-through to Step 7):
200
176
  - No row returned → fall through.
201
177
  - Row missing `closed_at` (orphan / still-open session) → fall through.
@@ -203,12 +179,12 @@ Probe the most-recent closed session log for a structured handoff payload (the h
203
179
  - `row.content` exists but parse throws or shape mismatch (`command` field absent OR is an empty string) → fall through.
204
180
  3. **Freshness gate** — load the row as `handoff = row.content` (per CHK-111 Migration A column alias). Mark stale when ANY of:
205
181
  - `(now - row.closed_at) > freshness_window_hours` (read from `.codebyplan/repo.json`, default 24 hours)
206
- - Referenced entity in `handoff.context` has shifted. For each id present, run the matching MCP read and find the row whose `id` matches:
207
- - `checkpoint_id` → `get_checkpoints({ repo_id })` find entry where `entry.id === handoff.context.checkpoint_id`
208
- - `task_id` → `get_tasks({ checkpoint_id })` if `handoff.context.checkpoint_id` is present, else `get_tasks({ repo_id, standalone: true })` → find entry where `entry.id === handoff.context.task_id`
209
- - `round_id` → `get_rounds({ task_id: handoff.context.task_id })` find entry where `entry.id === handoff.context.round_id`
182
+ - Referenced entity in `handoff.context` has shifted. For each id present, read the matching local state file and check `updated_at`:
183
+ - `checkpoint_id` → read `.codebyplan/state/checkpoints/<checkpoint_id>.json` (local-first; sync + MCP break-glass if missing)
184
+ - `task_id` → read `.codebyplan/state/checkpoints/<checkpoint_id>/tasks/<task_id>.json` (local-first; sync + MCP break-glass if missing)
185
+ - `round_id` → read `.codebyplan/state/checkpoints/<checkpoint_id>/tasks/<task_id>/rounds/<round_id>.json` (local-first; sync + MCP break-glass if missing)
210
186
  Then compare `entry.updated_at > handoff.captured_at` → stale on any inequality.
211
- - Entity lookup fails OR the matching `id` is not present in the returned array → stale (referenced entity gone or moved out of reach).
187
+ - Local file missing after sync attempt → stale (referenced entity gone or moved out of reach).
212
188
  - `handoff.context.checkpoint_id` resolves to a checkpoint whose `worktree_id` is non-null AND (caller `WORKTREE_ID` is `null` OR differs from `checkpoint.worktree_id`) → stale (a fresh handoff for another worktree's work — or for assigned work this caller cannot confirm ownership of — must not auto-resume here). Mirrors the cbp-todo Step 1.5 ownership rule.
213
189
  4. **On stale OR any defensive gate hit**: fall through silently to Step 7 (existing `/cbp-todo` trigger).
214
190
  5. **On fresh hit**: trigger `handoff.command` directly with `handoff.context` / `handoff.state` in the trigger arguments. The downstream skill self-loads its full context — do NOT duplicate `/cbp-todo` Step 2's context-loading matrix here. Skip Step 5.7, Step 6 output, and Step 7.
@@ -219,12 +195,12 @@ Clean the working tree of leftover infra before the session begins. Only commit
219
195
 
220
196
  1. `git status --porcelain` — list all modified/untracked files. If empty → skip this step.
221
197
  2. Resolve **task-related files** (leave these uncommitted):
222
- - MCP `get_current_task(repo_id)` active task
223
- - If active task exists: MCP `get_rounds(task_id)`, filter to rounds with status not in `completed` / `cancelled`
198
+ - Read `.codebyplan/state/todos.json` (local-first) to identify the active task id. If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_current_task(repo_id)` when the state dir is absent and sync fails.
199
+ - If active task exists: read `.codebyplan/state/checkpoints/<checkpoint_id>/tasks/<task_id>/rounds/` directory and filter to rounds with status not in `completed` / `cancelled`. Break-glass fallback: MCP `get_rounds(task_id)`.
224
200
  - Collect `files[]` from those rounds → `task_files` set
225
201
  - If no active task exists, `task_files` is empty
226
202
  3. `infra_files = changed_files − task_files`
227
- 4. **Re-run `git status --porcelain` immediately before showing the commit-prompt** (after Steps 0–5 have completed all MCP round-trips). Eliminates the race where prior-session staged files appear in the index only after MCP init's network round-trips complete. Recompute `infra_files` from the fresh listing.
203
+ 4. **Re-run `git status --porcelain` immediately before showing the commit-prompt** (after Steps 0–5 have completed all their round-trips). Eliminates the race where prior-session staged files appear in the index only after network round-trips complete. Recompute `infra_files` from the fresh listing.
228
204
  5. If `infra_files` is empty → skip. Otherwise present once:
229
205
 
230
206
  ```
@@ -241,7 +217,7 @@ Non-blocking — session start proceeds either way.
241
217
 
242
218
  ### Step 5.8: Resolve Ownership
243
219
 
244
- Call MCP `get_checkpoints({ repo_id, status: 'active' })`. Partition results into:
220
+ Call MCP `get_checkpoints({ repo_id, status: 'active' })` (MCP only — deliberate: the active-filter query has no local-mirror equivalent). Partition results into:
245
221
 
246
222
  - `owned[]` — entries where `checkpoint.worktree_id === WORKTREE_ID`, OR both are `null`
247
223
  - `cross_worktree[]` — entries where `checkpoint.worktree_id` is non-null AND differs from `WORKTREE_ID` (includes the case where caller `WORKTREE_ID` is `null` but the target has a non-null `worktree_id`)
@@ -255,9 +231,6 @@ Session active | Worktree: [worktree_id or "unregistered"]
255
231
 
256
232
  [⚠ resolve-worktree: <error_kind> — local state is broken; routing may be unreliable. Run `npx codebyplan setup` to repair. — only when error_kind is non-null and not tuple_miss]
257
233
 
258
- [⚠ .claude/ infra is N behind — run /cbp-refresh-infra — only when Step 1.5 found drift]
259
- [⚠ .claude/architecture is N module(s) stale — run /cbp-refresh-arch-map — only when Step 1.55 found drift]
260
-
261
234
  Previous session: [title or "none"]
262
235
  Pending: [pending items from previous log, or "—"]
263
236
 
@@ -284,8 +257,8 @@ Three-branch gate using `owned_count` and `total_count` from Step 5.8:
284
257
 
285
258
  - **Triggered by**: user invocation, `/clear` recovery
286
259
  - **Resolves**: `npx codebyplan resolve-worktree --json` (worktree id + distress signal; non-tuple-miss distress is non-blocking at session-start)
287
- - **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.4 home-branch fast-forward), MCP `get_session_logs` (worktree-filtered, limit 1single call shared by Step 4 and Step 4.5), MCP `health_check` (Step 0 hard gate), MCP `get_current_task`, MCP `get_rounds`, MCP `get_checkpoints` (two calls: `{ repo_id, status: 'active' }` for the Step 5.8 ownership partition; `{ repo_id }` unfiltered for the Step 4.5 freshness probe, which may resolve a non-active checkpoint), MCP `get_tasks` / `get_rounds` for the Step 4.5 freshness probe; `scripts/infra-drift.mjs` + a best-effort `git fetch` (Step 1.5 monorepo drift); `npx codebyplan arch-map drift` + `.codebyplan/architecture.json` presence (Step 1.55 architecture-map drift nudge, non-blocking); `npx codebyplan version-status` (Step 1.6 package-freshness gate); `npx codebyplan lsp --check` (Step 1.7 LSP binary nudge — reads `.codebyplan/lsp.json`, non-blocking). Reads at Step 3 and later (session-state, session logs, checkpoints, tasks/rounds) do NOT fire on a Step 0 MCP hard-fail or the Step 1.6 update-and-halt path
288
- - **Writes**: MCP `create_session_log` (new, possibly empty), MCP `update_session_state` (activate) — both SKIPPED on a Step 0 MCP hard-fail and on the Step 1.6 update-and-halt path
260
+ - **Reads**: `.codebyplan/repo.json`, `.codebyplan/git.json` (`branch_config.production` for the Step 1.4 home-branch fast-forward), MCP `health_check` (Step 0 hard gate stays MCP unconditionally); local-first reads (with `npx codebyplan sync` + MCP break-glass): `.codebyplan/state/session/current.json` (Step 4 previous log + Step 4.5 handoff probe), `.codebyplan/state/checkpoints/<id>.json` / `tasks/<id>.json` / `rounds/<id>.json` (Step 4.5 freshness probe), `.codebyplan/state/todos.json` (Step 5.7 active-task lookup); MCP `get_checkpoints({ repo_id, status: 'active' })` (Step 5.8 ownership partition MCP only, no local mirror for active-filter query); `scripts/infra-drift.mjs` + a best-effort `git fetch` (Step 1.5 monorepo drift); `npx codebyplan version-status` (Step 1.6 package-freshness gate); `npx codebyplan lsp --check` (Step 1.7 LSP binary nudge — reads `.codebyplan/lsp.json`, non-blocking). Reads at Step 3 and later do NOT fire on a Step 0 MCP hard-fail or the Step 1.6 update-and-halt path
261
+ - **Writes**: `codebyplan session create-log` (Step 5 — CLI write-through; break-glass: MCP `create_session_log`), `codebyplan session update-state --action activate` (Step 3 CLI write-through to `.codebyplan/state/session/state.json`; break-glass: MCP `update_session_state`) — both SKIPPED on a Step 0 MCP hard-fail and on the Step 1.6 update-and-halt path
289
262
  - **Spawns**: none
290
263
  - **Triggers**: `/cbp-git-commit` (conditional, on user approval at Step 5.7 or the Step 1.6 update path), `handoff.command` (on fresh handoff hit at Step 4.5), `/cbp-todo` (auto fall-through when owned_count >= 1 or total_count === 0; STOPS with no trigger when total_count >= 1 AND owned_count === 0; NOT triggered on a Step 0 hard-fail or the Step 1.6 update-and-halt path)
291
264
  - **Paired with**: `/cbp-session-end`
@@ -21,7 +21,7 @@ Step 1 of `/cbp-checkpoint-end` handles branch promotion to main via `/cbp-ship-
21
21
 
22
22
  | Source | What's read |
23
23
  | ----------------------------- | ----------------------------------------------------------------------------------------- |
24
- | MCP `get_current_task` | Active checkpoint (for context.shipment write-back) |
24
+ | Local state `.codebyplan/state/checkpoints/<id>.json`; on miss `npx codebyplan sync` once; MCP `get_current_task` break-glass | Active checkpoint (for context.shipment write-back) |
25
25
  | `.codebyplan/git.json` + `.codebyplan/shipment.json` | `branch_config`, `shipment` section if present (per `ship-configure`) |
26
26
  | Repo scan | Detect surfaces from filesystem (vercel.json, eas.json, package.json publishConfig, etc.) |
27
27
  | `checkpoint.context.shipment` | Last shipment record (timestamp, surfaces, results) |
@@ -197,7 +197,7 @@ Verification timeouts are conservative (Vercel: 5min, EAS: 30min, TestFlight pro
197
197
 
198
198
  ### Step 7 — Persist shipment record
199
199
 
200
- Write to `checkpoint.context.shipment` via MCP `update_checkpoint`:
200
+ Write to `checkpoint.context.shipment` via `codebyplan checkpoint update <id> --context '{"shipment": {...}}'` (CLI write-through); use MCP `update_checkpoint` as documented break-glass when the CLI is unavailable:
201
201
 
202
202
  ```json
203
203
  {
@@ -326,7 +326,7 @@ When present, this overrides scan results. `ship-configure` writes here.
326
326
  ## Integration
327
327
 
328
328
  - **Triggered by**: `/cbp-checkpoint-end` (auto, after branch promotion to main via `/cbp-ship-main`); user direct invocation for re-runs
329
- - **Reads**: MCP `get_current_task`, `.codebyplan/git.json` + `.codebyplan/shipment.json` (`branch_config` + `shipment`), filesystem scan
330
- - **Writes**: MCP `update_checkpoint` (context.shipment)
329
+ - **Reads**: Local state `.codebyplan/state/checkpoints/<id>.json`; on miss `npx codebyplan sync` once; MCP `get_current_task` as documented break-glass when the state dir is absent and sync fails. Also reads `.codebyplan/git.json` + `.codebyplan/shipment.json` (`branch_config` + `shipment`), filesystem scan.
330
+ - **Writes**: `codebyplan checkpoint update <id> --context '...'` (CLI write-through) for context.shipment; MCP `update_checkpoint` break-glass.
331
331
  - **Calls**: per-surface deploy via reference files (vercel CLI, eas CLI, supabase CLI, npm, vsce, railway CLI, gh release)
332
332
  - **Triggers**: returns control to caller — does NOT auto-trigger `/cbp-checkpoint-complete` (that's the caller's job)
@@ -13,7 +13,7 @@ Compose a PR body from checkpoint context, then delegate all git/gh mechanics to
13
13
 
14
14
  ### Step 1: Read Checkpoint Context
15
15
 
16
- Use MCP `get_current_task` (repo_id) to get the active checkpoint. Collect `checkpoint.title`, completed task titles (`get_tasks(checkpoint_id)` filtered to `status === 'completed'`), and key decisions from `checkpoint.context.decisions[]`.
16
+ Read local state `.codebyplan/state/checkpoints/<id>.json` to get the active checkpoint; on miss run `npx codebyplan sync` once and re-read. Use MCP `get_current_task` as documented break-glass when the state dir is absent and sync fails. Collect `checkpoint.title`, completed task titles (from `.codebyplan/state/checkpoints/<id>/tasks/*.json` filtered to `status === 'completed'`; MCP `get_tasks` break-glass), and key decisions from `checkpoint.context.decisions[]`.
17
17
 
18
18
  ### Step 2: Compose PR Body
19
19
 
@@ -80,13 +80,12 @@ If `branch_deleted === true`, run a conditional Supabase preview-branch teardown
80
80
  > Lifecycle contract: see [[supabase-branch-lifecycle]].
81
81
 
82
82
  - Read `FEAT_BRANCH` from the `feat_branch` field in the Step 3 JSON output — NOT from `git branch --show-current`. By the time Step 4 runs, `codebyplan ship` has already checked out the base branch (unless `--keep-feat` was passed), so the live branch is the base, not the feat branch.
83
- - Resolve the parent project ref: read `.codebyplan/shipment.json` `.shipment.surfaces.supabase.project_ref`; if absent or empty, read the first line of `supabase/.temp/project-ref`. Use that resolved ref as the `project_id`.
84
- - Call `mcp__supabase__list_branches` with the resolved `project_id`.
83
+ - Call `mcp__supabase__list_branches` with `project_id: rrvtrumtkhrsbhcyrwvf`.
85
84
  - Scan the returned list for an entry whose `name` exactly equals `$FEAT_BRANCH`.
86
85
  - If found: call `mcp__supabase__delete_branch` with its `branch_id`. Report the Supabase delete outcome alongside `pr_url` / `merge_commit` / `branch_deleted`.
87
86
  - If not found: no-op silently — the GitHub integration may have already removed the preview branch on PR close; not-found is success, NOT an error.
88
87
  - If the `list_branches` call itself fails (network, auth, or a non-success response — distinct from a successful lookup that returns no match): emit a non-blocking warning that the Supabase preview branch for `$FEAT_BRANCH` may still exist and should be verified in the dashboard. Do not treat an API failure as a not-found success.
89
- - Never delete the branch where `is_default` is true in the `list_branches` response (the production/parent project branch) or any other persistent/long-lived branch.
88
+ - Never delete the parent project `rrvtrumtkhrsbhcyrwvf` itself or any persistent/production branch.
90
89
  - This coordinates safely with `/cbp-checkpoint-end` — the existence-checked delete makes any second attempt a harmless no-op.
91
90
 
92
91
  ## Key Rules
@@ -99,4 +98,4 @@ If `branch_deleted === true`, run a conditional Supabase preview-branch teardown
99
98
 
100
99
  - **Called by**: `/cbp-checkpoint-end`
101
100
  - **Delegates to**: `codebyplan ship` CLI
102
- - **Reads**: MCP `get_current_task`, `get_tasks`
101
+ - **Reads**: Local state `.codebyplan/state/checkpoints/<id>.json` + `.../tasks/<id>.json`; on miss `npx codebyplan sync` once; MCP `get_current_task` / `get_tasks` as documented break-glass when the state dir is absent and sync fails.
@@ -342,3 +342,4 @@ Both emit `status: passed` so callers proceed; the `reason` differs for traceabi
342
342
  **Callers**: `cbp-ship-main` Step 2.5 invokes this skill pre-merge (`--mode pre_merge --target production`, only when a PR already exists for the branch); the caller proceeds on `passed` (Supabase Preview check green — including the CI-level `skipping` bucket, which Step 8 maps to `passed`) and `skipped` (no DB-path changes detected — the gate did not apply), and stops on `blocked`/`pending_pr`. Note: `status: "skipped"` is NOT the CI `skipping` bucket — the two are distinct layers.
343
343
  **Canonical bucket contract**: the gh-checks bucket vocabulary used in Step 6 — `pass|fail|pending|skipping|cancel` — is the single canonical contract shared with `evaluateChecks()` in `packages/codebyplan-package/src/lib/ship.ts` (the generic poller inside `codebyplan ship`). Only `pass`/`skipping` are non-blocking, `pending` waits, and every other disposition blocks (fail-safe). The two pollers MUST NOT drift — any change to this enum or its dispositions must land in both places.
344
344
  **Tools used**: `mcp__supabase__list_branches` for project_ref resolution; `mcp__supabase__get_logs` for failure diagnostics; `gh pr checks` for status polling; `supabase --experimental branches get` as CLI fallback.
345
+ - Official skill (vendored): `supabase` — advisor findings surfaced by this gate are scored against the Supabase security checklist.
@@ -3,7 +3,7 @@ scope: org-shared
3
3
  name: cbp-supabase-migrate
4
4
  description: Scaffold or adopt a Supabase migration for the current PR branch, apply to the branch's preview DB, run advisor checks, regenerate TypeScript types. Includes a fresh-branch dry-run pre-flight that uses one persistent dry-run ephemeral branch per feature branch.
5
5
  argument-hint: "[--new <name> | <path-to-sql>]"
6
- allowed-tools: Read, Edit, Write, Bash(git *), Bash(supabase *), Bash(jq *), Bash(date *), Bash(which *), Bash(cp *), Bash(mv *), Bash(test *), Bash(ls *), mcp__supabase__apply_migration, mcp__supabase__list_migrations, mcp__supabase__get_advisors, mcp__supabase__generate_typescript_types, mcp__supabase__reset_branch, mcp__supabase__list_branches, mcp__supabase__create_branch, mcp__supabase__get_cost, mcp__supabase__confirm_cost, mcp__codebyplan__update_checkpoint, mcp__codebyplan__update_task
6
+ allowed-tools: Read, Edit, Write, Bash(git *), Bash(supabase *), Bash(jq *), Bash(date *), Bash(which *), Bash(cp *), Bash(mv *), Bash(test *), Bash(ls *), Bash(npx codebyplan checkpoint update *), Bash(npx codebyplan task update *), mcp__supabase__apply_migration, mcp__supabase__list_migrations, mcp__supabase__get_advisors, mcp__supabase__generate_typescript_types, mcp__supabase__reset_branch, mcp__supabase__list_branches, mcp__supabase__create_branch, mcp__supabase__get_cost, mcp__supabase__confirm_cost
7
7
  effort: xhigh
8
8
  ---
9
9
 
@@ -125,7 +125,11 @@ already provisioned the branch. Capture it as `PREVIEW_PROJECT_REF` and jump str
125
125
 
126
126
  ### Idempotency check (list before create)
127
127
 
128
- Resolve the parent project ref: read `.codebyplan/shipment.json` `.shipment.surfaces.supabase.project_ref`; if absent or empty, read the first line of `supabase/.temp/project-ref`. Use that resolved ref as the `project_id` for all MCP calls in this step. The parent `project_id` is the same ref that Supabase uses as both the project identifier and the branch target. Call `mcp__supabase__list_branches` with the resolved `project_id`. Scan the returned list for an entry whose `name` exactly equals `$BRANCH` (slashes included — `feat/CHK-144-...` is a valid Supabase branch name).
128
+ Call `mcp__supabase__list_branches` with the parent `project_id` `rrvtrumtkhrsbhcyrwvf`. The
129
+ parent `project_id` for MCP calls is the same ref string stored in `.codebyplan/shipment.json`
130
+ `surfaces.supabase.project_ref` — Supabase uses that one ref as both the project identifier
131
+ and the branch target. Scan the returned list for an entry whose `name` exactly equals
132
+ `$BRANCH` (slashes included — `feat/CHK-144-...` is a valid Supabase branch name).
129
133
 
130
134
  - **Match found**: capture its `project_ref` as `PREVIEW_PROJECT_REF`. Skip creation; proceed
131
135
  to "Record connection". This is the idempotent reuse path (covers a branch the GitHub
@@ -144,7 +148,7 @@ Cost confirmation is mandatory before creating a branch — never bypass it:
144
148
  stays empty.
145
149
 
146
150
  After cost is confirmed, call `mcp__supabase__create_branch`:
147
- - `project_id`: the resolved parent project ref (`.codebyplan/shipment.json` `.shipment.surfaces.supabase.project_ref`, falling back to the first line of `supabase/.temp/project-ref`)
151
+ - `project_id`: `rrvtrumtkhrsbhcyrwvf` (parent project ref)
148
152
  - `name`: `$BRANCH` (verbatim — slashes included)
149
153
  - `confirm_cost_id`: the same id from the `get_cost` response that was passed to `confirm_cost`
150
154
 
@@ -165,12 +169,11 @@ Record the branch so cleanup (see `cbp-checkpoint-end`, `cbp-git-worktree-remove
165
169
  skills can discover it. Phrase any context payload as prose — the MCP edge rejects raw
166
170
  uppercase database keywords (Cloudflare WAF).
167
171
 
168
- 1. **Checkpoint / task context** — call `mcp__codebyplan__update_checkpoint` (or
169
- `mcp__codebyplan__update_task` for a standalone task) to add to `context.discoveries`:
172
+ 1. **Checkpoint / task context** — use CLI write-through to append a `context.discoveries` entry:
170
173
 
171
- ```json
172
- { "topic": "supabase_preview_branch", "finding": "branch <BRANCH> -> project_ref <PREVIEW_PROJECT_REF>" }
173
- ```
174
+ - Checkpoint-bound: `codebyplan checkpoint update <checkpoint_id> --context '{"discoveries":[{"topic":"supabase_preview_branch","finding":"branch <BRANCH> -> project_ref <PREVIEW_PROJECT_REF>"}]}'`
175
+ - Standalone task: `codebyplan task update <task_id> --context '{"discoveries":[{"topic":"supabase_preview_branch","finding":"branch <BRANCH> -> project_ref <PREVIEW_PROJECT_REF>"}]}'`
176
+ - MCP `update_checkpoint` / `update_task` as documented break-glass when CLI unavailable.
174
177
 
175
178
  2. **`.codebyplan/shipment.json`** — read-merge-write (the `preview_branches` array may not
176
179
  exist yet — create it if absent; never clobber the rest of the file). Under
@@ -267,6 +270,8 @@ Skip Steps 5.5 and 6 (dry-run pre-flight and apply) and proceed directly to Step
267
270
 
268
271
  ## Step 5 — Scaffold or Adopt
269
272
 
273
+ > Security reminder for authored migrations: when a migration creates row-level-security policies or views, follow the official `supabase` checklist — `update` policies need both `using` and `with check`; views in exposed schemas need `security_invoker = true`; authorization reads `app_metadata`, not `user_metadata`; `auth.role()` is deprecated — scope to roles with the `to` clause (`to authenticated`, `to anon`).
274
+
270
275
  Parse `$ARGUMENTS`:
271
276
 
272
277
  ### Case A: `--new <name>`
@@ -436,4 +441,4 @@ Next: open a PR (if not already open) and the Supabase Preview check will run au
436
441
 
437
442
  ## Integration
438
443
 
439
- Invoked by the developer or by `cbp-database-agent`'s routing rule. Companion: `/cbp-supabase-setup` (one-time enablement); ship-time hard-block lives in `cbp-supabase-branch-check`. References: [reference/advisor-triage.md](reference/advisor-triage.md) (severity), [reference/cli-fallback.md](reference/cli-fallback.md) (CLI apply).
444
+ Invoked by the developer or by `cbp-database-agent`'s routing rule. Companion: `/cbp-supabase-setup` (one-time enablement); ship-time hard-block lives in `cbp-supabase-branch-check`. References: [reference/advisor-triage.md](reference/advisor-triage.md) (severity), [reference/cli-fallback.md](reference/cli-fallback.md) (CLI apply). Context recording uses CLI write-through (`codebyplan checkpoint update` / `codebyplan task update`); MCP `update_checkpoint` / `update_task` as documented break-glass when CLI unavailable. Deeper guidance: the vendored official skills `supabase` (security checklist, RLS/auth authoring, MCP surface) and `supabase-postgres-best-practices` (schema/index design, query performance).
@@ -243,3 +243,4 @@ Ready for /cbp-ship. Every PR will now get an isolated Supabase preview environm
243
243
 
244
244
  - Dashboard walkthrough + GitHub checklist: [reference/branching-setup.md](reference/branching-setup.md)
245
245
  - CLI detection + branch parsing + manual fallback: [reference/cli-fallback.md](reference/cli-fallback.md)
246
+ - Official skills (vendored): `supabase` and `supabase-postgres-best-practices` — deeper Supabase setup-security and Postgres best-practice guidance.