v2.1.37 — Permission-Mode Awareness
Two responses in one release. bkit stops asking questions nobody is there to
answer, and adapts to a Claude Code default that changed underneath it.
What changes for you
If you run --dangerously-skip-permissions, dontAsk, or acceptEdits,
bkit stops interrupting you.
| You run with | Before | After |
|---|---|---|
--dangerously-skip-permissions |
bkit still asked before scoped deletes, hard resets, pushes to main |
it does not ask |
--permission-mode dontAsk (CI) |
the same asks became silent refusals with no recourse | it does not ask |
--permission-mode acceptEdits |
asked | it does not ask |
| default / plan mode | asked | unchanged — still asks |
| any mode at all | rm -rf /, force push, curl … | sh, DROP TABLE refused |
unchanged — still refused |
Claude Code sends permission_mode on every hook event. bkit read it in zero
places, so a session started with maximum autonomy was interrupted exactly as
often as one that had asked to be. The cost was worse than noise: a PreToolUse
question needs a human answer, and an unattended run has none — so the agent
stalled instead of failing, roughly 15 minutes per incident.
The line is the decision's grade, not the mode. A question can be skipped where
nobody can answer it; a refusal cannot be skipped anywhere — the same line Claude
Code draws by keeping a circuit breaker on rm -rf / in bypass mode. Measured
across 7 modes × 21 commands: benign commands stopped 14 → 0, all 49
negative controls intact.
Three commands that used to interrupt you and no longer do:
grep -rn delete src/ a b c d e # read-only — the rule matched the WORD "delete"
npm remove lodash react vue axios dayjs # a package manager, not a file deletion
npm install --force # only during the phase-9 deployment skill
If you are on Claude Code v2.1.232 or later, bkit tells you what changed and
what it means.
v2.1.232 turns fork mode on by default in interactive sessions. A subagent's
result now arrives as a notification on a later turn, and the Agent tool no
longer accepts run_in_background, so the foreground cannot be requested.
- Your skills are unaffected. The
background: falsebkit added in v2.1.31
still holds — confirmed in the binary, not inferred. - A sprint gate that measures through a subagent reports "not measured" rather
than a score, and names fork mode as the likely cause. A missing number, never
a wrong one. - Set
CLAUDE_CODE_FORK_SUBAGENT=0to get in-turn results back.
bkit surfaces this once at SessionStart and never blocks on it.
Three git commands that destroy work are now guarded, taking the rule set to
19: git clean -f* (deletes untracked files with no reflog entry to recover
from), the three spellings that discard uncommitted work (checkout -f,
restore against the worktree, switch --discard-changes), and expiring the
reflog with an immediate prune. --amend and --no-verify are deliberately not
guarded — an amended commit survives in the reflog, and publishing the rewrite
needs a force push, which was already refused.
Your .env file is guarded on the Bash surface for the first time, and your
JavaScript is not. The rule meant to notice .env had never matched it: \b
cannot express "start of a filename" when the filename starts with a dot. It had
been matching process.env.NODE_ENV instead, so editing any file that reads
configuration prompted for confirmation. Both directions are fixed and asserted.
Compatibility
Breaking changes: 0. The hook contract is byte-identical across Claude Code
v2.1.228, v2.1.229, v2.1.231 and v2.1.232 — 10 markers measured on all four
binaries. Consecutive compatible releases: 171.
Recommended runtime stays v2.1.220. Install floor v2.1.143, runtime floor
v2.1.78, model floor v2.1.170 for the Fable-pinned agents.
Withdrawn
"PostToolUse continueOnBlock" was not unimplemented. It was unimplementable.
continueOnBlock is a configuration field on a prompt-type hook definition,
confirmed at three places in the v2.1.232 binary. All 28 bkit hook handlers are
"type": "command", so no bkit hook can carry the field at all.
It had been advertised on four surfaces, including the marketplace description
you read before installing. bkit now claims five differentiations rather than six.
The test that let it survive three releases mattered more than the claim: it
asserted that a string appeared in a markdown file — which is true of a claim
nobody implemented, true of a claim nobody can implement, and true of a claim
that is simply wrong. A regex over source text does not verify a feature. Its
replacement checks that every hook handler is still command-type, so if that ever
stops being true the claim gets re-examined on evidence instead of shipping again.
Quality
- Suite: 5,272 / 5,277 pass, 0 fail, 5 skipped across 382 files
- Live QA on a real Claude Code v2.1.232 session: 145 / 145, 0 fail — 44 skills,
34 agents, 21 hook events, 19 MCP tools, plus a new fork-mode layer that
proves the gate is live before asserting anything under it - CI gates 22 / 22
- Every new regression suite was verified failing against the pre-fix tree
What this QA did not cover is written down in the report rather than left
implied: binary measurement is macOS x86_64 only, fork mode was reached through
CLAUDE_CODE_FORK_SUBAGENT=1 rather than a genuinely interactive session, and
the stdout visibility of eight hook events was taken from Claude Code's
documentation rather than probed live.
Also fixed
- A regression guard that had never fired once since v2.1.10, because it read a
payload field Claude Code has never sent - Two guards declared
removeWhen(ccVersion)and nothing called it — on v2.1.231
they were still watching for regressions fixed 113 releases earlier git reset --hardwas auto-denied by one bkit surface and merely confirmed by
another; searching for a dangerous string was graded as performing one- Sprint iterate no longer burns up to five auto-fix cycles against a gap list
whose only entry was "no JSON in output" - Three agents now preload the five skills they declared — the field was
skills_preload, which appears nowhere in Claude Code's documentation, and 23
such declarations across six keys were removed or moved to a field that works - Hook messages composed for the model now reach it on the nine events that have
a context channel, instead of being written to a log - 148 test files ran nowhere — neither the local runner nor CI referenced
them. All are now registered scripts/cc-binary-equivalence.js— the binary measurement three analysis
cycles had rebuilt by hand, with each erratum recorded beside the line that
enforces it
Full detail: CHANGELOG.md ·
CC v2.1.228–v2.1.232 impact analysis ·
QA report