codebyplan 1.13.61 → 1.13.63

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 (76) hide show
  1. package/dist/cli.js +1140 -2065
  2. package/package.json +1 -1
  3. package/templates/agents/cbp-e2e-maestro.md +1 -1
  4. package/templates/agents/cbp-e2e-playwright.md +11 -11
  5. package/templates/agents/cbp-e2e-tauri.md +1 -1
  6. package/templates/agents/cbp-e2e-vscode.md +1 -1
  7. package/templates/agents/cbp-e2e-xcuitest.md +1 -1
  8. package/templates/hooks/cbp-mcp-round-sync.sh +4 -15
  9. package/templates/hooks/cbp-test-hooks.sh +0 -81
  10. package/templates/hooks/hooks.json +0 -9
  11. package/templates/rules/cbp-operating-gotchas.md +8 -10
  12. package/templates/rules/effort-and-ultracode.md +70 -0
  13. package/templates/rules/model-invocation-convention.md +1 -0
  14. package/templates/rules/supabase-branch-lifecycle.md +2 -2
  15. package/templates/rules/todo-backend.md +11 -8
  16. package/templates/rules/workflow-orchestration.md +59 -0
  17. package/templates/settings.project.base.json +0 -5
  18. package/templates/skills/cbp-build-cc-agent/SKILL.md +1 -0
  19. package/templates/skills/cbp-build-cc-claude-file/SKILL.md +1 -0
  20. package/templates/skills/cbp-build-cc-mode/SKILL.md +25 -17
  21. package/templates/skills/cbp-build-cc-rule/SKILL.md +1 -0
  22. package/templates/skills/cbp-build-cc-settings/SKILL.md +1 -0
  23. package/templates/skills/cbp-build-cc-settings/reference/cbp-permission-policy.md +1 -1
  24. package/templates/skills/cbp-build-cc-settings/reference/settings-fields.md +1 -1
  25. package/templates/skills/cbp-build-cc-skill/SKILL.md +2 -1
  26. package/templates/skills/cbp-build-cc-skill/reference/frontmatter-fields.md +1 -1
  27. package/templates/skills/cbp-build-cc-skill/scripts/validate-skill.sh +12 -9
  28. package/templates/skills/cbp-checkpoint-check/SKILL.md +5 -0
  29. package/templates/skills/cbp-checkpoint-complete/SKILL.md +1 -0
  30. package/templates/skills/cbp-checkpoint-create/SKILL.md +13 -22
  31. package/templates/skills/cbp-checkpoint-end/SKILL.md +42 -0
  32. package/templates/skills/cbp-checkpoint-plan/SKILL.md +15 -8
  33. package/templates/skills/cbp-checkpoint-start/SKILL.md +28 -19
  34. package/templates/skills/cbp-checkpoint-update/SKILL.md +3 -2
  35. package/templates/skills/cbp-clear-continue/SKILL.md +2 -1
  36. package/templates/skills/cbp-clear-prep/SKILL.md +2 -1
  37. package/templates/skills/cbp-finalize/SKILL.md +3 -2
  38. package/templates/skills/cbp-frontend-design/SKILL.md +1 -0
  39. package/templates/skills/cbp-frontend-ui/SKILL.md +2 -1
  40. package/templates/skills/cbp-frontend-ux/SKILL.md +2 -1
  41. package/templates/skills/cbp-git-branch-feat-create/SKILL.md +1 -0
  42. package/templates/skills/cbp-git-commit/SKILL.md +1 -0
  43. package/templates/skills/cbp-map-architecture/SKILL.md +5 -0
  44. package/templates/skills/cbp-merge-main/SKILL.md +1 -0
  45. package/templates/skills/cbp-refresh-arch-map/SKILL.md +1 -0
  46. package/templates/skills/cbp-round-build/SKILL.md +5 -0
  47. package/templates/skills/cbp-round-complete/SKILL.md +4 -24
  48. package/templates/skills/cbp-round-plan/SKILL.md +6 -1
  49. package/templates/skills/cbp-session-end/SKILL.md +42 -31
  50. package/templates/skills/cbp-session-start/SKILL.md +8 -7
  51. package/templates/skills/cbp-session-start/qa-regression.md +32 -25
  52. package/templates/skills/cbp-setup-cd/SKILL.md +2 -1
  53. package/templates/skills/cbp-setup-ci/SKILL.md +2 -1
  54. package/templates/skills/cbp-setup-e2e/SKILL.md +2 -1
  55. package/templates/skills/cbp-setup-eslint/SKILL.md +2 -1
  56. package/templates/skills/cbp-ship/SKILL.md +5 -0
  57. package/templates/skills/cbp-ship-configure/SKILL.md +2 -1
  58. package/templates/skills/cbp-ship-main/SKILL.md +1 -0
  59. package/templates/skills/cbp-standalone-task-check/SKILL.md +1 -0
  60. package/templates/skills/cbp-standalone-task-complete/SKILL.md +3 -5
  61. package/templates/skills/cbp-standalone-task-create/SKILL.md +7 -14
  62. package/templates/skills/cbp-standalone-task-start/SKILL.md +12 -11
  63. package/templates/skills/cbp-standalone-task-testing/SKILL.md +2 -1
  64. package/templates/skills/cbp-stripe/SKILL.md +2 -1
  65. package/templates/skills/cbp-supabase-branch-check/SKILL.md +2 -1
  66. package/templates/skills/cbp-supabase-migrate/SKILL.md +1 -0
  67. package/templates/skills/cbp-supabase-setup/SKILL.md +2 -1
  68. package/templates/skills/cbp-task-create/SKILL.md +3 -2
  69. package/templates/skills/cbp-task-start/SKILL.md +11 -10
  70. package/templates/skills/cbp-todo/SKILL.md +25 -39
  71. package/templates/skills/cbp-todo/qa-regression.md +21 -27
  72. package/templates/skills/cbp-verify/SKILL.md +5 -0
  73. package/templates/skills/cbp-verify/reference/round-scope.md +1 -2
  74. package/templates/skills/supabase/SKILL.md +2 -0
  75. package/templates/skills/supabase-postgres-best-practices/SKILL.md +2 -0
  76. package/templates/hooks/cbp-mcp-caller-worktree-inject.sh +0 -78
@@ -2,7 +2,8 @@
2
2
  scope: org-shared
3
3
  name: cbp-clear-continue
4
4
  description: Resume work after /clear by reading .codebyplan/clear/handoff.md and re-invoking the previously-blocked heavy skill. Reports a friendly error if no handoff file exists.
5
- effort: xhigh
5
+ model: inherit
6
+ effort: low
6
7
  ---
7
8
 
8
9
  # cbp-clear-continue
@@ -3,7 +3,8 @@ scope: org-shared
3
3
  name: cbp-clear-prep
4
4
  description: Capture a clear-context handoff when the context window is too large to run a heavy skill. Reads active task/round state, writes .codebyplan/clear/handoff.md, then instructs the user to run /clear and /cbp-clear-continue to resume.
