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
@@ -1,8 +1,9 @@
1
1
  ---
2
2
  name: cbp-build-cc-mode
3
- description: Audit + apply the CHK-109 model/effort convention across every authoring skill and agent under `packages/codebyplan-package/templates/`. Skills set `effort:` only and inherit the session model; agents pin `model:` + `effort:`. Bare invocation audits and reports frontmatter gaps; with a path argument, edits the target file's frontmatter to the convention-decided values.
3
+ description: Audit + apply the CHK-229 model/effort convention across every authoring skill and agent under `packages/codebyplan-package/templates/`. Skills set `model: inherit` + `effort:`; agents pin `model:` + `effort:`. Bare invocation audits and reports frontmatter gaps; with a path argument, edits the target file's frontmatter to the convention-decided values.
4
4
  argument-hint: "[path-to-agent-or-skill]"
5
5
  allowed-tools: Read, Write, Edit, Glob, Grep
6
+ model: inherit
6
7
  effort: xhigh
7
8
  ---
8
9
 
@@ -12,8 +13,8 @@ Audit or apply the canonical model/effort frontmatter convention across every au
12
13
 
13
14
  The convention splits by surface:
14
15
 
15
- - **Skills do NOT pin `model:`.** A skill's inline turn runs inside the user's active session, so it must inherit the session model. Pinning a model (a) forces a model the user did not choose and (b) can carry the session's 1M `[1m]` context tier onto the skill, producing `API Error: Usage credits required for 1M context`. Skills set `effort:` only.
16
- - **Agents pin `model:` explicitly.** A spawned/forked subagent should not silently inherit the parent's model or context tier — every agent states its model so each subagent's cost/quality is auditable. Agents set both `model:` and `effort:`.
16
+ - **Skills set `model: inherit` AND `effort:`.** The `model: inherit` value signals explicitly that the skill inherits the user's active session model it is the standard value. A non-inherit model or an absent model field is a gap. A justified explicit pin (e.g. `model: sonnet`) is permitted when documented here as an exception.
17
+ - **Agents pin `model:` explicitly.** A spawned/forked subagent must not silently inherit the parent's model or context tier — every agent states its model so each subagent's cost/quality is auditable. Agents set both `model:` and `effort:`. `model: inherit` is NOT permitted for agents.
17
18
 
18
19
  ## When to Use
19
20
 
@@ -23,33 +24,40 @@ The convention splits by surface:
23
24
 
24
25
  ## Decision Matrix
25
26
 
26
- ### Skills — `effort:` only, never `model:`
27
+ ### Skills — `model: inherit` + `effort:`
27
28
 
28
- Omit `model:` entirely (inherit the session model). Set `effort:` per the skill's nature. Default `effort: xhigh`; tiers:
29
+ Set `model: inherit` (the standard value) and `effort:` per the skill's nature. Default `effort: xhigh`; tiers:
29
30
 
30
- | effort | use for | examples |
31
- | -------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
32
- | `xhigh` | deep authoring / planning / orchestration (most skills) | build-cc-*, checkpoint-check/end/plan, round-start/input/execute, task-create/start/complete/testing, standalone-task-*, frontend-*, ship, ship-configure, supabase-*, setup-e2e/eslint, session-end |
33
- | `high` | summary / orchestration, lighter than xhigh | checkpoint-create, checkpoint-start, checkpoint-update, round-end, task-check, standalone-task-check, ship-main, merge-main |
34
- | `medium` | moderate, scoped sync work | refresh-infra |
35
- | `low` | pure mechanical / dispatch / templated work | checkpoint-complete, round-check, round-complete, round-update, todo, session-start, git-commit, git-branch-feat-create |
31
+ | effort | use for | examples |
32
+ | -------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
33
+ | `xhigh` | deep authoring / planning / orchestration (most skills) | build-cc-*, checkpoint-check/end/plan, finalize, frontend-design, map-architecture, round-build/plan, ship, standalone-task-complete, supabase-migrate, task-start, verify |
34
+ | `high` | lighter orchestration, review, setup, targeted flows | checkpoint-create/start, frontend-ui/ux, merge-main, refresh-arch-map, session-end, setup-cd/ci/e2e/eslint, ship-configure/main, standalone-task-check/create/start/testing, stripe, supabase-branch-check/setup, task-create |
35
+ | `medium` | moderate, scoped sync work | checkpoint-update, clear-prep, todo |
36
+ | `low` | pure mechanical / dispatch / templated work | checkpoint-complete, clear-continue, git-commit, git-branch-feat-create, round-complete, session-start |
36
37
 
37
- A skill that carries a `model:` line is a **gap** — remove it unless a deliberate, documented exception is recorded here (currently none).
38
+ A skill with an absent `model:` field or a non-`inherit` model value is a **gap** — add `model: inherit` or document the exception here before applying a different pin.
39
+
40
+ > **Note on effort tiers**: `max` is the highest frontmatter effort tier. `ultracode` is a SESSION-ONLY runtime mode (`/effort ultracode`) — it is NOT a valid frontmatter value and `validate-skill.sh` rejects `effort: ultracode` with an explicit error.
38
41
 
39
42
  ### Agents — `model:` + `effort:`
40
43
 
41
- Default `model: sonnet` + `effort: xhigh`. Fifteen of the 17 authoring agents take the default (`cbp-cc-executor`, `cbp-database-agent`, `cbp-improve-claude`, `cbp-research`, `cbp-round-builder`, `cbp-security-agent`, `cbp-stripe-agent`, `cbp-verify-reviewer`, `cbp-round-planner`, `cbp-testing-qa-agent`, `cbp-e2e-playwright`, `cbp-e2e-maestro`, `cbp-e2e-tauri`, `cbp-e2e-vscode`, `cbp-e2e-xcuitest`). The other two are exceptions:
44
+ Default `model: sonnet` + `effort: xhigh`. Ten of the 17 authoring agents take the default (`cbp-cc-executor`, `cbp-database-agent`, `cbp-improve-claude`, `cbp-research`, `cbp-round-builder`, `cbp-round-planner`, `cbp-security-agent`, `cbp-stripe-agent`, `cbp-testing-qa-agent`, `cbp-verify-reviewer`). The other seven are exceptions:
42
45
 
43
46
  | agent | model | effort | reason |
44
47
  | -------------------- | ------ | ------ | ----------------------------------------------------------------------------------- |
45
48
  | cbp-mechanical-edits | haiku | low | Mechanical rename/substitution/frontmatter-edit subagent; no judgment, pure dispatch |
46
49
  | cbp-map-architecture | sonnet | high | Read-only module analyzer; bounded structured-map generation, lighter than xhigh |
