Skip to content

feat: blast radius preflight gate via charter blast (#20) - #22

Merged
stackbilt-admin merged 2 commits into
mainfrom
feat/blast-radius-preflight
Apr 9, 2026
Merged

feat: blast radius preflight gate via charter blast (#20)#22
stackbilt-admin merged 2 commits into
mainfrom
feat/blast-radius-preflight

Conversation

@stackbilt-admin

Copy link
Copy Markdown
Member

Summary

  • Closesfeat: blast radius preflight gate via charter blast #20 — adds a deterministic autonomous-safety gate that refuses to execute auto_safe tasks targeting architectural hubs.
  • Runs charter blast --format json on file paths extracted from the task prompt; classifies severity on a 4-level ladder; blocks execution when critical.
  • High/critical severities also inject a ## Blast Radius Warning section into the mission brief so the agent understands scope even when the task is allowed to proceed.
  • Zero runtime dependencies beyond charter CLI 0.10.0 being on PATH. Gracefully no-ops when charter is unavailable.
  • Applied symmetrically to taskrunner.sh and plugin/taskrunner.sh.

Severity ladder

Affected filesSeverityBehavior
0–4lowsilent
5–19mediumsilent
20–49highwarning injected into mission brief
50+criticalwarning injected; auto_safe tasks refused

Environment knobs

CC_DISABLE_BLAST=1 # opt out entirely
CC_BLAST_WARN=20 # high threshold (default)
CC_BLAST_BLOCK=50 # critical threshold (default)
CC_BLAST_TIMEOUT=60 # charter blast timeout in seconds (default)

Graceful degradation

All of these are no-ops that let the task run as before:

  • Charter CLI not installed
  • CC_DISABLE_BLAST=1 set
  • No recognizable file paths in the prompt (.ts / .tsx / .js / .jsx / .mjs / .cjs)
  • charter blast fails or times out
  • Target repo doesn't exist on this runner

How the gate fires

# Before
task { authority: auto_safe, prompt: "Refactor src/kernel/dispatch.ts ..." }
→ runs Claude, burns ~30 turns, produces 72-file PR, reviewer cries
# After
task { authority: auto_safe, prompt: "Refactor src/kernel/dispatch.ts ..." }
→ compute_blast_radius extracts dispatch.ts
→ charter blast reports 72 affected files (critical)
→ gate logs "⚠ GATE: blast radius critical — refusing auto_safe execution"
→ update_task_status("failed", "TASK_BLOCKED: blast_radius_critical — 72 files affected")
→ returns without spawning Claude

Operator can still force execution by changing the task's authority to operator and re-queuing. The gate only refuses auto_safe.

Real-world validation

Tested against a 263-file TypeScript Cloudflare Worker codebase:

Seed fileAffectedSeverityGate action
version.ts (leaf)5mediumproceed
chat-session.ts (isolated DO)1lowproceed
dispatch.ts (orchestrator)72criticalrefuse
types.ts (central types)127criticalrefuse

Also tested:

  • Prompt with no file paths → no-op, no blast data returned
  • Prompt with .ts file that doesn't exist in repo → no-op, file filtered out
  • High severity (20–49) → warning rendered, not blocked
  • Low severity (0–4) → warning empty, not blocked

Seed count cap

The helper caps seed files at 10 to prevent runaway prompts from exploding the blast call. If a prompt lists 47 .ts files, only the first 10 (after sort) are fed to charter.

Prompt brief excerpt

When a high or critical severity fires, the mission brief looks like:

# MISSION BRIEF — Autonomous Task
You are operating autonomously in an unattended Claude Code session.
Read files before modifying them. Be thorough.
## Task
Refactor the dispatcher to use the new executor interface
## Blast Radius Warning- Severity: **CRITICAL** — 72 files affected
- Seed files: src/kernel/dispatch.ts
- One or more seeds are in the top 20 most-imported files (architectural hub)
- Treat this as CROSS_CUTTING: review carefully before merging
## Project Context (auto-generated)
...

Test plan

  • Bash syntax validated via bash -n on both taskrunner.sh and plugin/taskrunner.sh
  • compute_blast_radius verified across low / medium / high / critical scenarios
  • render_blast_warning verified for low (empty) and critical (full section) cases
  • No-op path verified (no files in prompt)
  • Charter CLI 0.10.0 with blast command on PATH confirmed working
  • Gate logic (authority=auto_safe + critical) simulated in isolation

Related

🤖 Generated with Claude Code

stackbilt-adminand others added 2 commits April 9, 2026 07:39
Adds an autonomous-safety gate to the taskrunner that refuses to execute
auto_safe tasks targeting architectural hubs.
How it works:
1. compute_blast_radius() — new helper that extracts file paths from
the task prompt via regex, filters to ones that exist in the target
repo, and runs `charter blast <files> --format json` with a
configurable timeout. Summarizes to {seeds, affected, severity,
hot_file, top_hot_files} with a 4-level severity ladder:
low 0-4 affected
medium 5-19 affected
high 20-49 affected
critical 50+ affected
2. Execution gate — right before mission brief assembly, check the
severity. If critical + auto_safe, log, mark the task failed with
TASK_BLOCKED: blast_radius_critical, and return. Claude is never
spawned, no turns burned, no wrong changes committed.
3. render_blast_warning() — for high/critical severities, injects a
## Blast Radius Warning section into the mission brief so the agent
knows the scope it's operating in. For low/medium severities the
section is empty.
Environment knobs:
CC_DISABLE_BLAST=1 — opt out entirely
CC_BLAST_WARN=<n> — high threshold (default: 20)
CC_BLAST_BLOCK=<n> — critical threshold (default: 50)
CC_BLAST_TIMEOUT=<sec> — charter blast timeout (default: 60)
Graceful degradation:
- Charter not installed → no-op, task runs as before
- No file paths in prompt → no-op
- charter blast fails/timeout → no-op, task runs as before
- authority != auto_safe → warning injected but task runs
Seed count is capped at 10 to prevent runaway prompts from exploding
the blast call.
Applied symmetrically to taskrunner.sh and plugin/taskrunner.sh.
Depends on @stackbilt/cli >= 0.10.0 (for `charter blast`).
Validated against a real 263-file TypeScript Worker codebase:
version.ts (leaf) → 5 affected, medium, no gate
chat-session.ts (isolated) → 1 affected, low, no gate
dispatch.ts (orchestrator) → 72 affected, CRITICAL, gate fires
types.ts (central types) → 127 affected, CRITICAL, gate fires
Closes#20.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a new "Charter Integration (optional)" section documenting both:
- Project fingerprint via `charter surface` (shipped in 1.4.0, never docs'd)
- Blast radius preflight gate via `charter blast` (this PR)
Also adds the corresponding env vars to the Environment Variables table:
- CC_DISABLE_FINGERPRINT, CC_FINGERPRINT_TIMEOUT (from 1.4.0/1.4.1)
- CC_DISABLE_BLAST, CC_BLAST_WARN, CC_BLAST_BLOCK, CC_BLAST_TIMEOUT (this PR)
Includes:
- Severity ladder table (low/medium/high/critical)
- Gate firing behavior + how operators unblock tasks
- Sample mission brief warning section
- Pointer to the charter CLI install command
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@stackbilt-admin
stackbilt-adminforce-pushed the feat/blast-radius-preflight branch from 7eed3f8 to 04dbff2CompareApril 9, 2026 12:39
@stackbilt-admin
stackbilt-admin merged commit e05658a into mainApr 9, 2026
@stackbilt-admin
stackbilt-admin deleted the feat/blast-radius-preflight branch April 9, 2026 12:40
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: blast radius preflight gate via charter blast

1 participant

@stackbilt-admin