codebyplan 1.13.23 → 1.13.25

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 (31) hide show
  1. package/dist/cli.js +445 -187
  2. package/package.json +2 -2
  3. package/templates/agents/cbp-cc-executor.md +7 -7
  4. package/templates/agents/cbp-improve-round.md +2 -2
  5. package/templates/agents/cbp-round-executor.md +20 -4
  6. package/templates/agents/cbp-testing-qa-agent.md +3 -3
  7. package/templates/hooks/README.md +1 -1
  8. package/templates/hooks/cbp-statusline.mjs +106 -11
  9. package/templates/hooks/cbp-statusline.py +79 -13
  10. package/templates/hooks/cbp-statusline.sh +97 -17
  11. package/templates/hooks/validate-structure-patterns.sh +1 -1
  12. package/templates/skills/cbp-checkpoint-check/SKILL.md +2 -2
  13. package/templates/skills/cbp-checkpoint-complete/SKILL.md +2 -2
  14. package/templates/skills/cbp-merge-main/SKILL.md +1 -1
  15. package/templates/skills/cbp-round-end/SKILL.md +12 -35
  16. package/templates/skills/cbp-round-end/reference/findings-presentation.md +76 -3
  17. package/templates/skills/cbp-round-execute/SKILL.md +13 -60
  18. package/templates/skills/cbp-round-start/SKILL.md +3 -1
  19. package/templates/skills/cbp-round-update/SKILL.md +1 -1
  20. package/templates/skills/cbp-session-start/SKILL.md +2 -0
  21. package/templates/skills/cbp-ship-configure/SKILL.md +1 -1
  22. package/templates/skills/cbp-ship-configure/reference/supabase.md +2 -2
  23. package/templates/skills/cbp-ship-main/SKILL.md +2 -0
  24. package/templates/skills/cbp-standalone-task-create/SKILL.md +1 -1
  25. package/templates/skills/cbp-task-check/SKILL.md +1 -1
  26. package/templates/skills/cbp-task-complete/SKILL.md +1 -1
  27. package/templates/skills/cbp-task-create/SKILL.md +50 -1
  28. package/templates/skills/cbp-task-start/SKILL.md +2 -2
  29. package/templates/skills/cbp-task-testing/SKILL.md +2 -2
  30. package/templates/skills/cbp-todo/SKILL.md +36 -3
  31. package/templates/skills/cbp-todo/qa-regression.md +8 -1
@@ -15,7 +15,7 @@
15
15
  #
16
16
  # DISPLAY OPTIONS (team-shared, committed)
17
17
  # .codebyplan/statusline.json -> { "lines": {identity,context,cost,rate_limits,
18
- # repo_pr,worktree,infra_drift}, "no_color": bool }
18
+ # repo_pr,worktree,infra_drift,package_freshness}, "no_color": bool }
19
19
  #
20
20
  # ENV-VAR OVERRIDES (env > config > default)
21
21
  # CBP_STATUSLINE_HIDE_IDENTITY=1 suppress line 1 (folder, branch, model, effort, …)
@@ -24,7 +24,8 @@
24
24
  # CBP_STATUSLINE_HIDE_RATE_LIMITS=1 suppress line 4 (5h / 7d rate limits)
25
25
  # CBP_STATUSLINE_HIDE_REPO_PR=1 suppress line 5 (repo host/owner/name, PR)
26
26
  # CBP_STATUSLINE_HIDE_WORKTREE=1 suppress line 6 (worktree name/branch/path)
27
- # CBP_STATUSLINE_HIDE_INFRA_DRIFT=1 suppress line 7 (.claude infra commits behind main)
27
+ # CBP_STATUSLINE_HIDE_INFRA_DRIFT=1 suppress line 7 (.claude infra commits behind main)
28
+ # CBP_STATUSLINE_HIDE_PACKAGE_FRESHNESS=1 suppress line 8 (codebyplan package version)
28
29
  # CBP_STATUSLINE_NO_COLOR=1 strip all ANSI colour codes (also honoured by $NO_COLOR)
29
30
  #
30
31
  # TEST SEAMS (no effect in normal use)
@@ -48,6 +49,17 @@ if [ -f "$CBP_LOCAL_CFG" ] && command -v jq >/dev/null 2>&1; then
48
49
  case "$_r" in bash|node|python) CBP_RENDERER="$_r" ;; esac
49
50
  fi
50
51
 
52
+ # Background claude-status cache refresh (6h staleness gate).
53
+ # `find -mmin -360` PRINTS the path only when the file exists AND is younger
54
+ # than 6h; an EMPTY result means the cache is absent OR stale (>6h) — both
55
+ # need a refresh. (find's exit code is 0 for a present-but-non-matching path,
56
+ # so we must test its output, not its status.)
57
+ # Fully detached — never blocks the render, never writes to this stdout.
58
+ CBP_STATUS_CACHE="$CBP_ROOT/.codebyplan/claude-status.local.json"
59
+ if [ -z "$(find "$CBP_STATUS_CACHE" -mmin -360 2>/dev/null)" ]; then
60
+ (npx codebyplan claude status --write-cache --quiet >/dev/null 2>&1 &)
61
+ fi
62
+
51
63
  if [ "$CBP_RENDERER" = "node" ] && command -v node >/dev/null 2>&1 \
52
64
  && [ -f "$CBP_HOOK_DIR/cbp-statusline.mjs" ]; then
53
65
  CBP_STATUSLINE_ROOT="$CBP_ROOT" exec node "$CBP_HOOK_DIR/cbp-statusline.mjs"
@@ -83,7 +95,6 @@ eval "$(echo "$INPUT" | jq -r '
83
95
  @sh "CACHE_READ=\(.context_window.current_usage.cache_read_input_tokens // 0)",
84
96
  @sh "EXCEEDS_200K=\(.exceeds_200k_tokens // false)",
85
97
  @sh "EFFORT=\(.effort.level // "")",
86
- @sh "THINKING=\(.thinking.enabled // false)",
87
98
  @sh "RATE_5H_PCT=\(.rate_limits.five_hour.used_percentage // "")",
88
99
  @sh "RATE_5H_RESETS=\(.rate_limits.five_hour.resets_at // 0)",
89
100
  @sh "RATE_7D_PCT=\(.rate_limits.seven_day.used_percentage // "")",
@@ -105,7 +116,7 @@ eval "$(echo "$INPUT" | jq -r '
105
116
 
106
117
  # ---- Config: line toggles + no_color from .codebyplan/statusline.json --------
107
118
  CFG_IDENTITY=true; CFG_CONTEXT=true; CFG_COST=true