5
5
  argument-hint: "[blocked-skill]"
6
- effort: xhigh
6
+ model: inherit
7
+ effort: medium
7
8
  ---
8
9
 
9
10
  # cbp-clear-prep
@@ -3,6 +3,7 @@ name: cbp-finalize
3
3
  description: Finalize and complete the current task — commit, merge main, push, complete
4
4
  argument-hint: [chk-task]
5
5
  triggers: [cbp-task-start, cbp-checkpoint-check]
6
+ model: inherit
6
7
  effort: xhigh
7
8
  ---
8
9
 
@@ -132,7 +133,7 @@ Skip the push only when nothing was committed in Step 5 AND `/cbp-merge-main` re
132
133
 
133
134
  ### Step 7: Complete Task
134
135
 
135
- MCP `complete_task(task_id)` kept on MCP because the CLI `codebyplan task complete` sends an empty POST body and cannot forward `caller_worktree_id`, which the server uses to enforce the mutate-lock. `caller_worktree_id` 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, then enforces the mutate-lock. The server auto-clears `assigned_user_id` + `assigned_worktree_id` on the task; if this was the last sibling task, it also clears the parent checkpoint's assignment. (Per CHK-104 hard-lock.)
136
+ MCP `complete_task(task_id)`. The server keys on the JWT user (`ctx.userId`) no worktree param is needed. The server auto-clears `assigned_user_id` on the task; if this was the last sibling task, it also clears the parent checkpoint's assignment.
136
137
 
137
138
  ### Step 8: Run Cleanup + Migration (inline)
138
139
 
@@ -189,7 +190,7 @@ direct you to run `/cbp-clear-prep` first; otherwise checkpoint-check starts on
189
190
  - **Triggered by**: `/cbp-verify` (auto, scope=task, when it writes `verify_verdict.verdict === 'READY'`)
190
191
  - **Chain**: `/cbp-verify` (scope=task READY) → `/cbp-finalize`
191
192
  - **Reads**: `.codebyplan/state/checkpoints/*.json`, `checkpoints/<id>/tasks/*.json`, `checkpoints/<id>/tasks/<id>/rounds/*.json`, `todos.json` (local-first; `npx codebyplan sync` on miss; MCP `get_current_task`/`get_rounds`/`get_tasks` break-glass) — including each round's `verify_manifest` and `task.context.verify_verdict`
192
- - **Writes**: `codebyplan task update` for `files_changed` (CLI write-through; MCP `update_task` break-glass); MCP `complete_task` for task completion (kept MCP — CLI cannot forward `caller_worktree_id`)
193
+ - **Writes**: `codebyplan task update` for `files_changed` (CLI write-through; MCP `update_task` break-glass); MCP `complete_task` for task completion
193
194
  - **Uses skills (inline, no sub-agent)**: `cleanup` (if deletions), `migration` (if exports renamed)
194
195
  - **Triggers**: Same-context transitions auto-trigger via the Skill tool (next task in checkpoint → `cbp-task-start {N}`, `allow`-tier, fires silently). Checkpoint-done → auto-triggers `cbp-checkpoint-check` via Skill tool (`ask`-tier, permission prompt IS the human gate). No-task-anywhere fallback → directive `Next: Run /clear, then /cbp-session-end.`
195
196
  - **Checkpoint-bound only** — for standalone tasks use `/cbp-standalone-task-complete`
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: cbp-frontend-design
3
3
  description: Up-front design playbook loaded BEFORE writing UI / styling code. Detects the stack, loads the matching reference file, commits to an aesthetic direction, and prevents generic AI-slop output. Modelled on Anthropic's frontend-design skill, adapted for CBP repos with existing design systems.
4
+ model: inherit
4
5
  effort: xhigh
5
6
  ---
6
7
 
@@ -1,7 +1,8 @@
1
1
  ---
2
2
  name: cbp-frontend-ui
3
3
  description: Visual quality self-review pass invoked twice per round — once by round-executor Step 3.8 (phase 'style_only', no screenshots) for token/spacing/typography/color/cohesion, once by /cbp-round-build Step 5b (phase 'screenshot_review', with e2e screenshots) for rendered-output review and baseline regressions. Default phase 'full' runs everything for back-compat.
4
- effort: xhigh
4
+ model: inherit
5
+ effort: high
5
6
  ---
6
7
 
7
8
  # Frontend UI (Post-Implementation Visual Self-Review)
@@ -1,7 +1,8 @@
1
1
  ---
2
2
  name: cbp-frontend-ux
3
3
  description: Interaction-quality self-review pass loaded by round-executor AFTER UI code is written. Catches navigation flow issues, missing feedback states, cognitive-load problems, form usability gaps, and accessibility violations. Auto-applies in-scope mechanical UX fixes within the round's files_changed. Replaces the post-implementation ux-agent spawn with an inline skill invocation.
4
- effort: xhigh
4
+ model: inherit
5
+ effort: high
5
6
  ---
6
7
 
7
8
  # Frontend UX (Post-Implementation Interaction Self-Review)
@@ -2,6 +2,7 @@
2
2
  name: cbp-git-branch-feat-create
3
3
  description: Create feature branch from the production branch (main, config-driven)
4
4
  argument-hint: "[name] e.g. add-user-auth"
5
+ model: inherit
5
6
  effort: low
6
7
  ---
7
8
 
@@ -2,6 +2,7 @@
2
2
  name: cbp-git-commit
3
3
  description: Create scoped commit with conventional format
4
4
  argument-hint: "[--task|--all] [type]: [description]"
5
+ model: inherit
5
6
  effort: low
6
7
  ---
7
8
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: cbp-map-architecture
3
+ model: inherit
3
4
  effort: xhigh
4
5
  description: Orchestrate architecture map generation for one or all modules. Spawns the cbp-map-architecture agent per module, writes per-module .md files to .claude/architecture/, regenerates INDEX.md and graph.md, and stamps each module via the CLI. Idempotent — safe to re-run.
5
6
  argument-hint: '[--module <path>] [--deep <path,...>]'
@@ -66,6 +67,10 @@ For each module in `targets[]`:
66
67
  Modules may be spawned concurrently (parallel Task calls) when there are multiple targets
67
68
  with no inter-module dependency. The agent is read-only and safe to parallelize.
68
69
 
70
+ #### Orchestration (optional)
71
+
72
+ Step B's per-module `cbp-map-architecture` fan-out MAY be authored as a `Workflow(...)` script instead of ad-hoc parallel `Task` calls — for deterministic per-module fan-out and schema-validated map outputs. This is opt-in (ultracode session or explicit user request); the parallel `Task` flow above stays the DEFAULT and is unchanged. See `rules/workflow-orchestration.md`.
73
+
69
74
  ### Step C: Regenerate INDEX.md and graph.md
70
75
 
