Two audits waiting on your yes

The Fable 5.1 migration ran two audits that each end in a set of changes only you can approve, because every one of them touches a control or an always-loaded rule. The first is the hook fleet: the 204 small programs that run before and after nearly every action Jarvis takes. The second is the always-loaded rules: the text every session reads before it does anything. Each audit is summarised here as a short list of decisions, with the numbers behind them and my recommendation. Neither has been changed yet, apart from the four hook fixes you approved on 2 September, which are marked.

How to read this in twenty seconds.

1. The hook fleet: 204 hooks, and what they cost per action

Measured over 24 days (9 August to 1 September): 7.9 million hook runs, of which 103,000 did something and 5,900 blocked. Eighty-four hooks never fired once. The cost is paid on every action:

Every time Jarvis…Hooks that runTime they add
runs a shell command395.3 seconds
writes or edits a file407.5 to 8.3 seconds
starts a session173.6 seconds
reads a file or searches the web7 to 90.3 to 0.5 seconds

Nearly all of that is start-up time: a typical hook takes about 0.3 seconds just to load, before it looks at anything. Bash is 86% of all actions, so its row dominates.

The decisions

ChangeWhat it buysWhat it risksStatus
Fix the arrow false positive, the purchase stop's registration, and the name guard's two false positivesThree live irritants gone; the purchase stop actually runsNone left; all testedDone 2 Sep
"Fix the four hooks that error on every run"The audit read the log wrong: errors equalled FIRES, on one day, on an older version of one hook. Nothing is dead.Nothing to doRefuted 2 Sep
Retire 11 dead rows: six are test-harness names that were never hooks, two are hooks already deleted or folded into another, one belongs to a different project and is only counted here by accident, one maintained a file field that was retired in August, one is a checklist reminder that fired 0 times in 4,017 runs53,700 fewer hook runs per 24 days for zero lost enforcement; "never fired" starts meaning something again in the reportsStructural, not judgement: each one has no file, no registration, or is already goneRecommend
Shrink 3 guards to Claude Code's native deny list: the file-read guard (the one widened on 2 Sep), the npx-install blocker, and the Drive-create guard that duplicates a deny entry already in the settingsSame protection, enforced by Claude Code itself rather than a script that has to load each time; deterministic and model-independentLow: the native rule is checked before any script runs. Do the read-guard last, since it was just widened and its tests are freshRecommend
Merge cluster I: 13 shell-command pattern checks into one programAbout 1.4 seconds off every shell command; 1.9 million fewer runs per 24 days. The single biggest leverA bug in the merged program silences 13 checks at once. Mitigation: every merged hook's tests move under the new program and must stay green before it replaces themRecommend, first
Merge cluster D: 12 session-start checks into one banner programAbout 1.9 seconds off every session start; 99,000 fewer runsSame shape, lower stakes: these print reminders, they do not blockRecommend, second
Merge clusters A, G and B: 7 company-file guards, 6 content scanners, 7 after-write nudges, each cluster into one programAbout 3.1 seconds (42%) off every file write or edit; 243,000 fewer runsCluster A guards company records, so its tests matter most; G and B are scanners and nudgesRecommend, in that order

If all of it ships: about 3.1 seconds off every file write, 1.4 off every shell command, 1.9 off every session start, and 711,000 fewer hook runs every 24 days. Each merge is one commit with its own test run, so a problem is one revert away and never takes the others with it.

One correction to the report's own numbers, made by the report itself: of 6,279 "protected path" blocks in the log, 5,751 came from the guard's own test battery, not from real sessions. Real friction from that guard was 494 blocks, not 7,121.

2. The always-loaded rules: 21 proposed edits

An audit using Anthropic's own method for a model change read every file a session loads before it starts, and proposed 21 edits. Net effect: 3,335 bytes off the surface (1.5% at high confidence). Its own verdict: "this surface is unusually well maintained, and cruft here is concentrated in one layer rather than spread thin. Length was never the reason for any cut." Four of the 21 no longer apply, because the model-selection section they targeted was rewritten on 1 September when you set the model per domain. The remaining 17 fall into five groups.

GroupWhat changesWhyStatus
Overtaken (4 edits)Version numbers beside model names, the old model-selection argument, and its migration-relative phrasingRewritten on 1 September under your domain decision; nothing left to doOvertaken
Mechanical (3 edits)Delete the unscoped "do not narrate" copy in the global rules (the output style already carries the scoped one, and the global file's own rule says the output style is the only reply-shape authority); refresh the list of expected connectors, which names two that no longer exist and misses eight that do, including the bank; cut the paused playbook command's 257-byte "do not run" notice from every requestAnthropic's guide names "don't narrate" as the one instruction that makes this model under-report; the other two are stale factsRecommend
Claims about the previous model (3 edits)Three rules cite measurements or behaviour of Opus 5 as if they were current: a session-management note, a behavioural claim in the workspace rules, and the five-trial design-palette measurement whose own re-check trigger has firedRe-measure on Fable 5.1 rather than delete: the palette test is five cheap calls; the two prose claims get re-verified against the Fable 5.1 pages and rewritten or dropped on the resultRecommend re-measure
Skill descriptions (6 edits)Six skills carry long lists of trigger phrases or incident stories inside the short description every session loads; the audit moves the stories into the skill body and trims the phrase listsMoving trigger phrases changes when a skill fires, so each one is done with the skill-testing tool and its trigger test, one skill at a time, not as a batchRecommend, via the skill tests
Judgement calls (4 edits)(a) Remove "prepare the draft before the request" from the personality file, the behaviour Anthropic's guide says to suppress on this model (the audit's fix adds a boundary sentence instead, +209 bytes); (b) drop a NON-NEGOTIABLE marker on a rule whose hook fired once in 13,963 runs; (c) trim strategy coaching and restated defaults from the personality fileThese are taste, not fact. My lean: keep (a) but scoped as the audit wrote it; do (b); leave (c), the personality file is yoursYour call

3. The built-in write-protection: proven, one decision open

From the security page: Claude Code's own write-protection was switched on in an isolated test and did exactly what was promised (a write to a denied folder fails at the operating-system level whatever the command looks like; ordinary writes, network calls and permission prompts unchanged). It cannot go live yet because the same protection covers a folder Claude Code reserves for itself, ~/.claude/state, with no way to exempt it, and 45 of Jarvis's scripts keep their working state there. Confirmed twice, verbatim "permission denied".

Sources

Hook fleet: knowledge/projects/migrate-fable-5-1-2026-09-01/hook-declutter.md (a verdict on each of 204 hooks, measured from the hook telemetry log 9 August to 1 September) and agent-reports/06-hook-fleet-declutter.md. Rules: prompt-audit-report.md, prompt-audit.diff (21 hunks; 17 still apply after the 1 September rewrite, checked with a dry-run patch on 2 September) and agent-reports/05-prompt-audit-always-loaded.md. Write-protection: three isolated headless runs on 2 September, $0.62, recorded as KF-0464.