108
- CFG_RATE_LIMITS=true; CFG_REPO_PR=true; CFG_WORKTREE=true; CFG_INFRA_DRIFT=true; CFG_NO_COLOR=false
119
+ CFG_RATE_LIMITS=true; CFG_REPO_PR=true; CFG_WORKTREE=true; CFG_INFRA_DRIFT=true; CFG_PACKAGE_FRESHNESS=true; CFG_NO_COLOR=false
109
120
  CBP_CFG="$CBP_ROOT/.codebyplan/statusline.json"
110
121
  if [ -f "$CBP_CFG" ] && command -v jq >/dev/null 2>&1; then
111
122
  # Use `!= false` / `== true` (NOT jq `//`): the `//` operator treats an explicit
@@ -119,6 +130,7 @@ if [ -f "$CBP_CFG" ] && command -v jq >/dev/null 2>&1; then
119
130
  "CFG_REPO_PR=\(.lines.repo_pr != false)",
120
131
  "CFG_WORKTREE=\(.lines.worktree != false)",
121
132
  "CFG_INFRA_DRIFT=\(.lines.infra_drift != false)",
133
+ "CFG_PACKAGE_FRESHNESS=\(.lines.package_freshness != false)",
122
134
  "CFG_NO_COLOR=\(.no_color == true)"
123
135
  ' "$CBP_CFG" 2>/dev/null)"
124
136
  fi
@@ -150,6 +162,9 @@ fi
150
162
  # ---- Float-safe percentage comparison ----------------------------------------
151
163
  awk_gte() { awk -v v="$1" -v t="$2" 'BEGIN{exit !(v+0 >= t+0)}'; }
152
164
 
165
+ # ---- Percentage formatter (integer round-half-up; cross-runtime identical) ----
166
+ fmt_pct() { awk -v v="$1" 'BEGIN{ printf "%d", int(v + 0.5) }'; }
167
+
153
168
  # ---- Token/size formatter (K / M) — integer round-half-up (cross-runtime) -----
154
169
  fmt_k() {
155
170
  local val=$1
@@ -164,9 +179,9 @@ fmt_k() {
164
179
  fi
165
180
  }
166
181
 
167
- # ---- Cost formatter ($X.XXXX) — integer round-half-up (cross-runtime) ---------
182
+ # ---- Cost formatter ($X.XX) — integer round-half-up (cross-runtime) -----------
168
183
  fmt_cost() {
169
- awk -v c="$1" 'BEGIN{ n=int(c*10000 + 0.5); printf "$%d.%04d", int(n/10000), n%10000 }'
184
+ awk -v c="$1" 'BEGIN{ n=int(c*100 + 0.5); printf "$%d.%02d", int(n/100), n%100 }'
170
185
  }
171
186
 
172
187
  # ---- Duration formatter (ms → Xh Xm Xs) --------------------------------------
@@ -245,11 +260,6 @@ if should_show IDENTITY "$CFG_IDENTITY"; then
245
260
  L1="${L1} ${DIM}effort:${RST}${EFFORT}"
246
261
  fi
247
262
 
248
- # Thinking (only when explicitly true)
249
- if [ "$THINKING" = "true" ]; then
250
- L1="${L1} ${YELLOW}thinking:on${RST}"
251
- fi
252
-
253
263
  # Output style (when present and not "default")
254
264
  if [ -n "$OUTPUT_STYLE" ] && [ "$OUTPUT_STYLE" != "default" ]; then
255
265
  L1="${L1} ${DIM}style:${RST}${OUTPUT_STYLE}"
@@ -324,27 +334,29 @@ if should_show RATE_LIMITS "$CFG_RATE_LIMITS"; then
324
334
  L4=""
325
335
 
326
336
  if [ -n "$RATE_5H_PCT" ] && [ "$RATE_5H_RESETS" != "0" ]; then
327
- if awk_gte "$RATE_5H_PCT" 80; then
337
+ R5=$(fmt_pct "$RATE_5H_PCT")
338
+ if awk_gte "$R5" 80; then
328
339
  C5="$RED"
329
- elif awk_gte "$RATE_5H_PCT" 60; then
340
+ elif awk_gte "$R5" 60; then
330
341
  C5="$YELLOW"
331
342
  else
332
343
  C5="$GREEN"
333
344
  fi
334
345
  REL5=$(fmt_rel_time "$RATE_5H_RESETS")
335
- L4="${DIM}5h:${RST}${C5}${RATE_5H_PCT}%${RST} ${DIM}(resets in ${REL5})${RST}"
346
+ L4="${DIM}5h:${RST}${C5}${R5}%${RST} ${DIM}(resets in ${REL5})${RST}"
336
347
  fi
337
348
 
338
349
  if [ -n "$RATE_7D_PCT" ] && [ "$RATE_7D_RESETS" != "0" ]; then
339
- if awk_gte "$RATE_7D_PCT" 80; then
350
+ R7=$(fmt_pct "$RATE_7D_PCT")
351
+ if awk_gte "$R7" 80; then
340
352
  C7="$RED"
341
- elif awk_gte "$RATE_7D_PCT" 60; then
353
+ elif awk_gte "$R7" 60; then
342
354
  C7="$YELLOW"
343
355
  else
344
356
  C7="$GREEN"
345
357
  fi
346
358
  REL7=$(fmt_rel_time "$RATE_7D_RESETS")
347
- SEG7="${DIM}7d:${RST}${C7}${RATE_7D_PCT}%${RST} ${DIM}(resets in ${REL7})${RST}"
359
+ SEG7="${DIM}7d:${RST}${C7}${R7}%${RST} ${DIM}(resets in ${REL7})${RST}"
348
360
  if [ -n "$L4" ]; then
349
361
  L4="${L4} ${DIM}|${RST} ${SEG7}"
350
362
  else
@@ -421,3 +433,71 @@ if should_show INFRA_DRIFT "$CFG_INFRA_DRIFT"; then
421
433
  ;;
422
434
  esac
423
435
  fi
436
+
437
+ # ============================================================
438
+ # LINE 8 — Package freshness (codebyplan version / sync state)
439
+ # ============================================================
440
+ # Source: .codebyplan/claude-status.local.json (written by background refresh).
441
+ # Inline fallback (cache absent): read .claude/.cbp.manifest.json vs
442
+ # node_modules/codebyplan/package.json. HIDE when guarded (canonical_source /
443
+ # no_manifest / unknown) or when manifest absent (not a managed consumer).
444
+ if should_show PACKAGE_FRESHNESS "$CFG_PACKAGE_FRESHNESS"; then
445
+ L8=""
446
+ _CBP_GUARDED=false
447
+ _CBP_INSTALLED=""
448
+ _CBP_NEWER=false
449
+ _CBP_LATEST=""
450
+ _CBP_IN_SYNC=true
451
+
452
+ if [ -f "$CBP_STATUS_CACHE" ] && command -v jq >/dev/null 2>&1; then
453
+ # Cache present — read fields.
454
+ _cbp_guard_reason="$(jq -r '.guard_reason // ""' "$CBP_STATUS_CACHE" 2>/dev/null)"
455
+ case "$_cbp_guard_reason" in
456
+ canonical_source|no_manifest|unknown)
457
+ _CBP_GUARDED=true
458
+ ;;
459
+ esac
460
+ if [ "$_CBP_GUARDED" = "false" ]; then
461
+ _CBP_INSTALLED="$(jq -r '.installed // ""' "$CBP_STATUS_CACHE" 2>/dev/null)"
462
+ _CBP_NEWER="$(jq -r '.newer == true' "$CBP_STATUS_CACHE" 2>/dev/null)"
463
+ _CBP_LATEST="$(jq -r '.latest // ""' "$CBP_STATUS_CACHE" 2>/dev/null)"
464
+ # NOTE: `!= false` (NOT jq `//`): the `//` operator treats an explicit
465
+ # `false` as absent, so `.in_sync // true` would yield "true" for an
466
+ # out-of-sync cache and silently drop the ⟳ indicator (CHK-175 TASK-3 R1
467
+ # finding #1). `!= false` mirrors node `in_sync !== false` / python.
468
+ _CBP_IN_SYNC="$(jq -r '.in_sync != false' "$CBP_STATUS_CACHE" 2>/dev/null)"
469
+ fi
470
+ else
471
+ # Inline fallback: no cache, no network — read-only file reads only.
472
+ _cbp_manifest="$CBP_ROOT/.claude/.cbp.manifest.json"
473
+ _cbp_pkg="$CBP_ROOT/node_modules/codebyplan/package.json"
474
+ if [ ! -f "$_cbp_manifest" ]; then
475
+ # No manifest → not a managed consumer → hide segment.
476
+ _CBP_GUARDED=true
477
+ elif [ -f "$_cbp_pkg" ] && command -v jq >/dev/null 2>&1; then
478
+ _cbp_mver="$(jq -r '.version // ""' "$_cbp_manifest" 2>/dev/null)"
479
+ _cbp_iver="$(jq -r '.version // ""' "$_cbp_pkg" 2>/dev/null)"
480
+ _CBP_INSTALLED="$_cbp_iver"
481
+ if [ -n "$_cbp_mver" ] && [ -n "$_cbp_iver" ] && [ "$_cbp_mver" != "$_cbp_iver" ]; then
482
+ # manifest ≠ installed → .claude is out of sync → ⟳ run claude update
483
+ # (mirrors the doctor's version_skip → in_sync:false). No npm info in the
484
+ # offline fallback, so never the ↑ newer-available marker.
485
+ _CBP_IN_SYNC=false
486
+ fi
487
+ else
488
+ # Can't read package.json or no jq → hide segment.
489
+ _CBP_GUARDED=true
490
+ fi
491
+ fi
492
+
493
+ if [ "$_CBP_GUARDED" = "false" ] && [ -n "$_CBP_INSTALLED" ]; then
494
+ L8="${DIM}cbp${RST} ${_CBP_INSTALLED}"
495
+ if [ "$_CBP_NEWER" = "true" ] && [ -n "$_CBP_LATEST" ]; then
496
+ L8="${L8} ${YELLOW}↑${_CBP_LATEST}${RST}"
497
+ fi
498
+ if [ "$_CBP_IN_SYNC" = "false" ]; then
499
+ L8="${L8} ${YELLOW}⟳ run claude update${RST}"
500
+ fi
501
+ printf "%b\n" "$L8"
502
+ fi
503
+ fi
@@ -38,7 +38,7 @@ if match_path '^/\.claude/docs/stack/' \
38
38
  fi