71
76
  After all per-module map files are written:
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: cbp-merge-main
3
3
  description: Merge main into the current feat branch with interactive per-conflict resolution and inline QA re-run
4
+ model: inherit
4
5
  effort: high
5
6
  ---
6
7
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: cbp-refresh-arch-map
3
+ model: inherit
3
4
  effort: high
4
5
  description: Drift-scoped refresh of the .claude/architecture/ map — re-runs the cbp-map-architecture agent for ONLY the modules whose stamped git SHA has changed, regenerates INDEX.md + graph.md, and re-stamps. Idempotent; no-op when no module has drifted.
5
6
  argument-hint: '[--module <path>]'
@@ -2,6 +2,7 @@
2
2
  name: cbp-round-build
3
3
  description: Execute the approved plan from /cbp-round-plan — runs per-wave builders, inline testing-qa per wave, and auto-triggers /cbp-verify
4
4
  triggers: [cbp-verify]
5
+ model: inherit
5
6
  effort: xhigh
6
7
  ---
7
8
 
@@ -197,6 +198,10 @@ Input contracts: `cbp-testing-qa-agent` receives `executor_output`, `testing_pro
197
198
 
198
199
  **Independence**: neither agent reads the other's output. Baseline-regression findings surface as a BLOCKING gate at `/cbp-verify` (an explicit accept-or-fix user decision; baselines are NEVER auto-accepted). Per-wave spawns MAY run in parallel with the next wave's builder when dependency order allows. The `cbp-e2e-*` specialists are parallel siblings of `cbp-testing-qa-agent` — they do not share state.
199
200
 
201
+ #### Orchestration (optional)
202
+
203
+ Under heavy fan-out, Step 5's per-wave builders and their parallel `cbp-testing-qa-agent` + `cbp-e2e-*` siblings MAY be authored as a `Workflow(...)` script instead of ad-hoc `Task`/`Agent` spawning — for deterministic fan-out, wave barriers, and schema-validated outputs. This is opt-in (ultracode session or explicit user request); the spawn flow above stays the DEFAULT and is unchanged. See `rules/workflow-orchestration.md`.
204
+
200
205
  ### Step 5b: Post-E2E Screenshot Review (cbp-frontend-ui Phase 6.5)
201
206
 
202
207
  Aggregate screenshots across ALL specialists that ran: `screenshots = Object.values(round.context.e2e_outputs ?? {}).flatMap(o => o.screenshots ?? [])`. When the aggregated list is non-empty, invoke the `cbp-frontend-ui` skill with `phase: 'screenshot_review'` (input: `files_changed`, `e2e_screenshots: <aggregated screenshots>`, `context: { checkpoint_goal, round_requirements }`). Under this phase the skill runs only Phase 6.5 (Rendered-Output Visual Review) + 7 + 8 — Phases 1-6 (style) already ran inline at builder Step 3.8 with `phase: 'style_only'`.
@@ -4,6 +4,7 @@ description: Reconcile user git-add approvals and complete the round (the ask-ti
4
4
  argument-hint: [chk-task-round | task-round]
5
5
  disable-model-invocation: true
6
6
  triggers: [cbp-round-plan]
7
+ model: inherit
7
8
  effort: low
8
9
  ---
9
10
 
@@ -24,7 +25,7 @@ Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
24
25
  | Get task | local state (break-glass: `get_current_task`) | `get_current_standalone_task(repo_id)` |
25
26
  | Get rounds | local state (break-glass: `get_rounds`) | `get_standalone_rounds(standalone_task_id)` |
26
27
  | Update round | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_id, ...)` |
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
+ | Complete round | `complete_round(round_id, duration_minutes?)` | `complete_standalone_round(standalone_round_id, duration_minutes?)` |
28
29
 
29
30
  # Round Complete Command
30
31
 
@@ -83,20 +84,7 @@ Reconcile which files the user has approved by staging them. Run:
83
84
  npx codebyplan round sync-approvals --round-id <round_id> --task-id <task_id>
84
85
  ```
85
86
 
86
- The CLI auto-resolves the caller worktree id with the following precedence:
87
- 1. `--caller-worktree-id <uuid>` override (if passed — skips all resolution)
88
- 2. Per-device branch-keyed cache (`.codebyplan/worktree.local.json`)
89
- 3. In-process tuple API call: `POST /worktrees/resolve` using `(device_id, repo_path, branch)`
90
-
91
- On the write path (non `--dry-run`), if the worktree id cannot be resolved the CLI **hard-fails with exit 1** and prints an actionable message. To pre-populate the cache:
92
-
93
- ```
94
- npx codebyplan resolve-worktree --cache
95
- ```
96
-
97
- If this worktree is not yet registered, run `npx codebyplan setup` first, then re-run `/cbp-round-complete`.
98
-
99
- The CLI parses `git status --short`, merges drift + staging + web-UI flag, and writes both round and task (forwarding `caller_worktree_id` on both writes so the server honors the feat-worktree lock). A **cleanly staged** file (`git add`-ed, no further unstaged changes) becomes `user_approved: true`.
87
+ The CLI parses `git status --short`, merges drift + staging + web-UI flag, and writes both round and task. A **cleanly staged** file (`git add`-ed, no further unstaged changes) becomes `user_approved: true`.
100
88
 
101
89
  Read the stdout JSON: `{ added, stale_marked, reactivated, total_files }`.
102
90
 
@@ -109,14 +97,7 @@ This is the **single** explicit reconcile owned by this skill. (The `cbp-mcp-rou
109
97
  Calculate duration from the round's `started_at` to now in minutes.
110
98
 
111
99
  - **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
- - **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
-
114
- ```
115
- Warning: could not resolve caller_worktree_id (npx codebyplan resolve-worktree returned empty).
116
- The complete_standalone_round call may be rejected by the pre-guard. Proceed anyway? (yes / no)
117
- ```
118
-
119
- If the user confirms yes, proceed with `caller_worktree_id: ""`. If no, stop.
100
+ - **standalone KIND**: MCP `complete_standalone_round(standalone_round_id, duration_minutes)`. The server keys on the JWT user (`ctx.userId`) no worktree param needed or accepted.
120
101
 
121
102
  `complete_round` / `complete_standalone_round` sets the round `completed`, locks all `file_changes` for the round (`approval_locked: true`), and returns `unapproved_files[]` + `unapproved_count`. Hold those for routing.
122
103
 
