codebyplan 1.13.48 → 1.13.50
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.
- package/dist/cli.js +2 -1
- package/package.json +1 -1
- package/templates/agents/cbp-round-executor.md +8 -6
- package/templates/agents/cbp-stripe-agent.md +173 -0
- package/templates/agents/cbp-task-planner.md +2 -2
- package/templates/hooks/cbp-skill-context-guard.sh +52 -0
- package/templates/hooks/cbp-test-hooks.sh +144 -0
- package/templates/hooks/hooks.json +9 -0
- package/templates/rules/model-invocation-convention.md +40 -0
- package/templates/rules/parallel-waves.md +1 -1
- package/templates/rules/task-routing-recommendation.md +1 -1
- package/templates/settings.project.base.json +15 -1
- package/templates/skills/cbp-build-cc-settings/reference/cbp-permission-policy.md +42 -0
- package/templates/skills/cbp-clear-continue/SKILL.md +86 -0
- package/templates/skills/cbp-clear-prep/SKILL.md +121 -0
- package/templates/skills/cbp-round-execute/SKILL.md +9 -1
- package/templates/skills/cbp-round-start/SKILL.md +1 -1
- package/templates/skills/cbp-stripe/SKILL.md +116 -0
- package/templates/skills/cbp-stripe/reference/billing.md +106 -0
- package/templates/skills/cbp-stripe/reference/connect.md +105 -0
- package/templates/skills/cbp-stripe/reference/payments.md +107 -0
- package/templates/skills/cbp-stripe/reference/security.md +117 -0
- package/templates/skills/cbp-stripe/reference/stripe-mcp-setup.md +59 -0
- package/templates/skills/cbp-stripe/reference/tax.md +96 -0
- package/templates/skills/cbp-stripe/reference/treasury.md +87 -0
- package/templates/skills/cbp-task-check/SKILL.md +12 -5
- package/templates/skills/cbp-task-complete/SKILL.md +9 -11
- package/templates/skills/cbp-task-complete/reference/checkpoint-done-branching.md +14 -21
- package/templates/skills/cbp-task-complete/reference/next-step-heuristic.md +4 -6
- package/templates/skills/cbp-task-testing/SKILL.md +9 -14
- package/templates/skills/cbp-frontend-a11y/SKILL.md +0 -108
- package/templates/skills/cbp-frontend-a11y/reference/aria-roles-states.md +0 -130
- package/templates/skills/cbp-frontend-a11y/reference/contrast-visual.md +0 -122
- package/templates/skills/cbp-frontend-a11y/reference/keyboard-patterns.md +0 -154
- package/templates/skills/cbp-frontend-a11y/reference/semantic-html.md +0 -111
package/dist/cli.js
CHANGED
|
@@ -39,7 +39,7 @@ var VERSION, PACKAGE_NAME;
|
|
|
39
39
|
var init_version = __esm({
|
|
40
40
|
"src/lib/version.ts"() {
|
|
41
41
|
"use strict";
|
|
42
|
-
VERSION = "1.13.
|
|
42
|
+
VERSION = "1.13.50";
|
|
43
43
|
PACKAGE_NAME = "codebyplan";
|
|
44
44
|
}
|
|
45
45
|
});
|
|
@@ -639,6 +639,7 @@ var init_gitignore_block = __esm({
|
|
|
639
639
|
".codebyplan/statusline.local.json",
|
|
640
640
|
".codebyplan/worktree.local.json",
|
|
641
641
|
".codebyplan/state/",
|
|
642
|
+
".codebyplan/clear/",
|
|
642
643
|
".codebyplan/todo/",
|
|
643
644
|
".codebyplan/claude-status.local.json",
|
|
644
645
|
".codebyplan.local.json"
|
package/package.json
CHANGED
|
@@ -239,18 +239,13 @@ When the executor received a `wave` input with a non-empty `wave.skill_preloads[
|
|
|
239
239
|
For each entry in `wave.skill_preloads[]`, invoke the named skill via the Skill tool BEFORE Step 3 (Execute). Invoke in order:
|
|
240
240
|
|
|
241
241
|
1. `cbp-frontend-design` — if present, invoke FIRST (aesthetic direction before code)
|
|
242
|
-
2.
|
|
243
|
-
3. Any other skill preload — invoke in list order
|
|
242
|
+
2. Any other skill preload — invoke in list order
|
|
244
243
|
|
|
245
244
|
Record completion:
|
|
246
245
|
```yaml
|
|
247
246
|
round.context.frontend_design_loaded: true # if cbp-frontend-design was preloaded
|
|
248
|
-
round.context.frontend_a11y_loaded: true # if cbp-frontend-a11y was preloaded
|
|
249
|
-
round.context.frontend_a11y_checklist: [items from cbp-frontend-a11y/SKILL.md Phase 6 output] # only when cbp-frontend-a11y was preloaded for this wave
|
|
250
247
|
```
|
|
251
248
|
|
|
252
|
-
When cbp-frontend-a11y is preloaded, capture its Phase 6 per-component checklist output verbatim into `round.context.frontend_a11y_checklist`. Step 3 reads this for accessibility enforcement during code emission.
|
|
253
|
-
|
|
254
249
|
If `wave` is absent or `wave.skill_preloads[]` is empty, skip this step — Step 2.7 handles the non-wave UI pre-read path.
|
|
255
250
|
|
|
256
251
|
**Why step 2.6 and 2.7 coexist**: Step 2.7 fires for non-wave rounds when the executor detects UI files directly. Step 2.6 fires for wave rounds where the planner already determined the preloads. They cover the same skill but via different trigger paths; the round.context recording is identical so downstream steps behave uniformly.
|
|
@@ -315,6 +310,7 @@ When the approved plan includes specialized work, delegate to sub-executor agent
|
|
|
315
310
|
| Work Type | Agent | When to Delegate |
|
|
316
311
|
|-----------|-------|-----------------|
|
|
317
312
|
| Supabase migrations, RLS, types | `cbp-database-agent` | Plan includes DB schema changes, RLS policies, or type generation |
|
|
313
|
+
| Stripe integration (Checkout, webhooks, subscriptions, customer portal) | `cbp-stripe-agent` | Plan includes Stripe work (files under `stripe/`, or steps referencing `payment`, `checkout`, `webhook`, `subscription`, or `approved_plan.stripe_work === true`) |
|
|
318
314
|
| Batch identical-structure file writes (≥4 files) | `general-purpose` (background) | Plan has 4+ independent files, no shared state, no ordered dependency |
|
|
319
315
|
| `.claude/` infrastructure deliverables | `cbp-cc-executor` | `files_to_modify[]` includes **≥2** `.claude/` files (rules, skills, agents, context, hooks, settings, CLAUDE.md). A single `.claude/` file edit stays on Step 0 Skill-tool routing |
|
|
320
316
|
|
|
@@ -324,6 +320,12 @@ When the approved plan includes specialized work, delegate to sub-executor agent
|
|
|
324
320
|
3. Wait for completion, merge files_changed into executor output
|
|
325
321
|
4. Continue with remaining non-DB steps
|
|
326
322
|
|
|
323
|
+
**How to delegate to `cbp-stripe-agent`:**
|
|
324
|
+
1. Collect all Stripe-related steps from the plan
|
|
325
|
+
2. Spawn `cbp-stripe-agent` via Agent tool with those steps and `files_changed_scope` set to the executor's current `files_to_modify[]` paths
|
|
326
|
+
3. Wait for completion, merge files_changed into executor output
|
|
327
|
+
4. Continue with remaining non-Stripe steps
|
|
328
|
+
|
|
327
329
|
**When NOT to delegate:**
|
|
328
330
|
- Simple Supabase queries in application code (executor handles these)
|
|
329
331
|
- Only delegate schema/migration/RLS/type generation work
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-stripe-agent
|
|
4
|
+
description: Stripe integration specialist. Writes Stripe code (Checkout, webhooks, subscriptions, customer portal) in the consuming app and optionally drives live Stripe via MCP. Spawned as sub-executor by round-executor when the plan includes Stripe work.
|
|
5
|
+
tools: Read, Write, Edit, Glob, Grep, Bash, AskUserQuestion
|
|
6
|
+
model: sonnet
|
|
7
|
+
effort: xhigh
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Stripe Agent
|
|
11
|
+
|
|
12
|
+
Stripe integration specialist for payments, billing, webhooks, Connect, Tax, and Treasury.
|
|
13
|
+
|
|
14
|
+
## Purpose
|
|
15
|
+
|
|
16
|
+
Handles Stripe integration work when a round's plan includes payment code. Spawned by
|
|
17
|
+
round-executor as a sub-executor, not directly by `/cbp-round-start`. Two operating modes:
|
|
18
|
+
|
|
19
|
+
- **Primary (always)** — writes/modifies Stripe integration code in the consuming app using
|
|
20
|
+
the current Stripe Node SDK, guided by the `cbp-stripe` skill's API-selection routing.
|
|
21
|
+
- **Optional (opt-in)** — when a Stripe MCP server is configured AND a restricted/test key is
|
|
22
|
+
present, scaffolds live test data (products, prices, payment links) via that server. Absent
|
|
23
|
+
either, it degrades silently to code-only — never a hard failure.
|
|
24
|
+
|
|
25
|
+
## Input Contract
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
input:
|
|
29
|
+
stripe_tasks: [{step_number, description, type}] # Stripe-related plan steps
|
|
30
|
+
files_changed_scope: string[] # paths the round is allowed to touch
|
|
31
|
+
repo_id: string
|
|
32
|
+
context:
|
|
33
|
+
checkpoint_goal: string
|
|
34
|
+
task_requirements: string
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Output Contract
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
output:
|
|
41
|
+
status: 'completed' | 'blocked' | 'failed'
|
|
42
|
+
live_path_used: boolean # true only when the optional MCP path ran
|
|
43
|
+
files_changed:
|
|
44
|
+
- path: string
|
|
45
|
+
action: 'created' | 'modified' | 'deleted'
|
|
46
|
+
stripe_resources_created: # populated only when live_path_used === true
|
|
47
|
+
- type: string # e.g. 'product' | 'price' | 'payment_link'
|
|
48
|
+
id: string
|
|
49
|
+
mode: 'test' # ALWAYS test — live mode is never scaffolded here
|
|
50
|
+
issues_encountered: string[]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Workflow
|
|
54
|
+
|
|
55
|
+
### Pre-flight: Load Guidance + Resolve Live-Path Availability
|
|
56
|
+
|
|
57
|
+
Run both checks before writing any code:
|
|
58
|
+
|
|
59
|
+
1. **Load the `cbp-stripe` skill** for API-selection routing and security rules. Invoke the
|
|
60
|
+
`cbp-stripe` Skill (or Read `.claude/skills/cbp-stripe/SKILL.md` and the relevant
|
|
61
|
+
`reference/*.md` when Skill dispatch is unavailable). This is the source of truth for
|
|
62
|
+
which Stripe API to use per intent — do not select APIs from memory.
|
|
63
|
+
|
|
64
|
+
2. **Resolve live-path availability.** The optional MCP path runs ONLY when ALL hold:
|
|
65
|
+
- `STRIPE_SECRET_KEY` (or an equivalent restricted-key env var) is present AND is a
|
|
66
|
+
**test-mode** key. Check presence + prefix WITHOUT printing the secret (never `echo` or
|
|
67
|
+
`printenv` the raw value):
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
case "${STRIPE_SECRET_KEY:-}" in
|
|
71
|
+
sk_test_*|rk_test_*) echo "live path: eligible (test key)" ;;
|
|
72
|
+
sk_live_*|rk_live_*) echo "live path: refused (live-mode key)" ;;
|
|
73
|
+
"") echo "live path: skipped (no key)" ;;
|
|
74
|
+
*) echo "live path: refused (unknown prefix ${STRIPE_SECRET_KEY:0:8})" ;;
|
|
75
|
+
esac
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Only `sk_test_`/`rk_test_` enable the live path; live-mode keys (`sk_live_`, `rk_live_`)
|
|
79
|
+
are refused so a dev round never scaffolds real Stripe data.
|
|
80
|
+
- A Stripe MCP server is reachable. Stripe MCP tools (`mcp__stripe__*`) are NOT listed in
|
|
81
|
+
this agent's frontmatter because the server is optional and absent by default; discover
|
|
82
|
+
them at runtime via `ToolSearch` (query `mcp__stripe`). Setup is documented in
|
|
83
|
+
`.claude/skills/cbp-stripe/reference/stripe-mcp-setup.md`.
|
|
84
|
+
|
|
85
|
+
If any condition fails, set `live_path_used = false` and proceed code-only. Record the
|
|
86
|
+
reason in `issues_encountered[]` (e.g. `live path skipped: no STRIPE_SECRET_KEY`). This is
|
|
87
|
+
a normal outcome, NOT a block.
|
|
88
|
+
|
|
89
|
+
### Step 1: Analyze Stripe Tasks
|
|
90
|
+
|
|
91
|
+
Read `stripe_tasks` and categorize by type, mapping each to the `cbp-stripe` routing table:
|
|
92
|
+
|
|
93
|
+
- **One-time payments** → Checkout Sessions (`reference/payments.md`)
|
|
94
|
+
- **Custom payment UI** → Checkout Sessions + Payment Element (`reference/payments.md`)
|
|
95
|
+
- **Saving a payment method** → Setup Intents (`reference/payments.md`)
|
|
96
|
+
- **Subscriptions / recurring billing** → Billing APIs + Checkout Sessions, Customer Portal
|
|
97
|
+
(`reference/billing.md`)
|
|
98
|
+
- **Webhooks** → signed event handler (`reference/security.md`)
|
|
99
|
+
- **Marketplace / platform** → Connect Accounts v2 (`reference/connect.md`)
|
|
100
|
+
- **Tax** → Stripe Tax (`reference/tax.md`); **embedded finance** → Treasury
|
|
101
|
+
(`reference/treasury.md`)
|
|
102
|
+
|
|
103
|
+
### Step 2: Write Stripe Integration Code (PRIMARY)
|
|
104
|
+
|
|
105
|
+
For each task, write or modify code in `files_changed_scope` using the current Stripe Node SDK:
|
|
106
|
+
|
|
107
|
+
1. **Honor the critical rules from the skill**: never pass `payment_method_types` except for
|
|
108
|
+
the documented Terminal and Treasury-bank-account exceptions; prefer dynamic payment
|
|
109
|
+
methods.
|
|
110
|
+
2. **Server-side key handling**: read the key from `process.env` only; never hardcode or log
|
|
111
|
+
it. Prefer a restricted key (`rk_`) over a secret key.
|
|
112
|
+
3. **Next.js API routes that import `stripe` MUST export `export const dynamic =
|
|
113
|
+
'force-dynamic'`** at the top of the file (the SDK reads a runtime env var; static analysis
|
|
114
|
+
at build time fails without it). Source: `.claude/skills/cbp-frontend-design/reference/nextjs-scss.md`
|
|
115
|
+
Rule 6.
|
|
116
|
+
4. **Webhook routes** must verify the signature with `stripe.webhooks.constructEvent(rawBody,
|
|
117
|
+
sig, secret)` against the raw (unparsed) body, and guard the `stripe-signature` header
|
|
118
|
+
(it is typed `string | string[] | undefined`) before use.
|
|
119
|
+
5. Match the consuming app's existing conventions (error handling, response shape, file
|
|
120
|
+
layout). Verify the installed `stripe` major version (`grep '"stripe"' package.json`) and
|
|
121
|
+
write code for that version — the skill notes the latest API version, but consumer repos
|
|
122
|
+
may pin an older SDK.
|
|
123
|
+
|
|
124
|
+
### Step 3: Scaffold Live Test Data (OPTIONAL — only when Pre-flight enabled the live path)
|
|
125
|
+
|
|
126
|
+
When `live_path_used` is eligible AND a task explicitly needs live test data (e.g. "create a
|
|
127
|
+
test product + price for the checkout demo"):
|
|
128
|
+
|
|
129
|
+
1. Re-confirm the key prefix is `sk_test_` or `rk_test_` immediately before the first call.
|
|
130
|
+
Abort the live path on any live-mode key (`sk_live_` or `rk_live_`).
|
|
131
|
+
2. Use the discovered Stripe MCP tools to create only what the task requires (products,
|
|
132
|
+
prices, payment links, test customers). Record each in `stripe_resources_created[]`.
|
|
133
|
+
3. On ANY MCP error (server unreachable, auth rejected, rate limit), fall back to code-only:
|
|
134
|
+
set `live_path_used = false`, record the error in `issues_encountered[]`, and continue —
|
|
135
|
+
never block the round on the optional path.
|
|
136
|
+
|
|
137
|
+
### Step 4: Verify
|
|
138
|
+
|
|
139
|
+
1. For each changed `.ts`/`.tsx` file, run a scoped `npx tsc --noEmit` (or the app's
|
|
140
|
+
typecheck) on the changed set and confirm no new type errors.
|
|
141
|
+
2. Confirm every API route importing `stripe` exports `dynamic = 'force-dynamic'`
|
|
142
|
+
(`grep -L "force-dynamic"` across the changed route files).
|
|
143
|
+
3. Confirm no secret was committed: `grep -rE 'sk_live_|rk_live_|sk_test_[A-Za-z0-9]{16,}|rk_test_[A-Za-z0-9]{16,}'`
|
|
144
|
+
over the changed files returns nothing real. Live-key prefixes (`sk_live_`, `rk_live_`)
|
|
145
|
+
match with no length floor — a committed live key is never acceptable; test-key prefixes
|
|
146
|
+
carry a `{16,}` floor so doc placeholders like `sk_test_…` don't false-positive.
|
|
147
|
+
|
|
148
|
+
### Step 5: Return Output
|
|
149
|
+
|
|
150
|
+
Populate all output-contract fields. Include every file changed. Report the live-path outcome
|
|
151
|
+
(used / skipped + reason) in `issues_encountered[]` for the audit trail.
|
|
152
|
+
|
|
153
|
+
## When NOT to Use This Agent
|
|
154
|
+
|
|
155
|
+
- Non-payment application code (round-executor handles these).
|
|
156
|
+
- Reading Stripe data for display only with no integration change.
|
|
157
|
+
- Designing the payment UX/visual layer — that is the frontend skills' job; this agent writes
|
|
158
|
+
the Stripe wiring beneath it.
|
|
159
|
+
- Production / live-mode Stripe operations (`sk_live_`, `rk_live_`) — this agent refuses
|
|
160
|
+
live-mode keys by design; only test-mode keys enable the optional live path.
|
|
161
|
+
|
|
162
|
+
## Integration
|
|
163
|
+
|
|
164
|
+
- **Spawned by**: `round-executor` (as sub-executor when the plan includes Stripe work — see
|
|
165
|
+
`cbp-round-executor` Step 3.5 and `/cbp-round-execute` Step 3b-stripe dispatch).
|
|
166
|
+
- **Returns to**: `round-executor` (merges `files_changed[]` into the round output).
|
|
167
|
+
- **Loads**: the `cbp-stripe` skill (`.claude/skills/cbp-stripe/SKILL.md` + `reference/*.md`)
|
|
168
|
+
for API selection and security rules.
|
|
169
|
+
- **Optional tools**: Stripe MCP (`mcp__stripe__*`) discovered at runtime via `ToolSearch`
|
|
170
|
+
when a server is configured per `.claude/skills/cbp-stripe/reference/stripe-mcp-setup.md` —
|
|
171
|
+
intentionally absent from frontmatter because the server is opt-in.
|
|
172
|
+
- **Rule**: never commit Stripe secrets; restricted/test keys only; degrade to code-only when
|
|
173
|
+
the live path is unavailable.
|
|
@@ -533,7 +533,7 @@ After Phase 5 (solution design) and before Phase 6 (context summary), decompose
|
|
|
533
533
|
1. **Identify natural cut points**: look for cross-app boundaries (files in `apps/web/` vs `apps/backend/` vs `apps/desktop/`), packages with no shared state, or dependency ordering (DB migration must precede app code using the new schema).
|
|
534
534
|
2. **Check disjoint-files invariant**: no file may appear in two waves. If a shared file is needed by two waves, assign it to the earlier wave and make the later wave `depends_on` the earlier.
|
|
535
535
|
3. **Check DAG invariant**: `depends_on[]` must be acyclic. Any cycle is a plan error — resolve by merging the cyclic waves.
|
|
536
|
-
4. **Populate `skill_preloads[]`**: for each wave whose `files[]` contains UI-bearing paths (`*.tsx`, `*.jsx`, `*.scss`, etc.), add `"frontend-design"`
|
|
536
|
+
4. **Populate `skill_preloads[]`**: for each wave whose `files[]` contains UI-bearing paths (`*.tsx`, `*.jsx`, `*.scss`, etc.), add `"frontend-design"` to `skill_preloads[]`.
|
|
537
537
|
5. **Single-wave default**: if no independence is found, produce ONE wave covering all files. Parallel waves add orchestration overhead — only decompose when the benefit is clear.
|
|
538
538
|
6. **15-file cap**: after decomposition (including the single-wave default), count files in each wave. If any wave would exceed 15 files, auto-split it using the proximity-split algorithm in priority order: (a) **shared directory subtree** — split at the deepest common ancestor that produces two groups each ≥3 files; (b) **shared module** — split at the next directory level below the common ancestor; (c) **arbitrary boundary** — split at the 15-file boundary and add a one-line `note` on the continuation wave explaining the boundary. Split siblings are **independent**: do NOT add `depends_on` between them unless a real shared-file or data dependency requires ordering. **Tail rule**: choose boundaries so every resulting wave holds 3–15 files. A split must never leave a wave with <3 files; rebalance the boundary rather than absorbing a tail into a sibling in a way that pushes it above 15. The 3–15 range is a hard invariant — there is no exception above 15. **Apply the cap iteratively**: after a split, re-check each resulting wave and split again any that still exceeds 15 — a 40-file single-concern plan therefore yields ≥3 waves. When no natural boundary yields groups each ≥3 files, take the smallest ≥3-file prefix as one wave and apply the same procedure to the remainder. The single-wave default is itself subject to this cap. See `rules/parallel-waves.md` for the full algorithm and invariants.
|
|
539
539
|
|
|
@@ -559,7 +559,7 @@ printf '%s' "$PLAN_JSON" | codebyplan validate-waves --json
|
|
|
559
559
|
|
|
560
560
|
(`$PLAN_JSON` is the `{ "waves": [...] }` structure; pass a file path as the first argument instead of stdin if preferred.) Exit 0 = invariants I–III satisfied. Exit non-zero = one or more violations — the `--json` `violations[]` array names the failing invariant (`I`/`II`/`III`) and offending wave/file; fix the decomposition and re-run before emitting the plan. The validator does NOT check invariant IV (UI skill preloads) — that remains a manual step:
|
|
561
561
|
|
|
562
|
-
- [ ] UI-bearing waves have `frontend-design`
|
|
562
|
+
- [ ] UI-bearing waves have `frontend-design` in `skill_preloads[]` (invariant IV — not covered by `validate-waves`)
|
|
563
563
|
|
|
564
564
|
### Phase 6: Build Context Summary
|
|
565
565
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# @scope: org-shared
|
|
3
|
+
# Hook: PreToolUse (Skill)
|
|
4
|
+
# Purpose: Deny heavy close-out skills when context window > CBP_CONTEXT_WARN_TOKENS (default 200000).
|
|
5
|
+
# Reads transcript_path from stdin, sums the latest assistant message.usage — same logic
|
|
6
|
+
# as cbp-context-window-notify.sh. If total exceeds threshold AND the skill is in the
|
|
7
|
+
# heavy close-out allowlist, emits hookSpecificOutput.permissionDecision=deny directing
|
|
8
|
+
# Claude to run /cbp-clear-prep. Always exits 0 — fail-open.
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
INPUT=$(cat)
|
|
13
|
+
SKILL_NAME=$(echo "$INPUT" | jq -r '.tool_input.skill // .tool_input.skill_name // ""' 2>/dev/null) || SKILL_NAME=""
|
|
14
|
+
TRANSCRIPT=$(echo "$INPUT" | jq -r '.transcript_path // ""' 2>/dev/null) || TRANSCRIPT=""
|
|
15
|
+
|
|
16
|
+
# Fast-path: no transcript → pass through
|
|
17
|
+
[ -z "$TRANSCRIPT" ] && exit 0
|
|
18
|
+
[ ! -f "$TRANSCRIPT" ] && exit 0
|
|
19
|
+
|
|
20
|
+
THRESHOLD="${CBP_CONTEXT_WARN_TOKENS:-200000}"
|
|
21
|
+
|
|
22
|
+
# Heavy close-out allowlist (cbp-clear-prep + cbp-clear-continue deliberately excluded so
|
|
23
|
+
# they always run even when context > threshold).
|
|
24
|
+
HEAVY_SKILLS="cbp-round-execute cbp-task-testing cbp-standalone-task-testing cbp-checkpoint-check cbp-checkpoint-end"
|
|
25
|
+
|
|
26
|
+
# Cheap allowlist check before summing tokens
|
|
27
|
+
IS_HEAVY=false
|
|
28
|
+
for heavy in $HEAVY_SKILLS; do
|
|
29
|
+
if [ "$SKILL_NAME" = "$heavy" ]; then
|
|
30
|
+
IS_HEAVY=true
|
|
31
|
+
break
|
|
32
|
+
fi
|
|
33
|
+
done
|
|
34
|
+
[ "$IS_HEAVY" = "false" ] && exit 0
|
|
35
|
+
|
|
36
|
+
# Token sum — same logic as cbp-context-window-notify.sh
|
|
37
|
+
TOTAL=$(tail -n 400 "$TRANSCRIPT" \
|
|
38
|
+
| jq -rR 'fromjson? | select(.message.usage != null)
|
|
39
|
+
| (.message.usage
|
|
40
|
+
| ((.input_tokens // 0) + (.cache_creation_input_tokens // 0) + (.cache_read_input_tokens // 0)))' \
|
|
41
|
+
2>/dev/null | tail -1) || TOTAL=0
|
|
42
|
+
TOTAL="${TOTAL:-0}"
|
|
43
|
+
|
|
44
|
+
if [ "$TOTAL" -ge "$THRESHOLD" ] 2>/dev/null; then
|
|
45
|
+
jq -n \
|
|
46
|
+
--argjson tokens "$TOTAL" \
|
|
47
|
+
--argjson threshold "$THRESHOLD" \
|
|
48
|
+
--arg skill "$SKILL_NAME" \
|
|
49
|
+
'{hookSpecificOutput:{permissionDecision:"deny",permissionDecisionReason:("Context window at \($tokens) tokens (threshold \($threshold)) is too large to safely run /\($skill). Run /cbp-clear-prep now to capture a handoff, then /clear, then /cbp-clear-continue to resume.")}}'
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
exit 0
|
|
@@ -527,6 +527,150 @@ fi
|
|
|
527
527
|
|
|
528
528
|
echo ""
|
|
529
529
|
|
|
530
|
+
# ===== HOOK SMOKE TESTS — cbp-skill-context-guard =====
|
|
531
|
+
echo "## Hook Smoke Tests — cbp-skill-context-guard (CHK-217)"
|
|
532
|
+
|
|
533
|
+
GUARD_HOOK="$HOOKS_DIR/cbp-skill-context-guard.sh"
|
|
534
|
+
FIXTURES_GUARD="$HOOKS_DIR/__test-fixtures__/cbp-context-window-notify"
|
|
535
|
+
|
|
536
|
+
if [ ! -f "$GUARD_HOOK" ]; then
|
|
537
|
+
test_result "cbp-skill-context-guard.sh present" "passed" "missing"
|
|
538
|
+
else
|
|
539
|
+
|
|
540
|
+
# Case 1: over-threshold + cbp-round-execute (heavy) → permissionDecision=deny
|
|
541
|
+
STDIN=$(jq -n \
|
|
542
|
+
--arg t "$FIXTURES_GUARD/over-threshold.jsonl" \
|
|
543
|
+
--arg s "cbp-round-execute" \
|
|
544
|
+
'{transcript_path:$t,tool_input:{skill:$s}}')
|
|
545
|
+
OUTPUT=$(echo "$STDIN" | CBP_CONTEXT_WARN_TOKENS=200000 bash "$GUARD_HOOK" 2>/dev/null)
|
|
546
|
+
EXIT_CODE=$?
|
|
547
|
+
if [ "$EXIT_CODE" = "0" ] \
|
|
548
|
+
&& echo "$OUTPUT" | jq -e '.hookSpecificOutput.permissionDecision == "deny"' >/dev/null 2>&1; then
|
|
549
|
+
test_result "cbp-skill-context-guard.sh over-threshold + cbp-round-execute → deny" "passed" "passed"
|
|
550
|
+
else
|
|
551
|
+
test_result "cbp-skill-context-guard.sh over-threshold + cbp-round-execute → deny" "passed" "failed (exit=$EXIT_CODE output=$(echo "$OUTPUT" | head -c 80))"
|
|
552
|
+
fi
|
|
553
|
+
|
|
554
|
+
# Case 2: over-threshold + cbp-clear-prep (exempt) → empty stdout, exit 0
|
|
555
|
+
STDIN=$(jq -n \
|
|
556
|
+
--arg t "$FIXTURES_GUARD/over-threshold.jsonl" \
|
|
557
|
+
--arg s "cbp-clear-prep" \
|
|
558
|
+
'{transcript_path:$t,tool_input:{skill:$s}}')
|
|
559
|
+
OUTPUT=$(echo "$STDIN" | CBP_CONTEXT_WARN_TOKENS=200000 bash "$GUARD_HOOK" 2>/dev/null)
|
|
560
|
+
EXIT_CODE=$?
|
|
561
|
+
if [ "$EXIT_CODE" = "0" ] && [ -z "$OUTPUT" ]; then
|
|
562
|
+
test_result "cbp-skill-context-guard.sh over-threshold + cbp-clear-prep (exempt) → empty stdout" "passed" "passed"
|
|
563
|
+
else
|
|
564
|
+
test_result "cbp-skill-context-guard.sh over-threshold + cbp-clear-prep (exempt) → empty stdout" "passed" "failed (exit=$EXIT_CODE)"
|
|
565
|
+
fi
|
|
566
|
+
|
|
567
|
+
# Case 3: over-threshold + cbp-clear-continue (exempt) → empty stdout, exit 0
|
|
568
|
+
STDIN=$(jq -n \
|
|
569
|
+
--arg t "$FIXTURES_GUARD/over-threshold.jsonl" \
|
|
570
|
+
--arg s "cbp-clear-continue" \
|
|
571
|
+
'{transcript_path:$t,tool_input:{skill:$s}}')
|
|
572
|
+
OUTPUT=$(echo "$STDIN" | CBP_CONTEXT_WARN_TOKENS=200000 bash "$GUARD_HOOK" 2>/dev/null)
|
|
573
|
+
EXIT_CODE=$?
|
|
574
|
+
if [ "$EXIT_CODE" = "0" ] && [ -z "$OUTPUT" ]; then
|
|
575
|
+
test_result "cbp-skill-context-guard.sh over-threshold + cbp-clear-continue (exempt) → empty stdout" "passed" "passed"
|
|
576
|
+
else
|
|
577
|
+
test_result "cbp-skill-context-guard.sh over-threshold + cbp-clear-continue (exempt) → empty stdout" "passed" "failed (exit=$EXIT_CODE)"
|
|
578
|
+
fi
|
|
579
|
+
|
|
580
|
+
# Case 4: under-threshold + cbp-round-execute → empty stdout, exit 0
|
|
581
|
+
STDIN=$(jq -n \
|
|
582
|
+
--arg t "$FIXTURES_GUARD/under-threshold.jsonl" \
|
|
583
|
+
--arg s "cbp-round-execute" \
|
|
584
|
+
'{transcript_path:$t,tool_input:{skill:$s}}')
|
|
585
|
+
OUTPUT=$(echo "$STDIN" | CBP_CONTEXT_WARN_TOKENS=200000 bash "$GUARD_HOOK" 2>/dev/null)
|
|
586
|
+
EXIT_CODE=$?
|
|
587
|
+
if [ "$EXIT_CODE" = "0" ] && [ -z "$OUTPUT" ]; then
|
|
588
|
+
test_result "cbp-skill-context-guard.sh under-threshold + cbp-round-execute → empty stdout" "passed" "passed"
|
|
589
|
+
else
|
|
590
|
+
test_result "cbp-skill-context-guard.sh under-threshold + cbp-round-execute → empty stdout" "passed" "failed (exit=$EXIT_CODE)"
|
|
591
|
+
fi
|
|
592
|
+
|
|
593
|
+
# Case 5: empty skill_name → empty stdout, exit 0
|
|
594
|
+
STDIN=$(jq -n \
|
|
595
|
+
--arg t "$FIXTURES_GUARD/over-threshold.jsonl" \
|
|
596
|
+
'{transcript_path:$t,tool_input:{}}')
|
|
597
|
+
OUTPUT=$(echo "$STDIN" | CBP_CONTEXT_WARN_TOKENS=200000 bash "$GUARD_HOOK" 2>/dev/null)
|
|
598
|
+
EXIT_CODE=$?
|
|
599
|
+
if [ "$EXIT_CODE" = "0" ] && [ -z "$OUTPUT" ]; then
|
|
600
|
+
test_result "cbp-skill-context-guard.sh empty skill_name → empty stdout" "passed" "passed"
|
|
601
|
+
else
|
|
602
|
+
test_result "cbp-skill-context-guard.sh empty skill_name → empty stdout" "passed" "failed (exit=$EXIT_CODE)"
|
|
603
|
+
fi
|
|
604
|
+
|
|
605
|
+
# Case 6: missing transcript_path → empty stdout, exit 0 (fast-path)
|
|
606
|
+
STDIN=$(jq -n --arg s "cbp-round-execute" '{tool_input:{skill:$s}}')
|
|
607
|
+
OUTPUT=$(echo "$STDIN" | CBP_CONTEXT_WARN_TOKENS=200000 bash "$GUARD_HOOK" 2>/dev/null)
|
|
608
|
+
EXIT_CODE=$?
|
|
609
|
+
if [ "$EXIT_CODE" = "0" ] && [ -z "$OUTPUT" ]; then
|
|
610
|
+
test_result "cbp-skill-context-guard.sh missing transcript_path → empty stdout" "passed" "passed"
|
|
611
|
+
else
|
|
612
|
+
test_result "cbp-skill-context-guard.sh missing transcript_path → empty stdout" "passed" "failed (exit=$EXIT_CODE)"
|
|
613
|
+
fi
|
|
614
|
+
|
|
615
|
+
fi
|
|
616
|
+
|
|
617
|
+
# ===== STRUCTURAL ASSERTIONS — cbp-clear-* skills (CHK-217) =====
|
|
618
|
+
echo ""
|
|
619
|
+
echo "## Structural Assertions — cbp-clear-* skills (CHK-217)"
|
|
620
|
+
|
|
621
|
+
# cbp-clear-prep/SKILL.md: scope: org-shared + references handoff.md
|
|
622
|
+
CLEAR_PREP_SKILL="$(dirname "$HOOKS_DIR")/skills/cbp-clear-prep/SKILL.md"
|
|
623
|
+
if [ -f "$CLEAR_PREP_SKILL" ]; then
|
|
624
|
+
if grep -q 'scope: org-shared' "$CLEAR_PREP_SKILL"; then
|
|
625
|
+
test_result "cbp-clear-prep/SKILL.md has scope: org-shared" "passed" "passed"
|
|
626
|
+
else
|
|
627
|
+
test_result "cbp-clear-prep/SKILL.md has scope: org-shared" "passed" "missing"
|
|
628
|
+
fi
|
|
629
|
+
if grep -q 'handoff\.md' "$CLEAR_PREP_SKILL"; then
|
|
630
|
+
test_result "cbp-clear-prep/SKILL.md references handoff.md" "passed" "passed"
|
|
631
|
+
else
|
|
632
|
+
test_result "cbp-clear-prep/SKILL.md references handoff.md" "passed" "missing"
|
|
633
|
+
fi
|
|
634
|
+
else
|
|
635
|
+
test_result "cbp-clear-prep/SKILL.md structural checks (file absent — skipped)" "passed" "passed"
|
|
636
|
+
fi
|
|
637
|
+
|
|
638
|
+
# cbp-clear-continue/SKILL.md: scope: org-shared + references handoff.md + has rm of handoff
|
|
639
|
+
CLEAR_CONTINUE_SKILL="$(dirname "$HOOKS_DIR")/skills/cbp-clear-continue/SKILL.md"
|
|
640
|
+
if [ -f "$CLEAR_CONTINUE_SKILL" ]; then
|
|
641
|
+
if grep -q 'scope: org-shared' "$CLEAR_CONTINUE_SKILL"; then
|
|
642
|
+
test_result "cbp-clear-continue/SKILL.md has scope: org-shared" "passed" "passed"
|
|
643
|
+
else
|
|
644
|
+
test_result "cbp-clear-continue/SKILL.md has scope: org-shared" "passed" "missing"
|
|
645
|
+
fi
|
|
646
|
+
if grep -q 'handoff\.md' "$CLEAR_CONTINUE_SKILL"; then
|
|
647
|
+
test_result "cbp-clear-continue/SKILL.md references handoff.md" "passed" "passed"
|
|
648
|
+
else
|
|
649
|
+
test_result "cbp-clear-continue/SKILL.md references handoff.md" "passed" "missing"
|
|
650
|
+
fi
|
|
651
|
+
if grep -Eq 'rm -f.*handoff' "$CLEAR_CONTINUE_SKILL"; then
|
|
652
|
+
test_result "cbp-clear-continue/SKILL.md has rm -f of handoff.md" "passed" "passed"
|
|
653
|
+
else
|
|
654
|
+
test_result "cbp-clear-continue/SKILL.md has rm -f of handoff.md" "passed" "missing"
|
|
655
|
+
fi
|
|
656
|
+
else
|
|
657
|
+
test_result "cbp-clear-continue/SKILL.md structural checks (file absent — skipped)" "passed" "passed"
|
|
658
|
+
fi
|
|
659
|
+
|
|
660
|
+
# .gitignore contains .codebyplan/clear/
|
|
661
|
+
REPO_GITIGNORE="${CLAUDE_PROJECT_DIR:-}/.gitignore"
|
|
662
|
+
if [ -n "${CLAUDE_PROJECT_DIR:-}" ] && [ -f "$REPO_GITIGNORE" ]; then
|
|
663
|
+
if grep -q '\.codebyplan/clear/' "$REPO_GITIGNORE"; then
|
|
664
|
+
test_result ".gitignore contains .codebyplan/clear/" "passed" "passed"
|
|
665
|
+
else
|
|
666
|
+
test_result ".gitignore contains .codebyplan/clear/" "passed" "missing"
|
|
667
|
+
fi
|
|
668
|
+
else
|
|
669
|
+
test_result ".gitignore check skipped (CLAUDE_PROJECT_DIR unset or no .gitignore)" "passed" "passed"
|
|
670
|
+
fi
|
|
671
|
+
|
|
672
|
+
echo ""
|
|
673
|
+
|
|
530
674
|
# ===== SUMMARY =====
|
|
531
675
|
echo "=== TEST SUMMARY ==="
|
|
532
676
|
echo -e "Passed: ${GREEN}$PASSED${NC}"
|
|
@@ -52,6 +52,15 @@
|
|
|
52
52
|
}
|
|
53
53
|
]
|
|
54
54
|
},
|
|
55
|
+
{
|
|
56
|
+
"matcher": "Skill",
|
|
57
|
+
"hooks": [
|
|
58
|
+
{
|
|
59
|
+
"type": "command",
|
|
60
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/cbp-skill-context-guard.sh"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
55
64
|
{
|
|
56
65
|
"matcher": "mcp__codebyplan__(update_task|complete_task|update_checkpoint|create_checkpoint|create_task)",
|
|
57
66
|
"hooks": [
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Model Invocation Convention
|
|
2
|
+
|
|
3
|
+
CBP skills are **model-invocable by default**. Authors must omit `disable-model-invocation` unless
|
|
4
|
+
a skill is strictly user-only (i.e. it must never auto-trigger from another skill).
|
|
5
|
+
|
|
6
|
+
## Default: omit `disable-model-invocation`
|
|
7
|
+
|
|
8
|
+
The absence of `disable-model-invocation` (or `disable-model-invocation: false`) is the normal
|
|
9
|
+
state. It allows the skill to be auto-triggered via the Skill tool from within other skills —
|
|
10
|
+
which is how the auto-trigger close-out flow works (e.g. `cbp-task-check` → `cbp-task-testing`,
|
|
11
|
+
`cbp-task-testing` → `cbp-task-complete`).
|
|
12
|
+
|
|
13
|
+
## The sole exception: `cbp-round-complete`
|
|
14
|
+
|
|
15
|
+
`cbp-round-complete` sets `disable-model-invocation: true`. It is the permission-gated round
|
|
16
|
+
finalizer: the user must explicitly run it after their own `git add` selections, so it must
|
|
17
|
+
never auto-fire from within another skill. The `ask`-tier permission prompt on
|
|
18
|
+
`Skill(cbp-round-complete)` is a secondary gate on top of this; the frontmatter flag is the
|
|
19
|
+
primary model-invocation block.
|
|
20
|
+
|
|
21
|
+
No other skill in the CBP framework sets this flag. Do NOT add it to new skills without a
|
|
22
|
+
clear "user-only" rationale.
|
|
23
|
+
|
|
24
|
+
## Human gates for auto-triggering skills
|
|
25
|
+
|
|
26
|
+
For auto-trigger skills, the human checkpoint is expressed via two complementary mechanisms —
|
|
27
|
+
not via `disable-model-invocation`:
|
|
28
|
+
|
|
29
|
+
1. **`ask`-tier permission entry** in `settings.json` — the harness permission prompt is the
|
|
30
|
+
lightweight confirm gate. Skills in `ask` auto-fire silently ONLY after the user confirms.
|
|
31
|
+
2. **Routing prose** inside the triggering skill — states explicitly which skill fires next and
|
|
32
|
+
under what condition, so the intent is auditable and overridable.
|
|
33
|
+
|
|
34
|
+
See `.claude/skills/cbp-build-cc-settings/reference/cbp-permission-policy.md` for the full
|
|
35
|
+
`allow` vs `ask` split and the auto-trigger + 200K context-guard model.
|
|
36
|
+
|
|
37
|
+
## Related
|
|
38
|
+
|
|
39
|
+
- `rules/scope-vocabulary.md` — scope marker conventions for managed vs user-created files
|
|
40
|
+
- `cbp-build-cc-settings/reference/cbp-permission-policy.md` — allow/ask tiers
|
|
@@ -33,7 +33,7 @@ Each entry in `plan.waves[]` carries these fields (source: `.claude/agents/cbp-t
|
|
|
33
33
|
- Above 15: apply the proximity-split algorithm below.
|
|
34
34
|
- Sole exception — trivially small plans are exempt from the lower bound: a plan with fewer than 3 total files uses one single wave, and a single-app plan with ≤5 total files MAY skip decomposition entirely (one wave, or `waves[]` omitted — see `cbp-task-planner` Phase 5.6). Zero waves (omitted `waves[]`) trivially satisfies this invariant.
|
|
35
35
|
|
|
36
|
-
**(IV) UI skill preloads** — for each wave whose `files[]` contains UI-bearing paths (`*.tsx`, `*.jsx`, `*.scss`, etc.), add `"frontend-design"`
|
|
36
|
+
**(IV) UI skill preloads** — for each wave whose `files[]` contains UI-bearing paths (`*.tsx`, `*.jsx`, `*.scss`, etc.), add `"frontend-design"` to `skill_preloads[]` (source: `.claude/agents/cbp-task-planner.md` Phase 5.6 step "Populate `skill_preloads[]`").
|
|
37
37
|
|
|
38
38
|
## Proximity-Split Algorithm
|
|
39
39
|
|
|
@@ -45,7 +45,7 @@ After task completion, routes use single-directive form (never A/B/C menus):
|
|
|
45
45
|
|
|
46
46
|
**Checkpoint-bound task complete:**
|
|
47
47
|
- More tasks in checkpoint → auto-triggers next task (same context)
|
|
48
|
-
- Last task in checkpoint → `
|
|
48
|
+
- Last task in checkpoint → auto-triggers `cbp-checkpoint-check` (ask-tier permission prompt is the human gate; the 200K context guard handles oversized contexts)
|
|
49
49
|
|
|
50
50
|
**Standalone task complete:**
|
|
51
51
|
- Always → `Next: /cbp-session-end` (or `/cbp-standalone-task-create` for new work)
|
|
@@ -68,6 +68,18 @@
|
|
|
68
68
|
"mcp__codebyplan__delete_session_log",
|
|
69
69
|
"mcp__codebyplan__delete_worktree",
|
|
70
70
|
"mcp__codebyplan__release_assignment",
|
|
71
|
+
"mcp__stripe__create_customer",
|
|
72
|
+
"mcp__stripe__create_product",
|
|
73
|
+
"mcp__stripe__create_price",
|
|
74
|
+
"mcp__stripe__create_payment_link",
|
|
75
|
+
"mcp__stripe__create_invoice",
|
|
76
|
+
"mcp__stripe__create_subscription",
|
|
77
|
+
"mcp__stripe__update_subscription",
|
|
78
|
+
"mcp__stripe__create_refund",
|
|
79
|
+
"mcp__stripe__list_customers",
|
|
80
|
+
"mcp__stripe__list_products",
|
|
81
|
+
"mcp__stripe__list_prices",
|
|
82
|
+
"mcp__stripe__list_invoices",
|
|
71
83
|
"Bash(codebyplan setup:*)",
|
|
72
84
|
"Bash(npx codebyplan setup:*)",
|
|
73
85
|
"Bash(codebyplan create-org:*)",
|
|
@@ -104,7 +116,8 @@
|
|
|
104
116
|
"Skill(cbp-build-cc-skill)",
|
|
105
117
|
"Skill(cbp-checkpoint-plan)",
|
|
106
118
|
"Skill(cbp-checkpoint-update)",
|
|
107
|
-
"Skill(cbp-
|
|
119
|
+
"Skill(cbp-clear-continue)",
|
|
120
|
+
"Skill(cbp-clear-prep)",
|
|
108
121
|
"Skill(cbp-frontend-design)",
|
|
109
122
|
"Skill(cbp-frontend-ui)",
|
|
110
123
|
"Skill(cbp-frontend-ux)",
|
|
@@ -127,6 +140,7 @@
|
|
|
127
140
|
"Skill(cbp-ship-configure)",
|
|
128
141
|
"Skill(cbp-standalone-task-check)",
|
|
129
142
|
"Skill(cbp-standalone-task-testing)",
|
|
143
|
+
"Skill(cbp-stripe)",
|
|
130
144
|
"Skill(cbp-supabase-branch-check)",
|
|
131
145
|
"Skill(cbp-supabase-migrate)",
|
|
132
146
|
"Skill(cbp-supabase-setup)",
|
|
@@ -45,6 +45,48 @@ The pre-existing dangerous-`rm -rf` blocks. This policy does not alter `deny` se
|
|
|
45
45
|
|
|
46
46
|
When you add a skill / MCP tool / CLI subcommand, add its matching rule (`Skill(<name>)`, `mcp__codebyplan__<name>`, or `Bash(codebyplan <sub>:*)` + `Bash(npx codebyplan <sub>:*)`) to `allow` or `ask` in `templates/settings.project.base.json` — and mirror it into any dogfooding `.claude/settings.json`.
|
|
47
47
|
|
|
48
|
+
## Auto-trigger + allow/ask gating model
|
|
49
|
+
|
|
50
|
+
The CBP close-out flow uses **auto-triggers** instead of manual "Next: /cbp-X" directives.
|
|
51
|
+
A skill invokes the next skill via the Skill tool at the appropriate routing branch.
|
|
52
|
+
|
|
53
|
+
### How the human gate works
|
|
54
|
+
|
|
55
|
+
- **`allow`-tier** skill: the harness auto-fires it silently when the triggering skill invokes it.
|
|
56
|
+
No permission prompt. Use for safe, routine-flow skills (e.g. `cbp-task-testing`,
|
|
57
|
+
`cbp-round-input`) where the trigger condition already encodes the human intent.
|
|
58
|
+
- **`ask`-tier** skill: the harness pauses and shows a permission prompt before the skill runs.
|
|
59
|
+
**That prompt IS the human gate** — it replaces the old "Next: /cbp-X, run it yourself"
|
|
60
|
+
manual directive. Use for lifecycle/state-transition skills (e.g. `cbp-task-complete`,
|
|
61
|
+
`cbp-checkpoint-check`) where a deliberate confirmation is still desirable.
|
|
62
|
+
|
|
63
|
+
This means:
|
|
64
|
+
- A skill in `allow` that is auto-triggered fires silently — do NOT claim "the ask-tier prompt
|
|
65
|
+
is the gate" for it in routing prose.
|
|
66
|
+
- A skill in `ask` that is auto-triggered shows a permission prompt — that prompt is the gate;
|
|
67
|
+
say so in the routing prose.
|
|
68
|
+
|
|
69
|
+
### The 200K context guard
|
|
70
|
+
|
|
71
|
+
The `cbp-skill-context-guard.sh` PreToolUse hook denies heavy close-out skills when the
|
|
72
|
+
context window exceeds `CBP_CONTEXT_WARN_TOKENS` (default 200 000 tokens). The heavy allowlist
|
|
73
|
+
is: `cbp-round-execute`, `cbp-task-testing`, `cbp-standalone-task-testing`,
|
|
74
|
+
`cbp-checkpoint-check`, `cbp-checkpoint-end`.
|
|
75
|
+
|
|
76
|
+
When the guard fires, it directs the model to run `/cbp-clear-prep` instead. The flow is:
|
|
77
|
+
`cbp-clear-prep` (captures a handoff) → `/clear` (user command) → `cbp-clear-continue`
|
|
78
|
+
(re-invokes the blocked skill in the fresh context).
|
|
79
|
+
|
|
80
|
+
`cbp-clear-prep` and `cbp-clear-continue` are **excluded** from the guard's allowlist so they
|
|
81
|
+
always run regardless of context size.
|
|
82
|
+
|
|
83
|
+
Routing prose in triggering skills should NOT mandate an unconditional `/clear` before a heavy
|
|
84
|
+
skill — the guard handles oversized contexts automatically. Drop "Run /clear first" directives
|
|
85
|
+
from auto-trigger paths; only note the guard mechanism so the author understands when it fires.
|
|
86
|
+
|
|
87
|
+
See `rules/model-invocation-convention.md` for the `disable-model-invocation` convention —
|
|
88
|
+
authors must omit it on all skills except `cbp-round-complete`.
|
|
89
|
+
|
|
48
90
|
## Scope
|
|
49
91
|
|
|
50
92
|
`scope: org-shared` — CBP-framework infrastructure that lands identically in every consuming repo via the `codebyplan` package.
|