50
+ | cbp-e2e-maestro | sonnet | high | E2E specialist: bounded test-execution scope; sonnet+high calibrated in CHK-229 |
51
+ | cbp-e2e-playwright | sonnet | high | E2E specialist: bounded test-execution scope; sonnet+high calibrated in CHK-229 |
52
+ | cbp-e2e-tauri | sonnet | high | E2E specialist: bounded test-execution scope; sonnet+high calibrated in CHK-229 |
53
+ | cbp-e2e-vscode | sonnet | high | E2E specialist: bounded test-execution scope; sonnet+high calibrated in CHK-229 |
54
+ | cbp-e2e-xcuitest | sonnet | high | E2E specialist: bounded test-execution scope; sonnet+high calibrated in CHK-229 |
47
55
 
48
56
  `model: inherit` is NOT permitted for agents — pin an explicit alias (`sonnet` / `haiku`) or a full ID.
49
57
 
50
58
  ## Precedence Rule
51
59
 
52
- A skill's `effort:` applies to the inline-running turn (the orchestrator turn that invokes the skill); the skill runs on that turn's inherited model. An agent's `model:` / `effort:` apply to the spawned/forked subagent context. For `context: fork` skills, the agent named in `agent:` governs the forked subagent (per the official Claude Code spec) — so a forked skill's model comes from that agent, not from the skill.
60
+ A skill's `effort:` applies to the inline-running turn (the orchestrator turn that invokes the skill); the skill runs on that turn's inherited model (declared via `model: inherit`). An agent's `model:` / `effort:` apply to the spawned/forked subagent context. For `context: fork` skills, the agent named in `agent:` governs the forked subagent (per the official Claude Code spec) — so a forked skill's model comes from that agent, not from the skill.
53
61
 
54
62
  ## Audit Mode
55
63
 
@@ -70,10 +78,10 @@ Invoked with a path argument (the target `SKILL.md` or agent `.md`). Procedure:
70
78
  1. Read the file. Identify the name from the `name:` frontmatter (or the path basename).
71
79
  2. Look up the target from the convention above.
72
80
  3. Use Edit to set the frontmatter to the target, preserving every other field and the entire body:
73
- - **Skill**: REMOVE any `model:` line; set/keep a valid `effort:` (default `xhigh`).
81
+ - **Skill**: SET `model: inherit` if absent (or correct a non-inherit pin); set/keep a valid `effort:` (default `xhigh`).
74
82
  - **Agent**: set `model:` and `effort:` to the table values.
75
- 4. If the name is NOT covered, surface via AskUserQuestion: current state, propose the default (skill → no `model:` + `xhigh`; agent → `sonnet` + `xhigh`), and ask whether to (a) record an exception entry here first, or (b) apply the default.
83
+ 4. If the name is NOT covered, surface via AskUserQuestion: current state, propose the default (skill → `model: inherit` + `xhigh`; agent → `sonnet` + `xhigh`), and ask whether to (a) record an exception entry here first, or (b) apply the default.
76
84
 
77
85
  ## Self-Conformance
78
86
 
79
- This skill is itself a skill: its frontmatter sets `effort: xhigh` and NO `model:`. The first audit run after editing this file MUST emit `ok` for `packages/codebyplan-package/templates/skills/cbp-build-cc-mode/SKILL.md` — if it doesn't, the convention is out of sync with reality and must be reconciled before any further apply.
87
+ This skill is itself a skill: its frontmatter declares `model: inherit` + `effort: xhigh`. The first audit run after editing this file MUST emit `ok` for `packages/codebyplan-package/templates/skills/cbp-build-cc-mode/SKILL.md` — if it doesn't, the convention is out of sync with reality and must be reconciled before any further apply.
@@ -3,6 +3,7 @@ name: cbp-build-cc-rule
3
3
  description: Build a path-scoped rule file at .claude/rules/{name}.md following the official memory/rules spec (paths globs, always-loaded vs on-demand, symlinks) plus CBP conventions (scope field for structural classification — required only on user-created rules (validate-structure-scope.sh), narrow-paths discipline; hook warns at 100 lines, blocks at 200).
4
4
  argument-hint: '[name] [--scope=project|user] [--paths="glob,glob"]'
5
5
  allowed-tools: Read, Write, Edit, Glob, Grep
6
+ model: inherit
6
7
  effort: xhigh
7
8
  ---
8
9
 
@@ -3,6 +3,7 @@ name: cbp-build-cc-settings
3
3
  description: Create or update Claude Code settings.json / settings.local.json / managed-settings.json following the official settings spec — scopes, permissions, hooks, sandbox, attribution, plugins, env vars, JSON schema validation.
4
4
  argument-hint: "[action] [--scope=user|project|local|managed]"
5
5
  allowed-tools: Read, Write, Edit, Glob, Grep, Bash(jq *)
6
+ model: inherit
6
7
  effort: xhigh
7
8
  ---
8
9
 