@@ -157,7 +138,6 @@ Payload: `round.context.round_complete = { staged_count, unstaged_count, route,
157
138
  - **Permission prompt = confirmation** — gated by `ask`-tier `Skill(cbp-round-complete)`. Because the skill is `disable-model-invocation: true`, this gate applies to the user's **direct** `/cbp-round-complete` invocation. NEVER add an AskUserQuestion to confirm running; the harness prompt is the gate. A declined permission is a clean no-op.
158
139
  - **Step 2 (CLI) must exit 0** — if it fails, STOP before `complete_round`. The merge semantics are enforced by the CLI.
159
140
  - **NEVER ask the user to git add files** — Step 2 only reads staging status. **NEVER stage files** — Claude does not touch the git staging area; the user's `git add` is the approval signal.
160
- - **standalone KIND Step 3**: `caller_worktree_id` is REQUIRED for `complete_standalone_round` — always resolve and pass it.
161
141
 
162
142
  ## Integration
163
143
 
@@ -3,6 +3,7 @@ name: cbp-round-plan
3
3
  description: Plan a round — round-1 planning AND round-2+ deep-analysis of unapproved work, then spawn cbp-round-planner and auto-trigger /cbp-round-build
4
4
  triggers: [cbp-round-build]
5
5
  argument-hint: [chk-task-round | task-round | requirements-text] # e.g. `108-1-2`, `45-2`, or free-text
6
+ model: inherit
6
7
  effort: xhigh
7
8
  ---
8
9
 
@@ -24,7 +25,7 @@ Set `KIND` for the rest of this skill. Read/write sources vary by KIND:
24
25
  | Get rounds | local state (break-glass: `get_rounds`) | `get_standalone_rounds(standalone_task_id)` |
25
26
  | Add round | `codebyplan round add` (break-glass: `add_round`) | `add_standalone_round(standalone_task_id, ...)` |
26
27
  | Update round | `codebyplan round update` (break-glass: `update_round`) | `update_standalone_round(standalone_round_id, ...)` |
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
+ | Complete round | `complete_round(round_id, duration_minutes?)` | `complete_standalone_round(standalone_round_id, duration_minutes?)` |
28
29
  | Update task | `codebyplan task update` (break-glass: `update_task`) | `update_standalone_task(standalone_task_id, ...)` |
29
30
 
30
31
  > **Note**: The `standalone` KIND column uses MCP tools unchanged — standalone local-first migration is out of scope and will be addressed in a later task.
@@ -260,6 +261,10 @@ input:
260
261
 
261
262
  Wait for planner output. **If the spawn fails, STOP per "Planner Spawn Failure Is A Gate Failure" above** — do not self-certify a plan inline.
262
263
 
264
+ #### Orchestration (optional)
265
+
266
+ When a plan warrants independent perspectives, Step 7's `cbp-round-planner` spawn MAY be expressed as a `Workflow(...)` script — e.g. a judge-panel of independent plans, scored and synthesized — instead of a single ad-hoc spawn. This is opt-in (ultracode session or explicit user request); the single-spawn flow above stays the DEFAULT and is unchanged. See `rules/workflow-orchestration.md`.
267
+
263
268
  ### Step 8: Present Plan
264
269
 
265
270
  Present the plan to user:
@@ -1,7 +1,8 @@
1
1
  ---
2
2
  name: cbp-session-end
3
3
  description: End a development session
4
- effort: xhigh
4
+ model: inherit
5
+ effort: high
5
6
  ---
6
7
 
7
8
  # Session End Command
@@ -21,35 +22,46 @@ Always write a session log for this session — **even if empty**. `/cbp-session
21
22
  2. Pull facts from local state files rather than narrating from memory:
22
23
  - Rounds added/completed, tasks advanced/completed during this session (read from `.codebyplan/state/checkpoints/` subtree)
23
24
  - Decisions, blockers, or discoveries recorded in checkpoint/task context
24
-
25
- ### Step 1.3: Capture Handoff Snapshot
26
-
27
- 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).
28
-
29
- 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.
30
- 2. If `rows[0]` exists and its `command` is non-empty (active work in flight):
31
- ```yaml
32
- handoff:
33
- command: <rows[0].command> # e.g. "/cbp-verify"
34
- instructions: <rows[0].instructions> # human-readable trigger reason
35
- state: <rows[0].state> # workflow state label
36
- context: # entity ids used by the Step 4.5 freshness probe
37
- checkpoint_id: <rows[0].checkpoint_id>
38
- task_id: <rows[0].task_id>
39
- round_id: <rows[0].round_id>
40
- captured_at: <ISO now> # for entity-drift freshness comparison
41
- captured_session_log_id: <current session log id>
42
- ```
43
- 3. If the queue is empty or `rows[0].command` is empty / idle: set `handoff = null` so the next session's probe falls through to `/cbp-todo`.
44
- 4. Hold `handoff` in context for Step 1's `update_session_log` call below — it ships in the same write as `ended_at` and `summary`.
45
-
46
- Continuing Step 1:
47
-
48
- 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:
25
+ 3. Run `codebyplan session update-log --id <log-id> --ended-at <now> --summary <text> --pending <text> --git-branch <current-branch>` (CLI write-through: updates `.codebyplan/state/session/current.json` + REST). Break-glass fallback: MCP `update_session_log` when the CLI is unavailable. Fields:
49
26
  - `ended_at`: now (maps to the `closed_at` column per TASK-2 alias)
50
- - `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)
51
27
  - `summary`: concise — may be empty if nothing happened
52
28
  - `pending`: open items the next session should see first
29
+ - `git_branch`: the current git branch (informational; `git rev-parse --abbrev-ref HEAD`)
30
+ - **Do NOT pass `--handoff` / `handoff` field.** The DB handoff field is no longer written here. Omit entirely — never pass `handoff:null` (it clobbers summary/pending content).
31
+
32
+ ### Step 1.3: Optional Handoff File (mid-work only)
33
+
34
+ When an active in-progress task or round exists, offer to write a handoff file so the next session can auto-resume. Skip entirely when not mid-work.
35
+
36
+ 1. Read `.codebyplan/state/todos.json` (local-first) and check `rows[0]` (queue head, ordered by `sort_order`). If missing/stale, run `npx codebyplan sync` once and re-read. Break-glass fallback: MCP `get_todos({ repo_id })` when the state dir is absent and sync fails. The worker stamps `command`, `instructions`, `state`, and entity ids `checkpoint_id` / `task_id` / `round_id` on every row.
37
+
38
+ 2. **If `rows[0]` exists and its `command` is non-empty** (active work in flight):
39
+ - Determine the handoff file path. The directory is keyed by the human-facing **number** (`<NNN>` checkpoint number / `<N>` standalone task number) — matching the committed `.codebyplan/checkpoint/<NNN>/` plan-artifact convention and the session-start resume probe (which globs by number). Resolve the number from local state (break-glass: MCP):
40
+ - Checkpoint work: read `.codebyplan/state/checkpoints/<rows[0].checkpoint_id>.json` → `number` (break-glass: MCP `get_checkpoints`). Path: `.codebyplan/checkpoint/<NNN>/handoff.md`.
41
+ - Standalone work: read the standalone task's `number` from local standalone state (break-glass: MCP `get_standalone_tasks`). Path: `.codebyplan/standalone/<N>/handoff.md`.
42
+ - Offer to write the file:
43
+ ```
44
+ Write handoff file for next session?
45
+ <path>
46
+
47
+ Reply: yes | no
48
+ ```
49
+ - On `yes`: write the file with this structure:
50
+ ```markdown
51
+ ---
52
+ command: <rows[0].command>
53
+ state: <rows[0].state>
54
+ captured_at: <ISO now>
55
+ checkpoint_id: <rows[0].checkpoint_id or null>
56
+ task_id: <rows[0].task_id or null>
57
+ round_id: <rows[0].round_id or null>
58
+ ---
59
+
60
+ <rows[0].instructions — human-readable trigger reason>
61
+ ```
62
+ - The file is committed with the session's final commit (Step 1.5) or the user can stage it manually.
63
+
64
+ 3. **If the queue is empty or `rows[0].command` is empty/idle**: skip — no handoff file is written.
53
65
 
54
66
  ### Step 1.5: Commit Non-Task Files
55
67
 
@@ -116,7 +128,7 @@ Stop this worktree's Realtime watch daemon, non-blocking and non-fatal:
116
128
  npx codebyplan watch stop 2>/dev/null || true
117
129
  ```