39
39
 
40
40
  # Notation consistency (warn-only): flag bare-colon command notation in .claude/ markdown
41
- # See: /.claude/rules/notation-consistency.md — all command refs must use /cbp-* form
41
+ # See: cbp-round-start Step 0 "CHK / TASK / ROUND Identifier Notation Vocabulary" — all command refs must use /cbp-* form
42
42
  if match_path '^/\.claude/(rules|skills|agents)/' && match_path '\.md$'; then
43
43
  CONTENT=$(read_input_content)
44
44
  [ -z "$CONTENT" ] && [ -f "$FILE_PATH" ] && CONTENT=$(cat "$FILE_PATH" 2>/dev/null || true)
@@ -120,11 +120,11 @@ Aggregate the files touched across all tasks (reusing Step 4's deduplicated tabl
120
120
  Continue to Step 6.
121
121
 
122
122
  5. **On fail** (any framework `f`: `e2e_outputs[f].status === 'failed'` OR `e2e_outputs[f].test_results.failed > 0`): build a failure summary from `e2e_outputs[*].test_results.failures[]` aggregated and grouped by `category`. Surface via `AskUserQuestion`:
123
- - **(a) Create fix-task in CHK-{NNN} (recommended)** — invoke MCP `create_task` with `checkpoint_id=current_checkpoint_id`, `title="Fix checkpoint-level e2e failures (CHK-{NNN})"`, `requirements` containing the detailed failure breakdown (category counts, files involved, pages broken, screenshot paths from `e2e_outputs[*].screenshots[]`), AND `context: { source_checkpoint_id, e2e_failure_summary: { category_counts, pages_broken, screenshot_paths }, fix_type: "checkpoint_e2e" }` so downstream `cbp-task-planner` can verify failure premises. Per `infra-issue-absorption.md` "Resolve-in-Current-Scope by Default", checkpoint-level e2e failures absorb into the active checkpoint — not standalone.
123
+ - **(a) Create fix-task in CHK-{NNN} (recommended)** — invoke MCP `create_task` with `checkpoint_id=current_checkpoint_id`, `title="Fix checkpoint-level e2e failures (CHK-{NNN})"`, `requirements` containing the detailed failure breakdown (category counts, files involved, pages broken, screenshot paths from `e2e_outputs[*].screenshots[]`), AND `context: { source_checkpoint_id, e2e_failure_summary: { category_counts, pages_broken, screenshot_paths }, fix_type: "checkpoint_e2e" }` so downstream `cbp-task-planner` can verify failure premises. Per `cbp-round-end` reference `findings-presentation.md` "Infra Issue Absorption Contract — Resolve-in-Current-Scope by Default", checkpoint-level e2e failures absorb into the active checkpoint — not standalone.
124
124
  - **(b) Surface as warning only — proceed to checkpoint-end** — append `| Checkpoint E2E | warning | N failures (deferred) |` to Step 5 QA Summary; continue to Step 6.
125
125
  - **(c) Halt — review manually** — STOP and wait for the user.
126
126
 
127
- See `infra-issue-absorption.md` Catalog row "Checkpoint-level e2e failure" for the routing rationale.
127
+ See `cbp-round-end` reference `findings-presentation.md` "Infra Issue Absorption Contract — Infra-Class Issue Catalog" row "Checkpoint-level e2e failure" for the routing rationale.
128
128
 
129
129
  ### Step 6: User Discussion
130
130
 
@@ -47,13 +47,13 @@ Given the parse from Step 0.5:
47
47
 
48
48
  ### Step 2: Verify Checkpoint End Has Run
49
49
 
50
- Check `checkpoint.context.shipment` — must exist with at least `feat_to_dev.merged: true`.
50
+ Check `checkpoint.context.shipment` — must exist with at least `feat_to_base.merged: true`.
51
51
 
52
52
  If not:
53
53
  ```
54
54
  ## Cannot Complete Checkpoint
55
55
 
56
- Checkpoint has not been shipped yet. Run `/cbp-checkpoint-end` first to merge feat branch to development.
56
+ Checkpoint has not been shipped yet. Run `/cbp-checkpoint-end` first to merge the feat branch to the base branch.
57
57
  ```
58
58
  Stop here.
59
59
 
@@ -96,7 +96,7 @@ Supabase migrations are version-keyed by their numeric filename prefix. Two file
96
96
 
97
97
  - **Rename HEAD-side (Recommended when a main migration is already applied to a shared remote)** — rename the local file to a fresh, sequential timestamp that respects existing apply-order dependencies (probe `supabase migration list --db-url <preview>` if a preview branch exists, or inspect FK references in surrounding migrations). The orchestrator runs `git mv <old> <new>` itself; the rename lands in the git index and is picked up by the re-probe at step 5.
98
98
  - **Rename main-side (manual, OUT-OF-SKILL)** — only when the main file definitely has not been applied anywhere yet AND the user has write access to `{BASE}`. This skill does NOT touch the main branch: it runs on a feat branch (Step 0 enforces this) and the Key Rules below forbid any push from this skill. The user must, in a separate terminal: `git checkout {BASE} && git mv <old> <new> && git commit -m "fix(migration): rename to resolve collision with feat/..." && git push origin {BASE}`. After that push is confirmed remote-side, re-invoke `/cbp-merge-main` — Step 1 will fetch the updated main tip and Step 1.5 will re-probe with the rename in place.
99
- - **Defer to a new task in the active checkpoint** — `git merge --abort` is unnecessary because Step 2 has not started. Create a CHK-bound task per `infra-issue-absorption.md` "Resolve-in-Current-Scope by Default" and STOP `/cbp-merge-main`. Resume after the task completes.
99
+ - **Defer to a new task in the active checkpoint** — `git merge --abort` is unnecessary because Step 2 has not started. Create a CHK-bound task per `cbp-round-end` reference `findings-presentation.md` "Infra Issue Absorption Contract — Resolve-in-Current-Scope by Default" and STOP `/cbp-merge-main`. Resume after the task completes.
100
100
  - **Abort merge** — STOP the skill. User decides later.
101
101
 
102
102
  5. After any HEAD-side rename action, re-execute Step 1.5 (collisions may chain — fixing one can expose another). The HEAD-side probe at step 1 uses `git ls-files` rather than `git ls-tree HEAD`, so the freshly-staged `git mv` is visible without requiring a commit. Main-side renames require a fresh `/cbp-merge-main` invocation (the user manually fetched and re-ran per option 2 above), not an in-skill loop.
@@ -5,27 +5,6 @@ description: Summary wrap-up after testing phase completes
5
5
  effort: high
6
6
  ---
7
7
 
8
- ## Kind Detection
9
-
10
- Inspect the resolved identifier from argument parsing to determine the task kind:
11
-
12
- | Identifier shape | KIND |
13
- |-----------------|------|
14
- | `{task}-{round}` (2-segment, e.g. `45-2`) | `standalone` |
15
- | `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
16
- | _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
17
-
18
- Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
19
-
20
- | Operation | `checkpoint` KIND | `standalone` KIND |
21
- |-----------|------------------|-------------------|
22
- | Get task | `get_current_task(repo_id)` | `get_current_standalone_task(repo_id)` |
23
- | Get rounds | `get_rounds(task_id)` | `get_standalone_rounds(standalone_task_id)` |
24
- | Add round | `add_round(task_id, ...)` | `add_standalone_round(standalone_task_id, ...)` |
25
- | Update round | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_id, ...)` |
26
- | 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 |
27
- | Update task | `update_task(task_id, ...)` | `update_standalone_task(standalone_task_id, ...)` |
28
-
29
8
  # Round End Command
30
9
 
31
10
  Summary phase — presents what was done, then runs code quality review to catch bugs and logic errors that automated checks miss.
@@ -42,16 +21,14 @@ See `reference/inline-fallback.md` for full trigger table, procedure, and covera
42
21
 
43
22
  ## Identifier Notation
44
23
 
45
- This skill operates on the **active** task/round resolved via MCP and does not accept a positional identifier argument. Canonical chk-task-round notation used in prose, error messages, and cross-references follows `.claude/rules/notation-consistency.md` "CHK / TASK / ROUND Identifier Notation": `108-1` (CHK-108 TASK-1), `45` (standalone TASK-45), `108-1-2` (round 2 of CHK-108 TASK-1), `45-2` (round 2 of standalone TASK-45).
24
+ This skill operates on the **active** task/round resolved via MCP `get_current_task` / `get_rounds` and does not accept a positional identifier argument. Canonical chk-task-round notation is defined in `cbp-round-start` Step 0 "CHK / TASK / ROUND Identifier Notation Vocabulary".
46
25
 
47
26
  ## Instructions
48
27
 
49
28
  ### Step 1: Get Current Task and Round
50
29
 
51
- Use Kind Detection above to set KIND. Then:
52
-
53
- - **checkpoint KIND**: MCP `get_current_task(repo_id)` (pass `checkpoint_id` if known) to find the active task. MCP `get_rounds(task_id)` to find the in-progress round.
54
- - **standalone KIND**: MCP `get_current_standalone_task(repo_id)` to find the active task. MCP `get_standalone_rounds(standalone_task_id)` to find the in-progress round.
30
+ Use MCP `get_current_task` with repo_id (pass `checkpoint_id` if known to avoid disambiguation) to find the active task.
31
+ Use MCP `get_rounds` for the task to find the in-progress round.
55
32
 
56
33
  Load round context with all outputs (executor_output, testing_qa_output, reviewer_output).
57
34
 
@@ -93,11 +70,11 @@ Merge with previous rounds (supersede items for re-modified files, preserve veri
93
70
 
94
71
  ### Step 4: Update Task Files and QA
95
72
 
96
- Update via MCP using KIND-appropriate tools:
73
+ Update via MCP:
97
74
 
98
- - `update_task(task_id, files_changed: [...])` / `update_standalone_task(standalone_task_id, files_changed: [...])` — merge with existing
99
- - `update_round(round_id, files_changed: [...], qa: {items: [auto_qa items + default_checklist items]})` / `update_standalone_round(standalone_round_id, ...)` — round-specific
100
- - `update_task(task_id, qa: {items: [auto_qa items + default_checklist items]})` / `update_standalone_task(standalone_task_id, qa: {items: [auto_qa items + default_checklist items]})` — aggregated
75
+ - `update_task(task_id, files_changed: [...])` — merge with existing
76
+ - `update_round(round_id, files_changed: [...], qa: {items: [auto_qa items + default_checklist items]})` — round-specific
77
+ - `update_task(task_id, qa: {items: [auto_qa items + default_checklist items]})` — aggregated
101
78
 
102
79
  ### Step 5: Present Summary
103
80
 
@@ -160,8 +137,8 @@ Example tables and the `inline` option gating spec: see `reference/findings-pres
160
137
  - Auto-accept ALL findings into `improve_round_findings[]` regardless of severity (the user opted into the loop).
161
138
  - Skip the polish-spiral stop-gate (auto-loop has its own cap-exhausted termination).
162
139
  - Skip the user findings-decision prompt.
163
- - Save findings via `update_round` / `update_standalone_round` per KIND exactly as in manual mode.
164
- - Auto-trigger `/cbp-round-update` immediately. round-update Step 4 will decide whether to spawn another round or exit clean (see cbp-round-update SKILL.md Step 4).
140
+ - Save findings via `update_round` exactly as in manual mode.
141
+ - Auto-trigger `/cbp-round-update` immediately. round-update Step 6 will decide whether to spawn another round or exit clean (see cbp-round-update SKILL.md Step 6).
165
142
 
166
143
  **Else (manual mode — flag absent or false):**
167
144
 
@@ -169,7 +146,7 @@ Run the existing flow:
169
146
 
170
147
  1. After round 2+, surface the polish-spiral stop-gate per `polish-spiral-stop-gate.md` (defer-to-followups vs continue).
171
148
  2. Surface the findings-decision AskUserQuestion (with optional `inline` per the gating rules in `reference/findings-presentation.md`).
172
- 3. Save accepted/rejected findings to round context via MCP `update_round` / `update_standalone_round` per KIND:
149
+ 3. Save accepted/rejected findings to round context via MCP `update_round`:
173
150
  ```json
174
151
  {
175
152
  "context": {
@@ -190,7 +167,7 @@ Run the existing flow:
190
167
  ## Integration
191
168
 
192
169
  - **Triggered by**: `/cbp-round-execute` (auto, after all waves + testing complete)
193
- - **Reads**: MCP `get_current_task` / `get_current_standalone_task`, `get_rounds` / `get_standalone_rounds` (per KIND), round context
194
- - **Writes**: MCP `update_round` / `update_standalone_round`, `update_task` / `update_standalone_task` (files_changed, qa, findings) — per KIND
170
+ - **Reads**: MCP `get_current_task`, `get_rounds`, round context
171
+ - **Writes**: MCP `update_round`, `update_task` (files_changed, qa, findings)
195
172
  - **Spawns**: `cbp-improve-round` (code quality review)
196
173
  - **Triggers**: `/cbp-round-update` (auto, after findings handled)
@@ -29,16 +29,89 @@ Which findings should be fixed?
29
29
  - "all" — fix all findings in a new round
30
30
  - "1,2" — fix specific findings by number
31
31
  - "none" — skip all, proceed to round-update
32
- - "inline" — fix in THIS round before proceeding (only offered when all findings qualify under `infra-issue-absorption.md` Trivial-Resolution Exception)
32
+ - "inline" — fix in THIS round before proceeding (only offered when all findings qualify under the Trivial-Resolution Exception below)
33
33
  - Or explain why specific findings are not issues
34
34
  ```
35
35
 
36
36
  ## "inline" option gating
37
37
 
38
- Only present the "inline" option when ALL pending findings simultaneously satisfy:
38
+ Only present the "inline" option when ALL pending findings simultaneously qualify under the **Trivial-Resolution Exception** (see subsection below):
39
39
 
40
40
  1. Diff is comment-only, annotation-only, banner-only, or single-value rename — no logic, no control flow
41
41
  2. Each fix is under ~5 minutes of executor time
42
42
  3. Verification is automatic — the existing test/lint/audit pipeline confirms the change
43
43
 
44
- If any finding fails these gates, omit the "inline" option entirely (revert to the 3-option prompt). When inline is chosen, apply the edits via direct `Edit`, re-run the verification commands (hook syntax check + `testing-qa-agent` scoped to modified files) and proceed to `/cbp-round-update` without spawning a new round. Document the decision in `round.context.inline_fix_log = { findings: [ids], rationale: "trivial-resolution exception", applied_at: <ISO> }` (mirrors the `bypass_log` shape from `infra-issue-absorption.md` "Pipeline Bypass for Trivial-Resolution Rounds").
44
+ If any finding fails these gates, omit the "inline" option entirely (revert to the 3-option prompt). When inline is chosen, apply the edits via direct `Edit`, re-run the verification commands (hook syntax check + `cbp-testing-qa-agent` scoped to modified files) and proceed to `/cbp-round-update` without spawning a new round. Document the decision in `round.context.inline_fix_log = { findings: [ids], rationale: "trivial-resolution exception", applied_at: <ISO> }` (mirrors the `bypass_log` shape from the Pipeline Bypass subsection below).
45
+
46
+ ---
47
+
48
+ ## Infra Issue Absorption Contract
49
+
50
+ ### Resolve-in-Current-Scope by Default
51
+
52
+ When `/cbp-round-execute` Step 5 (per-wave `cbp-testing-qa-agent`) or `/cbp-task-testing` surfaces a pre-existing infra-class issue (critical/high CVE, broken ESLint config-load, Playwright env-loading gap, dead CI pipeline, etc.), the default response is **absorb into current scope** — NOT create a standalone task.
53
+
54
+ Order of preference for routing a finding:
55
+
56
+ 1. **Trivial-resolution inline** (no new round) — fix qualifies for the exception below
57
+ 2. **New round in the current task** — finding is related to the task's domain
58
+ 3. **New task in the current checkpoint** — finding belongs to the checkpoint goal but is a separate concern
59
+ 4. **Standalone task** — only when the finding is truly off-axis from the active checkpoint AND the user has explicitly confirmed standalone routing
60
+
61
+ ### Trivial-Resolution Exception
62
+
63
+ Resolve inline in the CURRENT round (no new round, no new task) when ALL hold:
64
+
65
+ 1. The fix is **fully mechanical** — no design decision, no tradeoff, no naming question
66
+ - **1a. Unambiguous scope**: no decision about sweep extent required
67
+ - **1b. Pattern soundness verified** at each target site before propagating
68
+ 2. The fix takes **under ~5 minutes** of executor time
69
+ 3. The fix's diff stays **scoped to its own concern** and won't dilute the round's primary diff
70
+ 4. Verification is automatic (existing test/lint/audit pipeline confirms it)
71
+
72
+ Examples that qualify:
73
+
74
+ | Finding | Inline action |
75
+ |---------|---------------|
76
+ | Pre-existing prettier drift in N files | `prettier --write` on those files |
77
+ | Single transitive CVE with a known-good `pnpm.overrides` line | Add the override, re-audit |
78
+ | One-line hook tweak (add a filename to an exemption list) | Edit the hook |
79
+ | Non-breaking patch bump on a build-tool | Update package.json, lockfile |
80
+ | In-module sibling violations (≤2) with canonical 2-line fix | Apply inline, document in adoption row |
81
+ | Homogeneous-pattern mass migration (single rule, single shape, fully mechanical, verifiable by grep) | Apply across all sites in one round |
82
+
83
+ Examples that do NOT qualify — route to a new round in the current task:
84
+
85
+ | Finding | Why |
86
+ |---------|-----|
87
+ | Diacritical fix in R1 i18n blocks with potentially 80+ unrelated sites elsewhere | Scope decision required |
88
+ | `.update().single()` violations in 22 sites across 9 modules | Cross-module sweep requires coordinated audit |
89
+ | Auth-guard sweep across multiple feature modules | Multi-module; needs dedicated round |
90
+
91
+ ### Pipeline Bypass for Trivial-Resolution Rounds
92
+
93
+ When the trivial-resolution exception qualifies, the orchestrator MAY bypass these pipeline stages — document in `round.context.bypass_log`:
94
+
95
+ | Stage | Bypass allowed when | Document as |
96
+ |-------|--------------------|-------------|
97
+ | `cbp-round-executor` | Single-file Edit fully specified by prior reviewer output | `bypass_log.executor: "single-file edit, used direct Edit"` |
98
+ | `cbp-testing-qa-agent` | Edit is non-code (comment, doc, type-annotation) AND existing test coverage protects the area | `bypass_log.testing_qa: "non-code edit, existing tests cover area"` |
99
+ | `cbp-improve-round` | Diff is ≤5 lines AND no logic changed | `bypass_log.improve_round: "≤5 lines non-logic, skipped"` |
100
+ | `cbp-task-planner` | Path B (the planner's trivial-corrective bypass that keeps repeat fix-rounds cheap) already qualifies | `bypass_log.planner: "Path B trivial-corrective bypass"` |
101
+
102
+ **ALL four bypasses simultaneously** is acceptable for ≤5-line non-logic corrective edits where every premise was verified by a prior reviewer.
103
+
104
+ **Do NOT bypass** when: round modifies behaviour; round changes test assertions; round touches more than one file; round is the FIRST round of the task.
105
+
106
+ ### Infra-Class Issue Catalog
107
+
108
+ These categories surface from per-wave `cbp-testing-qa-agent` or from `/cbp-task-testing`. Default routing for each is in-scope absorption unless genuinely off-axis from the active checkpoint.
109
+
110
+ | Category | Examples |
111
+ |----------|----------|
112
+ | Vulnerability | `pnpm audit` critical/high advisories |
113
+ | Dead build tooling | ESLint config fails to load, Prettier crashes, tsc OOM |
114
+ | Test infra gaps | Playwright `.env.local` not loaded, CI env var missing |
115
+ | Dependency drift | Major version behind on non-breaking peer dep |
116
+ | Config registry drift | Port allocation missing, turbo pipeline missing entry |
117
+ | Checkpoint-level e2e failure | Whole-checkpoint e2e run (`/cbp-checkpoint-check` Step 5b) reports failures — absorb into the active checkpoint as a fix-task, never standalone |
@@ -5,27 +5,6 @@ description: Execute the approved plan from /cbp-round-start — runs per-wave e
5
5
  effort: xhigh
6
6
  ---
7
7
 
8
- ## Kind Detection
9
-
10
- Inspect the resolved identifier from argument parsing to determine the task kind:
11
-
12
- | Identifier shape | KIND |
13
- |-----------------|------|
14
- | `{task}-{round}` (2-segment, e.g. `45-2`) | `standalone` |
15
- | `{chk}-{task}-{round}` (3-segment, e.g. `141-3-1`) | `checkpoint` |
16
- | _(empty / free-text)_ | Check `get_current_standalone_task` first; if found → `standalone`. Else → `checkpoint` via `get_current_task`. |
17
-
18
- Set `KIND` for the rest of this skill. MCP tool names vary by KIND:
19
-
20
- | Operation | `checkpoint` KIND | `standalone` KIND |
21
- |-----------|------------------|-------------------|
22
- | Get task | `get_current_task(repo_id)` | `get_current_standalone_task(repo_id)` |
23
- | Get rounds | `get_rounds(task_id)` | `get_standalone_rounds(standalone_task_id)` |
24
- | Add round | `add_round(task_id, ...)` | `add_standalone_round(standalone_task_id, ...)` |
25
- | Update round | `update_round(round_id, ...)` | `update_standalone_round(standalone_round_id, ...)` |
26
- | 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 |
27
- | Update task | `update_task(task_id, ...)` | `update_standalone_task(standalone_task_id, ...)` |
28
-
29
8
  # Round Execute Command
30
9
 
31
10
  Execution and validation phase. Receives the approved plan from `/cbp-round-start`, dispatches wave executors, runs per-wave `cbp-testing-qa-agent` in parallel, and routes to `/cbp-round-end`.
@@ -38,16 +17,14 @@ Execution and validation phase. Receives the approved plan from `/cbp-round-star
38
17
 
39
18
  ## Identifier Notation
40
19
 
41
- This skill operates on the **active** task/round resolved via MCP and does not accept a positional identifier argument. Canonical chk-task-round notation used in prose, error messages, and cross-references follows `.claude/rules/notation-consistency.md` "CHK / TASK / ROUND Identifier Notation": `108-1` (CHK-108 TASK-1), `45` (standalone TASK-45), `108-1-2` (round 2 of CHK-108 TASK-1), `45-2` (round 2 of standalone TASK-45).
20
+ This skill operates on the **active** task/round resolved via MCP `get_current_task` / `get_rounds` and does not accept a positional identifier argument. Canonical chk-task-round notation is defined in `cbp-round-start` Step 0 "CHK / TASK / ROUND Identifier Notation Vocabulary".
42
21
 
43
22
  ## Instructions
44
23
 
45
24
  ### Step 1: Get Current Task and Round
46
25
 
47
- Use Kind Detection above to set KIND. Then:
48
-
49
- - **checkpoint KIND**: MCP `get_current_task(repo_id)` (pass checkpoint_id if known) to find the active task. MCP `get_rounds(task_id)` to find the in-progress round.
50
- - **standalone KIND**: MCP `get_current_standalone_task(repo_id)` to find the active task. MCP `get_standalone_rounds(standalone_task_id)` to find the in-progress round.
26
+ Use MCP `get_current_task` with repo_id (pass checkpoint_id if known) to find the active task.
27
+ Use MCP `get_rounds` for the task to find the in-progress round.
51
28
 
52
29
  If no in-progress round: `No active round. Run /cbp-round-start first.`
53
30
 
@@ -184,35 +161,11 @@ Input contracts: `cbp-testing-qa-agent` receives `executor_output`, `testing_pro
184
161
 
185
162
  ### Step 5b: Post-E2E Screenshot Review (cbp-frontend-ui Phase 6.5)
186
163
 
187
- Aggregate across ALL specialists that ran:
188
-
189
- ```js
190
- screenshots = Object.values(round.context.e2e_outputs ?? {}).flatMap(o => o.screenshots ?? []);
191
- e2e_gallery = Object.values(round.context.e2e_outputs ?? {}).flatMap(o => o.e2e_gallery ?? []);
192
- ```
193
-
194
- **Auto-new baseline handling**: for each entry in `e2e_gallery` where `is_new === true`, the
195
- specialist has already run `git add <committed_path>`. No additional user gate is needed.
196
- **Changed-baseline handling**: entries where `is_new === false` AND `baseline_diff_pct > threshold`
197
- are `visual_regression` — do NOT auto-accept; surface as blocking gate at Step 7.
198
-
199
- Persist `e2e_gallery` to `round.context.e2e_gallery` (additive alongside existing
200
- `round.context.e2e_outputs`). This field is consumed by TASK-3 / checkpoint-end for DB upload.
201
- Note: `e2e_gallery[]` is aggregated and persisted regardless of whether `cbp-frontend-ui` runs — the empty-gallery enforcement lives in `cbp-task-check` Phase 4, while the `screenshots[]` visual review (frontend-ui Phase 6.5) is a separate concern gated on `screenshots[]` being non-empty.
202
-
203
- When the aggregated `screenshots` list is non-empty, invoke the `cbp-frontend-ui` skill with
204
- `phase: 'screenshot_review'` (input: `files_changed`, `e2e_screenshots: <aggregated screenshots>`,
205
- `context: { checkpoint_goal, round_requirements }`). Under this phase the skill runs only
206
- Phase 6.5 (Rendered-Output Visual Review) + 7 + 8 — Phases 1-6 (style) already ran at Step 3.8.
164
+ 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 executor Step 3.8 with `phase: 'style_only'`.
207
165
 
208
- Persist findings to `round.context.frontend_ui_review` (merge with Step 3.8's style-only output
209
- if present). Baseline-regression findings surface as a BLOCKING gate at `/cbp-round-end` Step 7
210
- (an explicit accept-or-fix user decision; changed baselines are NEVER auto-accepted);
211
- rendered_visual critical findings are surfaced in the Step 7 findings presentation. Neither
212
- auto-fails the round. cbp-testing-qa-agent does NOT read these findings (full independence).
166
+ Persist findings to `round.context.frontend_ui_review` (merge with Step 3.8's style-only output if present). Baseline-regression findings surface as a BLOCKING gate at `/cbp-round-end` Step 7 (an explicit accept-or-fix user decision; baselines are NEVER auto-accepted); rendered_visual critical findings are surfaced in the Step 7 findings presentation. Neither auto-fails the round. cbp-testing-qa-agent does NOT read these findings (full independence per Step 5).
213
167
 
214
- **Skip** when `round.context.e2e_outputs` is absent/empty, the aggregated `screenshots` list
215
- is empty, or `testing_profile === 'claude_only'`.
168
+ **Skip** when `round.context.e2e_outputs` is absent/empty, the aggregated `screenshots` list is empty, or `testing_profile === 'claude_only'`.
216
169
 
217
170
  ### Step 6: Hard-Fail Routing
218
171
 
@@ -225,7 +178,7 @@ Per-wave hard-fail signal — true when ANY hold:
225
178
  **All waves hard_fail: false** → proceed to Step 7. **Any wave hard_fail: true**:
226
179
 
227
180
  - **Simple fixes** (type errors, lint, missing imports, test assertion fixes, e2e `real`-category with clear code-side root cause, no prior re-trigger this round) → save failure details to round context; retrigger the failing wave's executor; re-run testing-qa AND the eligible `cbp-e2e-*` specialists for that wave.
228
- - **Structural OR already re-triggered once OR e2e preflight aborts OR `e2e_eligible_skipped`** → save failure context via MCP `update_round` / `update_standalone_round` per KIND; auto-trigger `/cbp-round-input`. STOP.
181
+ - **Structural OR already re-triggered once OR e2e preflight aborts OR `e2e_eligible_skipped`** → save failure context via MCP `update_round`; auto-trigger `/cbp-round-input`. STOP.
229
182
 
230
183
  ## Inline execution fallback
231
184
 
@@ -237,11 +190,11 @@ When `cbp-testing-qa-agent` spawn fails OR the resolved `testing_profile` is `cl
237
190
 
238
191
  ### Step 7: Save Executor Output
239
192
 
240
- Update round context via MCP `update_round` / `update_standalone_round` per KIND:
193
+ Update round context via MCP `update_round`:
241
194
 
242
- - `context`: { ...existing, executor_output, testing_qa_output, e2e_eligible, e2e_outputs, e2e_gallery, frontend_ui_review }
195
+ - `context`: { ...existing, executor_output, testing_qa_output, e2e_eligible, e2e_outputs, frontend_ui_review }
243
196
 
244
- `e2e_outputs` (a framework-keyed map of specialist outputs, e.g. `{ playwright: {...}, maestro: {...} }`), `e2e_gallery` (aggregated flat array of committed-PNG entries across all specialists — consumed by TASK-3 / checkpoint-end for DB upload), and `frontend_ui_review` are present only when the gates above admitted them (≥1 eligible framework ran AND Step 5b ran). `e2e_eligible[]` records which frameworks were eligible this round and drives the Step 6 `e2e_eligible_skipped` check.
197
+ `e2e_outputs` (a framework-keyed map of specialist outputs, e.g. `{ playwright: {...}, maestro: {...} }`) and `frontend_ui_review` are present only when the gates above admitted them (≥1 eligible framework ran AND Step 5b ran). `e2e_eligible[]` records which frameworks were eligible this round and drives the Step 6 `e2e_eligible_skipped` check.
245
198
 
246
199
  ### Step 8: Auto-trigger Round End
247
200
 
@@ -258,13 +211,13 @@ Trigger `/cbp-round-end`.
258
211
  - `testing_profile` from `task.context` governs which checks run — read it once in Step 2; pass to every testing-qa + e2e specialist spawn
259
212
  - `claude_only` profile skips all agent spawns (testing-qa AND `cbp-e2e-*`); runs hook syntax and skill structure checks inline
260
213
  - E2E dispatch is **config-driven and opt-out** (`.codebyplan/e2e.json`), not gated on `has_ui_work`/`testing_profile` — an eligible framework that silently does not run is an `e2e_eligible_skipped` hard-fail (`rules/e2e-mandatory.md`)
261
- - Step 5b (cbp-frontend-ui Phase 6.5) runs only when e2e produced screenshots — gated on the aggregated `e2e_outputs[*].screenshots[]` being non-empty; `e2e_gallery[]` is always aggregated and persisted when any specialist ran
214
+ - Step 5b (cbp-frontend-ui Phase 6.5) runs only when e2e produced screenshots — gated on the aggregated `e2e_outputs[*].screenshots[]` being non-empty
262
215
  - Claude NEVER git adds files in round commands
263
216
 
264
217
  ## Integration
265
218
 
266
- - **Reads**: MCP `get_current_task` / `get_current_standalone_task`, `get_rounds` / `get_standalone_rounds` (per KIND)
267
- - **Writes**: MCP `update_round` / `update_standalone_round` (context with executor_output + testing_qa_output + e2e_eligible + e2e_outputs + e2e_gallery + frontend_ui_review) — per KIND
219
+ - **Reads**: MCP `get_current_task`, `get_rounds`
220
+ - **Writes**: MCP `update_round` (context with executor_output + testing_qa_output + e2e_eligible + e2e_outputs + frontend_ui_review)
268
221
  - **Spawns**: `cbp-round-executor` (per wave or single), `cbp-testing-qa-agent` (per wave, parallel sibling of the `cbp-e2e-*` specialists), the `cbp-e2e-*` specialists (config-driven dispatch per `context/testing/e2e.md`, one per eligible framework in `.codebyplan/e2e.json`), `cbp-database-agent` (if DB work), `cbp-security-agent` (if security review needed)
269
222
  - **Skill invocations**: `cbp-frontend-ui` at Step 5b with `phase: 'screenshot_review'` (post-e2e)
270
223
  - **Triggers**: `/cbp-round-end` (auto)
@@ -58,7 +58,9 @@ Inline-fallback is NOT a quality downgrade trapdoor — Phase 1.5 row-by-row ver
58
58
 
59
59
  ### Step 0: Parse `$ARGUMENTS` shape
60
60
 
61
- Disambiguate the argument up front. Three input shapes (see `.claude/rules/notation-consistency.md` "CHK / TASK / ROUND Identifier Notation"):
61
+ Disambiguate the argument up front. Three input shapes:
62
+
63
+ ### CHK / TASK / ROUND Identifier Notation Vocabulary
62
64
 
63
65
  | Shape | Regex | Meaning |
64
66
  |-------|-------|---------|
@@ -44,7 +44,7 @@ If this is false: DO NOT proceed to Step 3.
44
44
 
45
45
  ### Step 1: Parse `$ARGUMENTS`
46
46
 
47
- Parse the argument using the canonical chk-task-round notation (see `.claude/rules/notation-consistency.md`):
47
+ Parse the argument using the canonical chk-task-round notation (see `cbp-round-start` Step 0 "CHK / TASK / ROUND Identifier Notation Vocabulary"):
48
48
 
49
49
  | Shape | Regex | Resolves to |
50
50
  |-------|-------|-------------|
@@ -97,6 +97,8 @@ Check whether a newer `codebyplan` is published and safe to auto-install on this
97
97
 
98
98
  ```bash
99
99
  VERSION_JSON=$(npx codebyplan version-status 2>/dev/null)
100
+ # Populate the claude-status cache best-effort (pure cache population — never gates session-start).
101
+ npx codebyplan claude status --write-cache --quiet 2>/dev/null || true
100
102
  ```
101
103
 
102
104
  Parse `$VERSION_JSON` as JSON and branch on the result:
@@ -62,7 +62,7 @@ References:
62
62
  **Supabase — branching integration** (run AFTER Step 5 — Verify completes for the
63
63
  supabase surface; do NOT invoke during Steps 1–4): once Step 5 has finished and
64
64
  `shipment.surfaces.supabase` is persisted, run
65
- `jq '.shipment.surfaces.supabase.branching_configured // empty' .codebyplan.json`.
65
+ `jq '.shipment.surfaces.supabase.branching_configured // empty' .codebyplan/shipment.json`.
66
66
  If empty, invoke `/cbp-supabase-setup` (GitHub integration, required-status-check,
67
67
  persistent branch). Delegate fully — do NOT duplicate steps inline. If already set,
68
68
  note as already-done in the Step 6 report.
@@ -174,11 +174,11 @@ project_id = "xyzwabcd" # 8-char ref from `supabase --experimental branches li
174
174
  ```
175
175
 
176
176
  Replace `development` and `xyzwabcd` with the actual integration branch name and project
177
- ref for this repo (confirmed in `.codebyplan.json` `branch_config.integration`).
177
+ ref for this repo (confirmed in `.codebyplan/git.json` `branch_config.integration`).
178
178
 
179
179
  ### Idempotency marker
180
180
 
181
- Written to `.codebyplan.json` after setup completes:
181
+ Written to `.codebyplan/shipment.json` after setup completes:
182
182
 
183
183
  ```json
184
184
  {