@@ -25,7 +25,7 @@ Precedence is `deny > ask > allow`; arrays union across scopes (managed/user/pro
25
25
  - **Non-lifecycle, non-shipment `/cbp-*` skills** — authoring (`cbp-build-cc-*`), frontend (`cbp-frontend-*`), git (`cbp-git-*`, `cbp-merge-main`, `cbp-refresh-infra`), round work (`cbp-round-plan`, `cbp-verify` — `cbp-verify` is the autonomous verify stage that runs deterministic gates, proves execution, spawns the fresh-context reviewer, and routes to `cbp-round-complete` or `cbp-round-plan`, so it runs without a prompt), setup/configure (`cbp-setup-*`, `cbp-ship-configure`, `cbp-supabase-*`), task prep (`cbp-task-create`/`-start`, `cbp-standalone-task-check`/`-testing`), planning (`cbp-checkpoint-plan`/`-update`), plus `cbp-session-start` and `cbp-todo`. Invoking a skill is the intended mode of operation; the gated side effects happen inside via the Bash/MCP tools the skill calls, which carry their own tiering. The lifecycle/state-transition and plan-approval skills are the exception — they live in `ask` (next section).
26
26
  - **All `mcp__codebyplan__*` reads** (`get_*`, `list_*`, `search_*`, `health_check`, `lookup_symbol`, `resolve_library_id`, `get_chunk`).
27
27
  - **Routine workflow-write MCP tools** the pipeline calls many times per task: create/update/complete checkpoint, task, and round; session log + session-state writes; `create_worktree`, `add_library`, `flag_stale_chunk`, `update_server_config`, `update_eslint_repo_config`, `update_task_template`. Gating these with `ask` would make the autonomous workflow unusable.
28
- - **Read/safe CLI commands** (both `codebyplan X` and `npx codebyplan X`): `whoami`, `resolve-worktree`, `statusline`, `ports`, `tech-stack`, `eslint`, `round`, `help`, `--version`.
28
+ - **Read/safe CLI commands** (both `codebyplan X` and `npx codebyplan X`): `whoami`, `statusline`, `ports`, `tech-stack`, `eslint`, `round`, `help`, `--version`.
29
29
 
30
30
  ### `ask` — the deliberate confirm-gate
31
31
 
@@ -54,7 +54,7 @@ Source: official Claude Code settings spec. Grouped by category. All fields are
54
54
  | `model` | Override default model |
55
55
  | `modelOverrides` | Map model IDs (e.g. Bedrock profile ARNs) |
56
56
  | `availableModels` | Restrict which models `/model` exposes |
57
- | `effortLevel` | Persist effort across sessions |
57
+ | `effortLevel` | Persist effort across sessions. Valid values: `low \| medium \| high \| xhigh` only — `max` and `ultracode` are session-only and rejected here. See `rules/effort-and-ultracode.md`. |
58
58
  | `alwaysThinkingEnabled` | Extended thinking on by default |
59
59
  | `showThinkingSummaries` | Show thinking summaries |
60
60
 
@@ -3,6 +3,7 @@ name: cbp-build-cc-skill
3
3
  description: Build a Claude Code skill at .claude/skills/{name}/SKILL.md following the official skills spec — frontmatter, supporting files (templates, examples, reference, scripts), invocation control, argument substitution, dynamic context, fork-to-subagent, allowed-tools.
4
4
  argument-hint: "[skill-name] [--scope=project|user] [--fork] [--disable-model-invocation]"
5
5
  allowed-tools: Read, Write, Edit, Glob, Grep, Bash(mkdir *), Bash(chmod *)
6
+ model: inherit
6
7
  effort: xhigh
7
8
  ---
8
9
 
@@ -97,7 +98,7 @@ Key fields by use case:
97
98
  | Hide from `/` menu | `user-invocable: false` |
98
99
  | Pre-approve tools | `allowed-tools: Bash(git add *) Bash(git commit *)` |
99
100
  | Accept arguments | `argument-hint: [file] [mode]`, optionally `arguments: [file mode]` for named `$file`/`$mode` |
100
- | Set effort (do NOT set model) | `effort: xhigh` default for plugin skills; lower (`high`/`low`) per [/cbp-build-cc-mode](../build-cc-mode/SKILL.md). **Omit `model:`** so the skill inherits the active session model pinning one forces a model the user didn't choose and can carry the session's 1M `[1m]` tier onto the skill (→ "usage credits required for 1M context"). Pin `model:` only as a deliberate, documented exception |
101
+ | Set model + effort | `model: inherit` (the standard value — explicitly signals session-model inheritance) and `effort: xhigh` (default for plugin skills; lower tiers `high`/`medium`/`low` per [/cbp-build-cc-mode](../build-cc-mode/SKILL.md)). A non-`inherit` model pin forces a model the user didn't choose and can carry the session's 1M `[1m]` tier onto the skill (→ "usage credits required for 1M context"), so pin only as a deliberate, documented exception |
101
102
  | Path-scoped auto-load | `paths: ["src/api/**/*.ts"]` |
102
103
  | Fork to subagent | `context: fork`, `agent: Explore` |
103
104
 
@@ -12,7 +12,7 @@ Source: official Claude Code skills spec. All fields are optional; `description`
12
12
  | `disable-model-invocation` | `true` → only user can invoke (via `/name`). Upstream skills that auto-trigger this skill MUST emit a `Next: /name` directive instead — model invocation is blocked by the runtime; see SKILL.md Step 4 "Convention: User-only / permission-gated finalizer" |
13
13
  | `user-invocable` | `false` → hidden from `/` menu, Claude-only |
14
14
  | `allowed-tools` | Pre-approve tools while the skill is active |
15
- | `model` | Override model for this skill's turn. **CBP skills normally OMIT this** so the skill inherits the active session model. Pinning a model (e.g. `sonnet`) forces that model and can carry the session's 1M `[1m]` context tier onto the skill, triggering "usage credits required for 1M context". Set it only as a deliberate, documented exception — see [/cbp-build-cc-mode](../../build-cc-mode/SKILL.md) |
15
+ | `model` | Model for this skill's turn. **CBP skills set `model: inherit`** (the standard value explicitly signals session-model inheritance). A non-`inherit` pin (e.g. `sonnet`) forces that model and can carry the session's 1M `[1m]` context tier onto the skill, triggering "usage credits required for 1M context"; use only as a deliberate, documented exception — see [/cbp-build-cc-mode](../../build-cc-mode/SKILL.md) |
16
16
  | `effort` | Override effort level (`low`/`medium`/`high`/`xhigh`/`max`). **Plugin skills authored in CBP MUST set this explicitly** (no commented-out placeholder); defaults to `xhigh`. See [/cbp-build-cc-mode](../../build-cc-mode/SKILL.md) for the matrix |
17
17
  | `context` | `fork` → run in a subagent |
18
18
  | `agent` | Subagent type when `context: fork` — built-in or custom |
@@ -57,19 +57,22 @@ if grep -qE '^scope:\s*' <<< "$fm"; then
57
57
  fi
58
58
  fi
59
59
 
60
- # Model — skills MUST NOT pin a model. A skill's inline turn runs in the user's
61
- # active session, so it inherits the session model. Pinning one forces a model the
62
- # user didn't choose and can carry the session's 1M [1m] context tier onto the skill
63
- # ("API Error: Usage credits required for 1M context"). Agents pin model explicitly
64
- # (validate-agent.sh) skills never do.
65
- if grep -qE '^model:' <<< "$fm"; then
66
- model=$(grep -E '^model:' <<< "$fm" | head -1 | sed -E 's/^model:[[:space:]]*//; s/[[:space:]]*$//')
67
- err "skills must NOT set 'model:' (found '$model') — skills inherit the session model; remove the line (see /cbp-build-cc-mode)"
60
+ # Model — skills MUST declare 'model: inherit' to signal session-model inheritance
61
+ # explicitly. Absent = warning (should be added); non-enum value = error.
62
+ # Valid values: inherit | sonnet | opus | haiku | fable | opusplan | claude-<id> | <id>[1m]
63
+ # Agents pin explicit model values (validate-agent.sh); skills use 'inherit'.
64
+ model_val=$(grep -E '^model:' <<< "$fm" | head -1 | sed -E 's/^model:[[:space:]]*//; s/[[:space:]]*$//' || true)
65
+ if [ -z "$model_val" ]; then
66
+ echo " WARN: model: absent add 'model: inherit' (skills must declare session-model inheritance)" >&2
67
+ elif ! [[ "$model_val" =~ ^(inherit|sonnet|opus|haiku|fable|opusplan|claude-[a-z0-9][a-z0-9.-]*|.*\[1m\])$ ]]; then
68
+ err "model: invalid value '$model_val' (valid values: inherit | sonnet | opus | haiku | fable | opusplan | claude-<id> | <id>[1m])"
68
69
  fi
69
70
 
70
71
  # Effort (if present)
71
72
  effort=$(grep -E '^effort:' <<< "$fm" | head -1 | sed -E 's/^effort:[[:space:]]*//; s/[[:space:]]*$//; s/^"(.*)"$/\1/' || true)
72
- if [ -n "$effort" ] && [[ ! "$effort" =~ ^(low|medium|high|xhigh|max)$ ]]; then
73
+ if [ "$effort" = "ultracode" ]; then
74
+ err "effort: ultracode is a session-only mode, not a frontmatter effort — use max + /effort ultracode"
75
+ elif [ -n "$effort" ] && [[ ! "$effort" =~ ^(low|medium|high|xhigh|max)$ ]]; then
73
76
  err "effort invalid: '$effort'"
74
77
  fi
75
78
 
@@ -3,6 +3,7 @@ scope: org-shared
3
3
  name: cbp-checkpoint-check
4
4
  description: Full re-evaluation of a checkpoint with before/after comparison
5
5
  argument-hint: [CHK-NNN]
6
+ model: inherit
6
7
  effort: xhigh
7
8
  ---
8
9
 
@@ -133,6 +134,10 @@ Aggregate the files touched across all tasks (reusing Step 4's deduplicated tabl
133
134
 
134
135
  See `cbp-verify` reference `findings-presentation.md` "Infra Issue Absorption Contract — Infra-Class Issue Catalog" row "Checkpoint-level e2e failure" for the routing rationale.
135
136
 
137
+ #### Orchestration (optional)
138
+
139
+ Step 5b's parallel whole-checkpoint `cbp-e2e-*` specialist dispatch MAY be authored as a `Workflow(...)` script instead of ad-hoc `Task`/`Agent` spawning — for deterministic fan-out across eligible frameworks and schema-validated aggregation. This is opt-in (ultracode session or explicit user request); the dispatch flow above stays the DEFAULT and is unchanged. See `rules/workflow-orchestration.md`.
140
+
136
141
  ### Step 6: User Discussion
137
142
 
138
143
  Present findings and discuss with user:
@@ -2,6 +2,7 @@
2
2
  name: cbp-checkpoint-complete
3
3
  description: Complete a checkpoint after all tasks are done
4
4
  argument-hint: [checkpoint-number]
5
+ model: inherit
5
6
  effort: low
6
7
  ---
7
8
 
@@ -2,6 +2,7 @@
2
2
  name: cbp-checkpoint-create
3
3
  description: Mechanical checkpoint creation — capture the user's description, infer title + goal, dedup against existing modules, create the checkpoint row + feat branch, then hand off to /cbp-checkpoint-plan for deep planning. Creates ZERO tasks.
4
4
  argument-hint: [checkpoint description]
5
+ model: inherit
5
6
  effort: high
6
7
  ---
7
8
 
@@ -59,35 +60,25 @@ Skip when the description has zero domain matches OR the user already named a ta
59
60
 
60
61
  Lightweight inference from the description — no deep analysis. **Title**: concise, ≤80 chars. **Goal**: ≤300 chars, a faithful restatement of intent (not a plan).
61
62
 
62
- ### Step 6: Claim-or-Open Prompt
63
-
64
- Ask the user via AskUserQuestion whether to claim this checkpoint now:
65
-
66
- - **Claim for me + this worktree** (default) — resolve `npx codebyplan resolve-worktree 2>/dev/null` and set it as the checkpoint `worktree_id` at create. The creator carries momentum straight through plan → start.
67
- - **Leave it open** — create with `worktree_id` null so anyone free can claim it later via `/cbp-checkpoint-start`.
68
-
69
- Record the choice; it drives both the create call (Step 7) and the plan→start routing in `/cbp-checkpoint-plan`.
70
-
71
- ### Step 7: Create Checkpoint Row
63
+ ### Step 6: Create Checkpoint Row
72
64
 
73
65
  `codebyplan checkpoint create` (CLI write-through: writes `.codebyplan/state/checkpoints/<id>.json` + REST). Pass flags:
74
66
  - `--repo-id` (from `.codebyplan/repo.json`), `--title`, `--goal`, `--deadline`, `--status pending`
75
67
  - `--ideas` JSON `[{ description: <raw user text> }]`
76
- - `--worktree-id` the resolved worktree **only if the user chose "claim"**; omit when "leave open"
77
68
 
78
- Do **not** pass `--number` — the database auto-assigns the next per-repo checkpoint number via a `BEFORE INSERT` trigger (advisory-locked `MAX(number)+1` scoped to `repo_id`). The DB-assigned number comes back on the created row (and is written into `.codebyplan/state/checkpoints/<id>.json`); read it for the branch slug (Step 8) and the result display (Step 9).
69
+ Do **not** pass `--number` — the database auto-assigns the next per-repo checkpoint number via a `BEFORE INSERT` trigger (advisory-locked `MAX(number)+1` scoped to `repo_id`). The DB-assigned number comes back on the created row (and is written into `.codebyplan/state/checkpoints/<id>.json`); read it for the branch slug (Step 7) and the result display (Step 8).
79
70
 
80
71
  Break-glass fallback: MCP `create_checkpoint` (also omit `number`) when the CLI is unavailable.
81
72
 
82
- This is the first identity-stamping point when claiming, passing `worktree_id` here engages the CHK-104 hard-lock from birth. No `context`, `research`, `plan`, or tasks are written here.
73
+ Assignment (`assigned_user_id`) is stamped server-side from the caller's JWT when the checkpoint is activated via `/cbp-checkpoint-start` it is not set at create time. No `context`, `research`, `plan`, or tasks are written here.
83
74
 
84
- ### Step 8: Create + Switch to Feat Branch
75
+ ### Step 7: Create + Switch to Feat Branch
85
76
 
86
- `{NNN}` below is the DB-assigned checkpoint number read back from the Step 7 `codebyplan checkpoint create` response.
77
+ `{NNN}` below is the DB-assigned checkpoint number read back from the Step 6 `codebyplan checkpoint create` response.
87
78
 
88
79
  Read `.codebyplan/git.json` `branch_config.production` (default `"main"`) as `BASE`. codebyplan repos are main-only — never create or branch from a `development`/integration branch.
89
80
 
90
- **8.1 — Reuse the cloud-created branch when present.** When the repo is GitHub-connected, the CHK-207 `create-feat-branch` Edge Function fires on the Step 7 row INSERT, creates `feat/CHK-{NNN}-<slug>` on origin, and writes `branch_name` back to the checkpoint row. Creating a second, differently-slugged branch here orphans the cloud one — so re-read the row first:
81
+ **7.1 — Reuse the cloud-created branch when present.** When the repo is GitHub-connected, the CHK-207 `create-feat-branch` Edge Function fires on the Step 6 row INSERT, creates `feat/CHK-{NNN}-<slug>` on origin, and writes `branch_name` back to the checkpoint row. Creating a second, differently-slugged branch here orphans the cloud one — so re-read the row first:
91
82
 
92
83
  ```bash
93
84
  sleep 5 # give the INSERT webhook a moment to write branch_name back
@@ -95,14 +86,14 @@ npx codebyplan sync 2>/dev/null || true
95
86
  BRANCH=$(jq -r '.branch_name // empty' ".codebyplan/state/checkpoints/{checkpoint-id}.json" 2>/dev/null)
96
87
  ```
97
88
 
98
- (Break-glass: MCP `get_checkpoints` and read the row's `branch_name`.) If `BRANCH` is non-empty, check out the existing remote branch and skip 8.2 entirely — do NOT push (it already exists on origin) and do NOT persist `--branch-name` (the Edge Function already recorded it):
89
+ (Break-glass: MCP `get_checkpoints` and read the row's `branch_name`.) If `BRANCH` is non-empty, check out the existing remote branch and skip 7.2 entirely — do NOT push (it already exists on origin) and do NOT persist `--branch-name` (the Edge Function already recorded it):
99
90
 
100
91
  ```bash
101
92
  git fetch origin "$BRANCH"
102
93
  git checkout -b "$BRANCH" --track "origin/$BRANCH"
103
94
  ```
104
95
 
105
- **8.2 — Fallback: create the branch locally.** Only when `BRANCH` is empty (repo not GitHub-connected, or the webhook hasn't landed). Compute the slug deterministically:
96
+ **7.2 — Fallback: create the branch locally.** Only when `BRANCH` is empty (repo not GitHub-connected, or the webhook hasn't landed). Compute the slug deterministically:
106
97
 
107
98
  ```bash
108
99
  SLUG=$(codebyplan slug "{checkpoint title}")
@@ -121,13 +112,13 @@ Persist the branch via `codebyplan checkpoint update --id <checkpoint-id> --bran
121
112
 
122
113
  **Note — Supabase preview branch**: no Supabase branch is created here. Creation is lazy — it happens on the first DB change when `/cbp-supabase-migrate` runs on this feat branch, which provisions a Supabase branch named identically to the git branch. See `cbp-supabase-migrate` Step 2.3 for the creation protocol.
123
114
 
124
- ### Step 9: Show Result + Auto-Trigger Plan
115
+ ### Step 8: Show Result + Auto-Trigger Plan
125
116
 
126
117
  ```
127
118
  ## Checkpoint Created
128
119
 
129
120
  **CHK-NNN**: [title] • **Deadline**: [date] • **Branch**: feat/CHK-NNN-slug
130
- **Claim**: [claimed by this worktree / left open]
121
+ **Assignment**: stamped on activation via /cbp-checkpoint-start
131
122
  **Worktree**: `npx codebyplan worktree add CHK-{NNN}`
132
123
 
133
124
  Now planning CHK-NNN… handing off to /cbp-checkpoint-plan.
@@ -138,6 +129,6 @@ Auto-trigger `/cbp-checkpoint-plan {NNN}` in the same context. This skill create
138
129
  ## Integration
139
130
 
140
131
  - **Runs inline**: mechanical setup only — no assessment, research, Q&A, plan, or tasks
141
- - **Reads**: `.codebyplan/state/checkpoints/*.json` (local-first; `npx codebyplan sync` if stale; MCP `get_checkpoints` break-glass); `.codebyplan/repo.json`, `.codebyplan/git.json`; `npx codebyplan resolve-worktree`
142
- - **Writes**: `codebyplan checkpoint create` (description-only ideas + deadline + optional worktree_id), `codebyplan checkpoint update --branch-name` (break-glass: MCP `create_checkpoint` / `update_checkpoint`)
132
+ - **Reads**: `.codebyplan/state/checkpoints/*.json` (local-first; `npx codebyplan sync` if stale; MCP `get_checkpoints` break-glass); `.codebyplan/repo.json`, `.codebyplan/git.json`
133
+ - **Writes**: `codebyplan checkpoint create` (description-only ideas + deadline), `codebyplan checkpoint update --branch-name` (break-glass: MCP `create_checkpoint` / `update_checkpoint`)
143
134
  - **Triggers**: `/cbp-checkpoint-plan` (auto)
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: cbp-checkpoint-end
3
3
  description: Single point for all shipment — branch promotion to main via /cbp-ship-main, runtime deploy via /cbp-ship, branch cleanup, summary. Standalone tasks bypass shipment entirely.
4
+ model: inherit
4
5
  effort: xhigh
5
6
  ---
6
7
 
@@ -161,6 +162,10 @@ If `/cbp-ship` reports `aborted_at` (user aborted) or any surface failed verific
161
162
 
162
163
  If the repo has zero configured surfaces (very early-stage), `/cbp-ship` exits with `## No deployable surfaces configured` — that's a success state, continue to cleanup.
163
164
 
165
+ #### Orchestration (optional)
166
+
167
+ The multi-step shipment coordinated here (Step 5 `/cbp-ship-main` → Step 7 `/cbp-ship` → screenshot upload) MAY be expressed as a `Workflow(...)` pipeline instead of ad-hoc sequential invocation. This is opt-in (ultracode session or explicit user request); the sequential flow above stays the DEFAULT and is unchanged. See `rules/workflow-orchestration.md`.
168
+
164
169
  ### Step 7.5: Upload E2E Screenshots to DB (best-effort)
165
170
 
166
171
  After `/cbp-ship` completes successfully, upload the checkpoint's new/changed committed E2E screenshots to the CodeByPlan DB so they can be reviewed per-checkpoint in the web UI (CHK-171). This step is **best-effort and non-blocking** — a failure here MUST NOT halt shipment or cleanup.
@@ -260,6 +265,41 @@ After the feat branch git delete, run the same conditional Supabase teardown for
260
265
  - If not found: no-op silently — idempotent, not-found is success.
261
266
  - 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.
262
267
 
268
+ ### Step 9.5: Physical Git-Worktree Cleanup
269
+
270
+ After the feat branch has been git-deleted (Step 9), check whether a git worktree is still
271
+ checked out to that now-deleted branch and clean it up if safe.
272
+
273
+ ```bash
274
+ git worktree list --porcelain
275
+ ```
276
+
277
+ Scan the output for any `worktree` entry whose `branch` field matches `refs/heads/$FEAT_BRANCH`
278
+ (i.e. the feat branch just deleted in Step 9). For each matching worktree path:
279
+
280
+ **Case A — the current session is NOT inside that worktree path:**
281
+
282
+ ```bash
283
+ codebyplan worktree remove <path>
284
+ git worktree prune
285
+ ```
286
+
287
+ Record the removed path in `WORKTREES_REMOVED[]`. If `codebyplan worktree remove` exits
288
+ non-zero, emit a non-blocking warning and continue — a failed removal does not halt shipment.
289
+
290
+ **Case B — the current session IS inside that worktree path (i.e. `$PWD` starts with
291
+ `<path>`):**
292
+
293
+ Do NOT self-remove. Surface a single directive (no A/B/C menu):
294
+
295
+ > "This session is inside the worktree at `<path>`. After switching to your main checkout,
296
+ > run `codebyplan worktree remove <path>` to clean it up."
297
+
298
+ Record the path in `WORKTREES_REMOVED[]` as `{ path, status: 'pending_manual_cleanup' }`.
299
+
300
+ If `git worktree list --porcelain` finds no worktree checked out to the deleted feat branch,
301
+ skip this step silently — `WORKTREES_REMOVED` stays empty.
302
+
263
303
  ### Step 10: Save Shipment Results and Summary
264
304
 
265
305
  Update checkpoint context via `codebyplan checkpoint update <id> --context '{"shipment": {...}}'` (CLI write-through); use MCP `update_checkpoint` as documented break-glass when the CLI is unavailable. The `shipment` block contains both branch promotion AND runtime surface results (from `/cbp-ship` Step 7):
@@ -275,6 +315,7 @@ context.shipment: {
275
315
  stale_branches_cleaned: [list of deleted git branches],
276
316
  feat_branch_deleted: true/false,
277
317
  supabase_branches_deleted: [list of Supabase preview branch names removed in Steps 8–9],
318
+ worktrees_removed: WORKTREES_REMOVED, // from Step 9.5 — paths removed or pending manual cleanup
278
319
  e2e_images_uploaded: E2E_IMAGES_UPLOADED // from Step 7.5 — { count, stored_paths, skipped, error? } (CHK-171)
279
320
  }
280
321
  ```
@@ -305,6 +346,7 @@ Present summary:
305
346
  - Stale branches deleted: [N] ([list])
306
347
  - Feat branch: [deleted/kept]
307
348
  - Supabase preview branches deleted: [N] ([list from supabase_branches_deleted], or "none")
349
+ - Git worktrees cleaned: [N] ([paths from worktrees_removed], or "none")
308
350
 
309
351
  ### Before/After Branch State
310
352
  - Before: [list of feat/* branches]
@@ -2,12 +2,13 @@
2
2
  name: cbp-checkpoint-plan
3
3
  description: Deep inline planning for a checkpoint — assess, gap-analyse, decide dependencies, compare alternatives, optionally e2e-probe a suspected-broken area, then create tasks as vertical slices. Runs after /cbp-checkpoint-create (mechanical) and before /cbp-checkpoint-start (activate + claim). Does NOT activate or claim.
4
4
  argument-hint: [checkpoint-number]
5
+ model: inherit
5
6
  effort: xhigh
6
7
  ---
7
8
 
8
9
  # Checkpoint Plan Command
9
10
 
10
- Runs INLINE (no subagent) — all analysis and Q&A stay in the main session. This is the rigour stage that prevents half-baked plans: it discovers shortcomings, decides whether existing dependencies suffice or a new one is warranted, compares competing approaches, and only THEN creates tasks. It produces `plan.steps[]` + tasks but **never activates the checkpoint and never claims a user/worktree** — that is `/cbp-checkpoint-start`.
11
+ Runs INLINE (no subagent) — all analysis and Q&A stay in the main session. This is the rigour stage that prevents half-baked plans: it discovers shortcomings, decides whether existing dependencies suffice or a new one is warranted, compares competing approaches, and only THEN creates tasks. It produces `plan.steps[]` + tasks but **never activates the checkpoint and never claims a user** — that is `/cbp-checkpoint-start`.
11
12
 
12
13
  ## Pipeline
13
14
 
@@ -36,7 +37,7 @@ Malformed (non-numeric, contains `-`): surface `checkpoint-plan: invalid argumen
36
37
  2. Read task files under `.codebyplan/state/checkpoints/<id>/tasks/*.json` (fallback: MCP `get_tasks(checkpoint_id)`) — load existing tasks. This sets the mode:
37
38
  - **fresh** — zero tasks: full plan + create all tasks.
38
39
  - **additive re-plan** — tasks exist: gap-analyse against them; only ADD new tasks or refine requirements for gaps. NEVER delete or overwrite an in-flight task.
39
- 3. Note whether `worktree_id` is set (claimed at create) — drives routing in Step 11.
40
+ 3. Note whether `assigned_user_id` is set (claimed at activation) — drives routing in Step 11.
40
41
 
41
42
  ### Step 2: Assess Ideas + Codebase
42
43
 
@@ -49,6 +50,10 @@ Iterate ALL `ideas[]` (not just the first). For each:
49
50
 
50
51
  Write each idea's analysis into `ideas[N].assessment` (Claude-authored; never touch `description`, which is the user's words).
51
52
 
53
+ #### Orchestration (optional)
54
+
55
+ Step 2's `cbp-research` and any e2e-probe subagent spawns MAY be authored as a `Workflow(...)` script instead of ad-hoc `Task` spawning — useful when multiple ideas each warrant an independent research/assessment pass. 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`.
56
+
52
57
  ### Step 3: Gap Analysis
53
58
 
54
59
  Find what the raw request misses — this is the core anti-"half-ass" step. Load `reference/gap-analysis-playbook.md` and run its two passes:
@@ -129,16 +134,18 @@ Final write of the complete `checkpoint.context` JSONB via `codebyplan checkpoin
129
134
  ...
130
135
  ```
131
136
 
132
- This skill does **NOT** activate the checkpoint and does **NOT** claim a user/worktree.
137
+ This skill does **NOT** activate the checkpoint and does **NOT** claim a user.
138
+
139
+ Resolve the current user: `npx codebyplan whoami --json` → `user_id`.
133
140
 
134
- - **Claimed by THIS session** — `worktree_id` is set AND equals `npx codebyplan resolve-worktree 2>/dev/null`: auto-trigger `/cbp-checkpoint-start` in the same context (the creator carries momentum into activation).
135
- - **Otherwise** — `worktree_id` is null, set to a different worktree, or `resolve-worktree` is empty: surface a single directive — `Next: /cbp-checkpoint-start` — so the owning session (or anyone free, if open) claims and starts it. Never auto-activate a checkpoint owned by a different worktree.
141
+ - **Open or yours** — `whoami` returns a `user_id` AND `assigned_user_id` is either null (unclaimed) or equals caller `user_id`: auto-trigger `/cbp-checkpoint-start` in the same context. `assigned_user_id` is stamped on activation, so a freshly-created checkpoint (null) is claimed by `/cbp-checkpoint-start` itself — the creator carries momentum into activation.
142
+ - **Owned by another, or no identity** — `assigned_user_id` is non-null and differs from caller `user_id`, or `whoami` returns no `user_id`: surface a single directive — `Next: /cbp-checkpoint-start` — so the owning session (or anyone free, if open) claims and starts it. Never auto-activate a checkpoint owned by a different user.
136
143
 
137
144
  ## Integration
138
145
 
139
- - **Reads**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/*.json`, `session/current.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_current_task`, `get_checkpoints`, `get_tasks`)
146
+ - **Reads**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/*.json`, `session/current.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_current_task`, `get_checkpoints`, `get_tasks`); `npx codebyplan whoami --json`
140
147
  - **Writes**: `codebyplan checkpoint update` (ideas assessment, context, plan, research), `codebyplan task create` (break-glass: MCP `update_checkpoint`, `create_task`)
141
148
  - **Spawns**: `cbp-research` (level 2+ only), config-matched `cbp-e2e-*` specialist (opt-in discovery probe, `whole_checkpoint_mode` — see `context/testing/e2e.md` dispatch contract)
142
149
  - **Triggered by**: `/cbp-checkpoint-create` (auto), or user directly
143
- - **Triggers**: `/cbp-checkpoint-start` (auto when claimed at create; directive when left open)
144
- - **Never**: activates the checkpoint or claims a user/worktree — that is `/cbp-checkpoint-start`
150
+ - **Triggers**: `/cbp-checkpoint-start` (auto when open/unclaimed or assigned to the current user; directive when owned by another or no identity)
151
+ - **Never**: activates the checkpoint or claims a user — that is `/cbp-checkpoint-start`
@@ -2,12 +2,13 @@
2
2
  name: cbp-checkpoint-start
3
3
  description: Activate a planned checkpoint and claim it for the current user/worktree, then route into task work. Runs after /cbp-checkpoint-plan (which produces tasks but never activates). Refuses to start an unplanned checkpoint.
4
4
  argument-hint: [checkpoint-number]
5
+ model: inherit
5
6
  effort: high
6
7
  ---
7
8
 
8
9
  # Checkpoint Start Command
9
10
 
10
- The activation + claim gate of the checkpoint pipeline. `/cbp-checkpoint-plan` produces tasks but deliberately leaves the checkpoint `pending` and possibly unclaimed so it can sit in a team queue. This skill flips it to `active`, claims it for the caller's worktree if still open, and routes into the first task.
11
+ The activation + claim gate of the checkpoint pipeline. `/cbp-checkpoint-plan` produces tasks but deliberately leaves the checkpoint `pending` and unclaimed so it can sit in a team queue. This skill flips it to `active` the server auto-stamps `assigned_user_id` from the caller's JWT on activation and routes into the first task.
11
12
 
12
13
  ## Pipeline
13
14
 
@@ -19,7 +20,13 @@ The activation + claim gate of the checkpoint pipeline. `/cbp-checkpoint-plan` p
19
20
 
20
21
  ### Step 0: Parse `$ARGUMENTS`
21
22
 
22
- Source `repo_id` from `.codebyplan/repo.json`. Resolve caller worktree once for the whole skill: `CALLER_WT=$(npx codebyplan resolve-worktree 2>/dev/null)`.
23
+ Source `repo_id` from `.codebyplan/repo.json`. Resolve the current user once for the whole skill:
24
+
25
+ ```bash
26
+ npx codebyplan whoami --json # → {"user_id":"<uuid>","email":"…"} or null
27
+ ```
28
+
29
+ `USER_ID` = `user_id` from the result (may be null for anonymous/keychain-empty callers).
23
30
 
24
31
  | Shape | Resolves to |
25
32
  |-------|-------------|
@@ -30,55 +37,57 @@ Malformed (non-numeric, contains `-`): surface `checkpoint-start: invalid argume
30
37
 
31
38
  ### Step 1: Load Checkpoint + Tasks
32
39
 
33
- Read `.codebyplan/state/checkpoints/<id>.json` for `status`, `worktree_id`, `plan` (local-first; if missing/stale run `npx codebyplan sync` once; break-glass: MCP `get_checkpoints`). Read task files under `.codebyplan/state/checkpoints/<id>/tasks/*.json` (fallback: MCP `get_tasks(checkpoint_id)`).
40
+ Read `.codebyplan/state/checkpoints/<id>.json` for `status`, `assigned_user_id`, `plan` (local-first; if missing/stale run `npx codebyplan sync` once; break-glass: MCP `get_checkpoints`). Read task files under `.codebyplan/state/checkpoints/<id>/tasks/*.json` (fallback: MCP `get_tasks(checkpoint_id)`).
34
41
 
35
42
  ### Step 2: Planned-Gate
36
43
 
37
44
  A checkpoint must be planned before it can start.
38
45
 
39
- - **No tasks AND empty `plan.steps[]`** → refuse: surface `CHK-NNN is not planned yet.` and auto-trigger `/cbp-checkpoint-plan {NNN}`. STOP. (An unplanned checkpoint is `worktree_id`-null, so there is nothing to own yet — always kick off planning, matching `/cbp-todo` Rule A.)
46
+ - **No tasks AND empty `plan.steps[]`** → refuse: surface `CHK-NNN is not planned yet.` and auto-trigger `/cbp-checkpoint-plan {NNN}`. STOP. (An unplanned checkpoint is unassigned, so there is nothing to own yet — always kick off planning, matching `/cbp-todo` Rule A.)
40
47
  - **Already `active`** → no activation needed; skip to Step 3 for a claim-check only, then Step 5.
41
48
  - **`pending` with tasks** → proceed.
42
49
 
43
50
  ### Step 3: Claim Logic
44
51
 
45
- Compare the checkpoint's `worktree_id` against `CALLER_WT`:
52
+ Compare the checkpoint's `assigned_user_id` against `USER_ID`:
46
53
 
47
- | Checkpoint `worktree_id` | Action |
48
- |--------------------------|--------|
49
- | null (left open at create) | Claim it: in Step 4 pass `worktree_id: CALLER_WT`. If `CALLER_WT` is empty, warn the checkpoint will stay unclaimed and proceed without it. |
50
- | equals `CALLER_WT` | Already yours — no-op. |
51
- | a DIFFERENT worktree | STOP. Surface: `CHK-NNN is claimed by worktree {other}; current worktree is {CALLER_WT}. If {other} is dead, a maintainer can release it via the release_assignment MCP tool, then re-run /cbp-checkpoint-start.` Do not activate. |
54
+ | Checkpoint `assigned_user_id` | Action |
55
+ |-------------------------------|--------|
56
+ | null (open not yet claimed) | Proceed to Step 4 activation. The server will stamp `assigned_user_id = USER_ID` (from JWT) on `status=active`. If `USER_ID` is null (anonymous caller), warn the checkpoint will stay unclaimed and proceed. |
57
+ | equals `USER_ID` | Already yours — no-op. Proceed to Step 5. |
58
+ | a DIFFERENT user (non-null) | STOP. Surface: `CHK-NNN is assigned to user <assigned_user_id-email-or-uuid>; you are <USER_ID-email-or-uuid>. Ask the owner to release the assignment, or a maintainer can use the release_assignment tool, then re-run /cbp-checkpoint-start.` Do not activate. |
52
59
 
53
- This mirrors the CHK-104 hard-lock model — never wrest a checkpoint from a live worktree.
60
+ Never wrest a checkpoint from another user.
54
61
 
55
62
  ### Step 4: Activate
56
63
 
57
- If the checkpoint is already `active` AND `worktree_id` already equals `CALLER_WT` (the Step 3 no-op row), skip this step entirely and proceed to Step 5 — nothing to write.
64
+ If the checkpoint is already `active` AND `assigned_user_id` already equals `USER_ID` (the Step 3 no-op row), skip this step entirely and proceed to Step 5 — nothing to write.
65
+
66
+ Otherwise set the checkpoint `active` via `codebyplan checkpoint update --id <checkpoint-id> --status active` (CLI write-through; break-glass: MCP `update_checkpoint`). The server auto-stamps `assigned_user_id = ctx.userId` (from the JWT) on activation — no client-side user param required. After the write, read the row back to confirm `assigned_user_id` is non-null.
58
67
 
59
- Otherwise set the checkpoint `active` via `codebyplan checkpoint update --id <checkpoint-id> --status active` (CLI write-through; break-glass: MCP `update_checkpoint`), plus `--worktree-id CALLER_WT` when claiming per Step 3. For MCP break-glass path: `caller_worktree_id` identifies the calling worktree and is auto-injected by the `cbp-mcp-caller-worktree-inject.sh` PreToolUse hook (CHK-198 TASK-2); the server falls back to the repo `main` worktree only when it is absent. If the checkpoint was already `active` but a claim is still needed, skip the status write and only write `worktree_id`.
68
+ If the checkpoint was already `active` but `assigned_user_id` is still null (edge case: prior activation without a valid JWT), re-read and surface a warning rather than silently proceeding.
60
69
 
61
70
  ### Step 5: Route
62
71
 
63
72
  Follow the close-out routing convention — auto-trigger the next same-context step, never an A/B/C menu. `{first-pending-task}` is the lowest-numbered pending task from Step 1 (not necessarily TASK-1, since additive re-planning may have completed earlier ones):
64
73
 
65
- - **Claimed by THIS session** (`CALLER_WT` now owns the checkpoint): auto-trigger `/cbp-task-start {chk}-{first-pending-task}` in the same context.
66
- - **`CALLER_WT` empty / unresolved**: surface a single directive — `Next: /cbp-task-start {chk}-{first-pending-task}` — and let the user proceed.
74
+ - **Claimed by THIS session** (`USER_ID` is non-null and now owns the checkpoint): auto-trigger `/cbp-task-start {chk}-{first-pending-task}` in the same context.
75
+ - **`USER_ID` null / anonymous**: surface a single directive — `Next: /cbp-task-start {chk}-{first-pending-task}` — and let the user proceed.
67
76
 
68
77
  Show a one-line confirmation before routing:
69
78
 
70
79
  ```
71
80
  ## Checkpoint Started
72
81
 
73
- **CHK-NNN**: [title] • **Status**: active • **Claimed by**: [worktree or "open"]
82
+ **CHK-NNN**: [title] • **Status**: active • **Claimed by**: [user email or "open"]
74
83
  **Next task**: TASK-[N] — [title]
75
84
  **Worktree**: `npx codebyplan worktree add CHK-{NNN}`
76
85
  ```
77
86
 
78
87
  ## Integration
79
88
 
80
- - **Reads**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/*.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_checkpoints`, `get_tasks`); `npx codebyplan resolve-worktree`
81
- - **Writes**: `codebyplan checkpoint update --status active [--worktree-id <id>]` (CLI write-through; break-glass: MCP `update_checkpoint`; `caller_worktree_id` auto-injected by cbp-mcp-caller-worktree-inject.sh hook on the MCP path)
82
- - **Triggered by**: `/cbp-checkpoint-plan` (auto when claimed at create), `/cbp-todo` (planned-but-pending gate), or user directly
89
+ - **Reads**: `.codebyplan/state/checkpoints/<id>.json`, `checkpoints/<id>/tasks/*.json` (local-first; `npx codebyplan sync` if stale; break-glass: MCP `get_checkpoints`, `get_tasks`); `npx codebyplan whoami --json`
90
+ - **Writes**: `codebyplan checkpoint update --status active` (CLI write-through; break-glass: MCP `update_checkpoint`; server auto-stamps `assigned_user_id` from JWT on activation)
91
+ - **Triggered by**: `/cbp-checkpoint-plan` (auto when open/unclaimed or assigned to the current user), `/cbp-todo` (planned-but-pending gate), or user directly
83
92
  - **Triggers**: `/cbp-task-start` (auto when claimed), or `/cbp-checkpoint-plan` (when the checkpoint is unplanned)
84
93
  - **Never**: plans or creates tasks — that is `/cbp-checkpoint-plan`
@@ -2,7 +2,8 @@
2
2
  name: cbp-checkpoint-update
3
3
  description: Update checkpoint state (activate, update context, etc.)
4
4
  argument-hint: [checkpoint-number]
5
- effort: high
5
+ model: inherit
6
+ effort: medium
6
7
  ---
7
8
 
8
9
  # Checkpoint Update Command
@@ -42,7 +43,7 @@ Given the parse from Step 0.5:
42
43
  | Parse | Resolution path |
43
44
  |-------|-----------------|
44
45
  | `{chk}` | Scan `.codebyplan/state/checkpoints/*.json` for `number === {chk}` (local-first; if missing/stale run `npx codebyplan sync` once; break-glass: MCP `get_checkpoints`). |
45
- | _(empty)_ | Read `.codebyplan/state/session/current.json` (with worktree_id from `npx codebyplan resolve-worktree`) to find the active checkpoint (fallback: MCP `get_current_task`). If no active checkpoint, scan local state for `pending` checkpoints (fallback: MCP `get_checkpoints` filtered by `pending`). |
46
+ | _(empty)_ | Read `.codebyplan/state/session/current.json` to find the active checkpoint (fallback: MCP `get_current_task`). If no active checkpoint, scan local state for `pending` checkpoints (fallback: MCP `get_checkpoints` filtered by `pending`). |
46
47
 
47
48
  ### Step 1.5: Detect Entry Context (from `/cbp-finalize` expand path)
48
49