118
130
 
119
- 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.
131
+ This SIGTERMs the per-worktree pidfile daemon started by `cbp-session-start-hook.sh`. Silently ignored when no daemon is running. 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.
120
132
 
121
133
  ### Step 3: Update Session State
122
134
 
@@ -133,9 +145,8 @@ You can close this window.
133
145
  ## Integration
134
146
 
135
147
  - **Triggered by**: user invocation (prompted by `/cbp-todo` when no work remains)
136
- - **Reads**: `.codebyplan/repo.json`; 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); `codebyplan session freshness-gate` (Step 1.7 package-freshness gate, without --halt-on-update); `codebyplan session infra-files --json --task-files <csv>` (Step 1.5 infra-file set math)
137
- - **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`)
148
+ - **Reads**: `.codebyplan/repo.json`; 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 mid-work detection + Step 1.5 active-task lookup), `.codebyplan/state/checkpoints/<id>/tasks/<id>/rounds/` (Step 1.5 task-file resolution); `codebyplan session freshness-gate` (Step 1.7 package-freshness gate, without --halt-on-update); `codebyplan session infra-files --json --task-files <csv>` (Step 1.5 infra-file set math)
149
+ - **Writes**: `codebyplan session update-log --id <id> --git-branch <branch> ...` (Step 1 finalize — CLI write-through to `.codebyplan/state/session/current.json`; break-glass: MCP `update_session_log`; handoff field never passed), `codebyplan session create-log` (Step 1 fallback when no log exists; break-glass: MCP `create_session_log`), optional handoff file at `.codebyplan/checkpoint/<NNN>/handoff.md` or `.codebyplan/standalone/<N>/handoff.md` (Step 1.3, mid-work only), `codebyplan session update-state --action deactivate` (Step 3 — CLI write-through to `.codebyplan/state/session/state.json`; break-glass: MCP `update_session_state`)
138
150
  - **Spawns**: none
139
151
  - **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 `result === 'updated'` path (committing changed `.claude/` and `.codebyplan/` paths).
140
152
  - **Paired with**: `/cbp-session-start`
141
- - **Pairs with**: `/cbp-session-start` Step 4.5 (handoff payload shape + freshness-gate contract; specified inline — no separate rule file)
@@ -2,6 +2,7 @@
2
2
  name: cbp-session-start
3
3
  description: Start a development session
4
4
  triggers: [cbp-todo]
5
+ model: inherit
5
6
  effort: low
6
7
  ---
7
8
 
@@ -40,7 +41,7 @@ codebyplan session start --json
40
41
  The orchestrator performs (in order, all fail-safe):
41
42
 
42
43
  1. Resolve `repo_id` from `.codebyplan/repo.json`
43
- 2. `codebyplan resolve-worktree --json` → `worktree_id`, `worktree_error_kind`
44
+ 2. `codebyplan whoami --json` → `user_id`, `user_error_kind` (CHK-225 retired worktree identity — concurrency is user-level via `assigned_user_id`; the removed `resolve-worktree` verb no longer exists)
44
45
  3. `codebyplan session freshness-gate --halt-on-update` → update_halt short-circuit (no activate, no create-log when halt)
45
46
  4. Infra-drift nudge (monorepo-only), arch-map drift nudge, LSP binary nudge
46
47
  5. Read previous session log from `.codebyplan/state/session/current.json` (sync on miss)
@@ -48,7 +49,7 @@ The orchestrator performs (in order, all fail-safe):
48
49
  7. `codebyplan session update-state --action activate` (write-through)
49
50
  8. `codebyplan session create-log` → `session_log_id`
50
51
  9. Infra-files set math: active task round files subtracted from `git status --porcelain`
51
- 10. `get_checkpoints({ repo_id, status:'active' })` → ownership partition (owned vs cross)
52
+ 10. `get_checkpoints({ repo_id, status:'active' })` → ownership partition (owned by you vs other users)
52
53
  11. Compute `next_action` + render the Step 6 output block
53
54
 
54
55
  The envelope shape:
@@ -57,8 +58,8 @@ The envelope shape:
57
58
  {
58
59
  status: 'ok' | 'update_halt',
59
60
  session_log_id: string | null,
60
- worktree_id: string | null,
61
- worktree_error_kind: string | null,
61
+ user_id: string | null,
62
+ user_error_kind: string | null,
62
63
  infra_drift_nudge: string | null,
63
64
  arch_map_nudge: string | null,
64
65
  lsp_nudges: string[],
@@ -103,13 +104,13 @@ Route from `envelope.next_action`:
103
104
  - **`resume_handoff`** — trigger `envelope.handoff.command` directly with `envelope.handoff.context` / `envelope.handoff.state`. Skip Step 5.7.
104
105
  - **`commit_then_todo`** — run Step 5.7 (infra commit gate), then trigger `/cbp-todo`.
105
106
  - **`trigger_todo`** — trigger `/cbp-todo` (owns active work, or idle path).
106
- - **`stop`** — do NOT auto-trigger `/cbp-todo`. The Ownership block in `rendered_block` communicates the situation; the user must switch to the owning worktree or start new work explicitly.
107
+ - **`stop`** — do NOT auto-trigger `/cbp-todo`. The Ownership block in `rendered_block` communicates the situation; the user must coordinate with the owning user or start new work explicitly.
107
108
 
108
109
  ## Integration
109
110
 
110
111
  - **Triggered by**: user invocation, `/clear` recovery
111
- - **Reads**: MCP `health_check` (Step 0 hard gate — stays MCP unconditionally); `codebyplan session start --json` (Steps 1–5.8 — the orchestrator reads `.codebyplan/repo.json`, `.codebyplan/git.json`, `.codebyplan/state/session/current.json`, `.codebyplan/state/todos.json`, `.codebyplan/state/checkpoints/` entity files, `scripts/infra-drift.mjs`, `.codebyplan/architecture.json`, `.codebyplan/lsp.json`)
112
- - **Writes**: orchestrator calls `codebyplan session update-state --action activate` (Step 7) and `codebyplan session create-log` (Step 8) — both SKIPPED on Step 0 hard-fail and on `status: update_halt`
112
+ - **Reads**: MCP `health_check` (Step 0 hard gate — stays MCP unconditionally); `codebyplan session start --json` (Steps 1–5.8 — the orchestrator runs `codebyplan whoami --json` for caller identity and reads `.codebyplan/repo.json`, `.codebyplan/git.json`, `.codebyplan/state/session/current.json`, `.codebyplan/state/todos.json`, `.codebyplan/state/checkpoints/` entity files, `scripts/infra-drift.mjs`, `.codebyplan/architecture.json`, `.codebyplan/lsp.json`)
113
+ - **Writes**: orchestrator calls `codebyplan session update-state --action activate` (Step 7) and `codebyplan session create-log` (Step 8 — user-level; no worktree_id in the body) — both SKIPPED on Step 0 hard-fail and on `status: update_halt`
113
114
  - **Spawns**: none
114
115
  - **Triggers**: `/cbp-git-commit` (conditional, on user approval at Step 5.7), `envelope.handoff.command` (on `next_action: resume_handoff`), `/cbp-todo` (on `next_action: trigger_todo` or `commit_then_todo`); STOPS with no trigger on `next_action: stop` or `mcp_update_halt`
115
116
  - **Paired with**: `/cbp-session-end`
@@ -1,52 +1,59 @@
1
1
  ---
2
2
  name: cbp-session-start-qa-regression
3
- description: Manual regression procedure for the cbp-session-start worktree-ownership awareness + resolve-worktree distress channel (CHK-137 TASK-3)
3
+ description: Manual regression procedure for the cbp-session-start user-identity awareness + user-lock routing (CHK-225 TASK-5)
4
4
  ---
5
5
 
6
- # cbp-session-start — Worktree-Ownership Regression
6
+ # cbp-session-start — User-Identity Regression
7
7
 
8
- Manual procedure verifying that `/cbp-session-start` correctly resolves the caller's worktree identity, gates Step 7 auto-trigger on ownership, and surfaces distress signals non-blocking. Run these by hand whenever the SKILL's envelope-consumption logic (Step 0 health gate, the `codebyplan session start` invocation, the Step 5.7 commit gate, or the Step 7 `next_action` routing) changes.
8
+ Manual procedure verifying that `/cbp-session-start` correctly resolves the caller's user identity (via `codebyplan whoami --json`), gates Step 7 auto-trigger on user-level ownership, and surfaces distress signals non-blocking. Run these by hand whenever the SKILL's envelope-consumption logic (Step 0 health gate, the `codebyplan session start` invocation, the Step 5.7 commit gate, or the Step 7 `next_action` routing) changes.
9
9
 
10
- Since the worktree resolution, handoff freshness, ownership partition, and Step 6 render are now computed inside `codebyplan session start` (Steps 1–5.8 collapsed into one CLI call), the deterministic behavior is covered by unit tests (`src/cli/session/start.test.ts`, `src/lib/session.test.ts`). These scenarios are now best verified by inspecting the **envelope** the CLI emits — run `codebyplan session start --json` and read its fields — rather than tracing SKILL prose. The `ownership`, `next_action`, `handoff.fresh`, and `worktree_error_kind` fields below correspond to envelope keys.
10
+ Since the user resolution, handoff freshness, ownership partition, and Step 6 render are now computed inside `codebyplan session start` (Steps 1–5.8 collapsed into one CLI call), the deterministic behavior is covered by unit tests (`src/cli/session/start.test.ts`, `src/lib/session.test.ts`). These scenarios are now best verified by inspecting the **envelope** the CLI emits — run `codebyplan session start --json` and read its fields — rather than tracing SKILL prose. The `ownership`, `next_action`, `handoff.fresh`, and `user_error_kind` fields below correspond to envelope keys.
11
11
 
12
12
  Repo under test: `2ff6d405-39c5-47b8-a6d1-59f998ac0537`.
13
13
 
14
14
  ## Preconditions
15
15
 
16
16
  - The SKILL keeps Step 0 (`health_check`) as a hard gate, then delegates Steps 1–5.8 to `codebyplan session start --json` — confirm with `grep -n 'session start --json' SKILL.md` → at least one hit.
17
- - The orchestrator resolves worktree identity via `resolve-worktree --json` and partitions ownership via `get_checkpoints({ repo_id, status: 'active' })` — confirm the envelope carries `worktree_id` / `worktree_error_kind` / `owned_count` / `total_count`.
17
+ - The orchestrator resolves user identity via `whoami --json` and partitions ownership via `get_checkpoints({ repo_id, status: 'active' })` — confirm the envelope carries `user_id` / `user_error_kind` / `owned_count` / `total_count`.
18
18
  - The Step 6 Ownership block (the envelope's `rendered_block`) is READ-ONLY — confirm no "reassign", "release_assignment", or "transfer" language appears in SKILL.md: `grep -n 'reassign\|release_assignment\|transfer' SKILL.md` → no hits.
19
- - The handoff freshness gate includes the cross-worktree stale rule (checkpoint `worktree_id` non-null and differs from caller) — covered by the `probeHandoff` unit tests; the envelope surfaces the outcome as `handoff.fresh`.
19
+ - The handoff freshness gate includes the cross-user stale rule (checkpoint `assigned_user_id` non-null and differs from caller) — covered by the `probeHandoff` unit tests; the envelope surfaces the outcome as `handoff.fresh`.
20
20
 
21
- ## Scenario A — caller owns an active CHK → auto-trigger
21
+ ## Scenario A — current user owns an active CHK → auto-trigger
22
22
 
23
- 1. Run from a worktree whose `WORKTREE_ID` matches the active checkpoint's `worktree_id` (or both are `null`).
24
- 2. `get_checkpoints({ repo_id, status: 'active' })` returns at least one entry whose `worktree_id === WORKTREE_ID` (or both null).
25
- 3. **Expected**: envelope `owned_count >= 1`, `next_action: 'trigger_todo'`. `rendered_block` shows `Ownership: N active CHK(s), N owned by this worktree`. The SKILL's Step 7 fires `/cbp-todo`.
23
+ 1. Run signed in as a user whose `user_id` matches the active checkpoint's `assigned_user_id` (or the checkpoint's `assigned_user_id` is `null`).
24
+ 2. `get_checkpoints({ repo_id, status: 'active' })` returns at least one entry whose `assigned_user_id === user_id` (or is null).
25
+ 3. **Expected**: envelope `owned_count >= 1`, `next_action: 'trigger_todo'`. `rendered_block` shows `Ownership: N active CHK(s), N owned by you`. The SKILL's Step 7 fires `/cbp-todo`.
26
26
 
27
- ## Scenario B — active CHK(s) exist but none owned by caller → Ownership block + STOP
27
+ ## Scenario B — active CHK(s) exist, all owned by a different user → Ownership block + STOP
28
28
 
29
- Repro: caller worktree is `codebyplan-claude-2` (`38cd7dfa`). The only active checkpoint is CHK-136, assigned to `codebyplan-cli` (`016bd7f2`).
29
+ Repro: current user is `alice@example.com` (`uuid-A`). The only active checkpoint is CHK-136, assigned to `bob@example.com` (`uuid-B`).
30
30
 
31
- 1. `resolve-worktree --json` returns `{"worktree_id":"38cd7dfa-...","error_kind":null}`.
32
- 2. `get_checkpoints({ repo_id, status: 'active' })` returns CHK-136 with `worktree_id = "016bd7f2-..."`.
33
- 3. Step 5.8: `owned_count = 0`, `total_count = 1`, `cross_worktree = [CHK-136]`.
34
- 4. **Expected**: envelope `owned_count = 0`, `total_count = 1`, `next_action: 'stop'`, `cross_checkpoints = [CHK-136]`. `rendered_block` shows `Ownership: 1 active CHK(s), 0 owned by this worktree` and `[Cross-worktree: CHK-136 (…)]`. The SKILL **STOPS** on `next_action: 'stop'` — `/cbp-todo` is NOT auto-triggered. No reassignment language appears.
31
+ 1. `whoami --json` returns `{"user_id":"uuid-A","email":"alice@example.com"}`.
32
+ 2. `get_checkpoints({ repo_id, status: 'active' })` returns CHK-136 with `assigned_user_id = "uuid-B"`.
33
+ 3. Step 5.8: `owned_count = 0`, `total_count = 1`, `cross_checkpoints = [CHK-136]`.
34
+ 4. **Expected**: envelope `owned_count = 0`, `total_count = 1`, `next_action: 'stop'`, `cross_checkpoints = [CHK-136]`. `rendered_block` shows `Ownership: 1 active CHK(s), 0 owned by you` and `[Other users: CHK-136 (…)]`. The SKILL **STOPS** on `next_action: 'stop'` — `/cbp-todo` is NOT auto-triggered. No reassignment language appears.
35
35
 
36
36
  ## Scenario C — no active CHKs anywhere → idle /cbp-todo trigger
37
37
 
38
38
  1. `get_checkpoints({ repo_id, status: 'active' })` returns `[]`.
39
39
  2. Step 5.8: `owned_count = 0`, `total_count = 0`.
40
- 3. **Expected**: envelope `owned_count = 0`, `total_count = 0`, `next_action: 'trigger_todo'`. `rendered_block` shows `Ownership: 0 active CHK(s), 0 owned by this worktree`. The SKILL fires `/cbp-todo` (idle path → checkpoint-create or session-end suggestion).
40
+ 3. **Expected**: envelope `owned_count = 0`, `total_count = 0`, `next_action: 'trigger_todo'`. `rendered_block` shows `Ownership: 0 active CHK(s), 0 owned by you`. The SKILL fires `/cbp-todo` (idle path → checkpoint-create or session-end suggestion).
41
41
 
42
- ## Scenario D — cross-worktree handoff → Step 4.5 marks stale, falls through
42
+ ## Scenario D — stale handoff pointing to a different user's checkpoint handoff marked stale, falls through
43
43
 
44
- 1. The most-recent closed session log contains a handoff payload whose `context.checkpoint_id` resolves to a checkpoint with `worktree_id = "016bd7f2-..."` (a different worktree).
45
- 2. Caller `WORKTREE_ID = "38cd7dfa-..."`.
46
- 3. **Expected**: the orchestrator's handoff freshness gate hits the cross-worktree stale rule (`checkpoint.worktree_id` non-null AND differs from caller) → envelope `handoff.fresh: false`. The mismatched handoff is NOT auto-resumed (`next_action` is never `resume_handoff`); ownership/routing proceed normally per `owned_count`/`total_count`.
44
+ 1. The most-recent closed session log contains a handoff payload whose `context.checkpoint_id` resolves to a checkpoint with `assigned_user_id = "uuid-B"` (a different user).
45
+ 2. Caller `user_id = "uuid-A"`.
46
+ 3. **Expected**: the orchestrator's handoff freshness gate hits the cross-user stale rule (`checkpoint.assigned_user_id` non-null AND differs from caller) → envelope `handoff.fresh: false`. The mismatched handoff is NOT auto-resumed (`next_action` is never `resume_handoff`); ownership/routing proceed normally per `owned_count`/`total_count`.
47
47
 
48
- ## Scenario E — resolver distress (non-tuple-miss) → warning line above Ownership block, session proceeds
48
+ ## Scenario E — whoami distress (identity unresolved) → session proceeds, non-blocking warning
49
49
 
50
- 1. `resolve-worktree --json` returns `{"worktree_id":null,"error_kind":"local_config_read_failed"}` (or any other non-null, non-tuple-miss `error_kind`).
51
- 2. **Expected**: the envelope carries `worktree_error_kind: 'local_config_read_failed'`; `status` stays `'ok'` (non-blocking). `rendered_block` surfaces `⚠ resolve-worktree: local_config_read_failed — local state is broken; routing may be unreliable. Run \`npx codebyplan setup\` to repair.` ABOVE the Ownership block. The orchestrator still activates + creates the session log. `next_action` routes per the `owned_count`/`total_count` values as normal — the skill does NOT hard-stop the way `/cbp-todo` does on the same distress kinds.
52
- 3. **Compound case** (distress typically leaves `worktree_id` null): ownership then classifies every checkpoint with a non-null `worktree_id` as `cross_checkpoints[]` (only truly-null-`worktree_id` checkpoints land in `owned_checkpoints[]`). So if all active checkpoints are assigned, `owned_count = 0` and `next_action: 'stop'` — the distress warning + Ownership block are the only output. The created session log records `worktree_id: null` (the resolver could not read local state); this is expected, not a failure.
50
+ 1. `whoami --json` returns `{"user_id":null,"error_kind":"local_config_read_failed"}` (or any other non-null, non-tuple-miss `error_kind`).
51
+ 2. **Expected**: the envelope carries `user_error_kind: 'local_config_read_failed'`; `status` stays `'ok'` (non-blocking). `rendered_block` surfaces `⚠ whoami: local_config_read_failed — identity could not be resolved; routing may be unreliable. Run \`npx codebyplan whoami\` to check identity.` ABOVE the Ownership block. The orchestrator still activates + creates the session log. `next_action` routes per the `owned_count`/`total_count` values as normal — the skill does NOT hard-stop the way `/cbp-todo` does on the same distress kinds.
52
+ 3. **Compound case** (distress typically leaves `user_id` null): ownership then classifies every checkpoint with a non-null `assigned_user_id` as `cross_checkpoints[]` (only open, null-`assigned_user_id` checkpoints land in `owned_checkpoints[]`). So if all active checkpoints are assigned, `owned_count = 0` and `next_action: 'stop'` — the distress warning + Ownership block are the only output. The created session log records the caller's JWT user server-side; the envelope `user_id: null` (the resolver could not read local identity) is expected, not a failure.
53
+
54
+ ## Scenario F — anonymous session (whoami returns null / signed out) → session proceeds, open checkpoints treated as own
55
+
56
+ 1. `whoami --json` returns `null` (signed out), empty output, or exits non-zero.
57
+ 2. `user_id` is treated as null (anonymous) with `user_error_kind: 'tuple_miss'`.
58
+ 3. `get_checkpoints({ repo_id, status: 'active' })` returns checkpoints with `assigned_user_id` null or set to real user IDs.
59
+ 4. **Expected**: ownership classifies null-`assigned_user_id` checkpoints as `owned_checkpoints[]` (no user to compare against) and non-null-`assigned_user_id` checkpoints as `cross_checkpoints[]` (anonymous caller cannot claim them). `rendered_block` shows the `⚠ Not signed in — run \`npx codebyplan login\` to sign in` line below the User line. `next_action` routes per `owned_count`/`total_count` as normal — the session does NOT hard-stop solely due to anonymous identity. The session log is created in Step 8.
@@ -3,7 +3,8 @@ scope: org-shared
3
3
  name: cbp-setup-cd
4
4
  description: Detect configured CD surfaces, write/update .codebyplan/cd.json via `codebyplan cd init`, scaffold publish.yml and release-desktop.yml GitHub Actions workflows, and walk through environment/approval/OIDC setup. Interactive, idempotent.
5
5
  argument-hint: "[--force]"
6
- effort: xhigh
6
+ model: inherit
7
+ effort: high
7
8
  allowed-tools: Read, Write, Edit, Bash(cat *), Bash(jq *), Bash(test *), Bash(ls *), Bash(diff *), Bash(codebyplan cd *), Bash(npx codebyplan cd *), AskUserQuestion
8
9
  ---
9
10
 
@@ -3,7 +3,8 @@ scope: org-shared
3
3
  name: cbp-setup-ci
4
4
  description: Detect CI platforms, write/update .codebyplan/ci.json, scaffold the GitHub Actions CI workflow, and enforce the required CI status check on the main branch. Interactive, idempotent.
5
5
  argument-hint: "[--force]"
6
- effort: xhigh
6
+ model: inherit
7
+ effort: high
7
8
  allowed-tools: Read, Write, Edit, Bash(cat *), Bash(jq *), Bash(test *), Bash(ls *), Bash(codebyplan ci *), Bash(npx codebyplan ci *), Bash(gh api *), Bash(gh auth *), AskUserQuestion
8
9
  ---
9
10
 
@@ -2,7 +2,8 @@
2
2
  name: cbp-setup-e2e
3
3
  description: Detect installed E2E frameworks, ask which to enable, record credentials source (gitignored env-file path + var names only, never secrets), and write/refresh .codebyplan/e2e.json. Interactive, idempotent.
4
4
  argument-hint: "[--force]"
5
- effort: xhigh
5
+ model: inherit
6
+ effort: high
6
7
  allowed-tools: Read, Write, Edit, Bash(cat *), Bash(jq *), Bash(which *), Bash(test *), Bash(mkdir *), Bash(cp *), Bash(echo *), Bash(date *), Bash(mv *), Bash(git check-ignore *), AskUserQuestion, mcp__codebyplan__get_repos
7
8
  ---
8
9
 
@@ -2,7 +2,8 @@
2
2
  name: cbp-setup-eslint
3
3
  description: Detect each app's tech stack, resolve matching DB ESLint presets, confirm which to enable per app, run `codebyplan eslint init` to generate eslint.config.mjs, and write/refresh .codebyplan/eslint.json. Interactive, idempotent.
4
4
  argument-hint: "[--force]"
5
- effort: xhigh
5
+ model: inherit
6
+ effort: high
6
7
  allowed-tools: Read, Write, Edit, Bash(cat *), Bash(jq *), Bash(test *), Bash(ls *), Bash(mkdir *), Bash(cp *), Bash(echo *), Bash(mv *), Bash(npx codebyplan eslint *), AskUserQuestion, mcp__codebyplan__get_repos, mcp__codebyplan__get_eslint_presets
7
8
  ---
8
9
 
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: cbp-ship
3
3
  description: Orchestrate runtime deployment for a checkpoint — Vercel web, EAS mobile (Expo Go dev build / TestFlight preview), Tauri desktop, npm package publish, VS Code extension, Railway backend, Supabase migrations. Detects configured surfaces, walks the user through what to deploy, executes per-surface deploy steps, verifies each landed.
4
+ model: inherit
4
5
  effort: xhigh
5
6
  ---
6
7
 
@@ -202,6 +203,10 @@ If a surface fails:
202
203
 
203
204
  EXCEPTION: `supabase` migration push failure halts the rest. Schema mismatch downstream is worse than partial shipment.
204
205
 
206
+ #### Orchestration (optional)
207
+
208
+ Step 5's per-surface deploys — the independent tails after the mandatory `supabase`-first step — MAY be authored as a `Workflow(...)` script for deterministic parallel fan-out instead of ad-hoc sequencing. This is opt-in (ultracode session or explicit user request); the sequential flow above (including the `supabase`-first ordering) stays the DEFAULT and is unchanged. See `rules/workflow-orchestration.md`.
209
+
205
210
  ### Step 6 — Verify each surface landed
206
211
 
207
212
  After each surface deploys, run its verification:
@@ -3,7 +3,8 @@ name: cbp-ship-configure
3
3
  description: Configure shipment for one or more surfaces in the current repo — Vercel link, EAS project + eas.json scaffold, Apple credentials probe, npm publish auth check (including `codebyplan` asset-publish automation via the publish-on-main workflow), Railway project link, Supabase access token verify; Supabase GitHub branching integration via /cbp-supabase-setup. Interactive step-by-step; never stores credentials in the repo.
4
4
  argument-hint: [--surface=<id>]
5
5
  allowed-tools: Read, Write, Edit, Bash(which *), Bash(vercel *), Bash(eas *), Bash(npm *), Bash(railway *), Bash(jq *), Bash(mkdir *), Bash(cp *), Bash(echo *), Skill(cbp-supabase-setup)
6
- effort: xhigh
6
+ model: inherit
7
+ effort: high
7
8
  ---
8
9
 
9
10
  # Ship Configure Command
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: cbp-ship-main
3
3
  description: Ship feat branch to production branch via PR — thin wrapper around `codebyplan ship`
4
+ model: inherit
4
5
  effort: high
5
6
  ---
6
7
 
@@ -4,6 +4,7 @@ name: cbp-standalone-task-check
4
4
  description: AI production review for the current standalone task
5
5
  argument-hint: [task] # e.g. `45` (standalone TASK-45)
6
6
  triggers: [cbp-standalone-task-testing]
7
+ model: inherit
7
8
  effort: high
8
9
  ---
9
10