Claude Code First, specification version 0.1.0. The plain-language guide
Version 0.1.0. Grade R3/S2.
F402 Permission prompts were treated as a cost to remove, and a hook that refuses named writes stood in for them
| Field | Value |
|---|---|
| Status | active |
| Topic | Environment, permissions, and agent-facing products |
| Grade | R3/S2 |
| Cases | Shio, freewilly, roadkeep, polyweave |
| Contrary | none |
| Harness facts | H4, H6, H7 |
Claim
Where the committed configuration shows a permission posture, it allows most tools by bare name, and the projects changed their tools to stop prompting; the control left in place of a prompt is a PreToolUse hook that refuses writes to named files, not a narrow allow list.
Mechanism
A prompt interrupts an agent that is meant to run a batch of tasks unattended, and a tool reached through a path that changes per version or machine prompts again on every new path. The projects removed both kinds of prompt: broad committed allow lists (H7), and one stable path for the tool they call most. What they kept is narrower: a hook on Edit, Write and Bash (H4) that denies an edit of a governed file with the command to use instead (H6), and never grants anything itself. The guard's design states why it never answers allow: "Silence is the allow." [roadkeep@91754240:src/roadkeep/guarding.py#L24]
Observations
- shio. The committed settings allow nearly every tool by bare name, starting with
"Bash" [shio@821f18d74:.claude/settings.json#L8], across the list at [shio@821f18d74:.claude/settings.json#L7-L50], with empty deny and ask lists [shio@821f18d74:.claude/settings.json#L52-L53] and "acceptEdits" [shio@821f18d74:.claude/settings.json#L54] as the default mode. The engine was vendored to one path on 2026-08-14 [shio@1a541993e] because "every distinct command path is a fresh authorization" [shio@821f18d74:agents.md#L276] prompt. The guard runs through the committed launcher on the three hook events [shio@821f18d74:.claude/settings.json#L61-L94].
- freewilly. The committed settings set "acceptEdits" [freewilly@c1c2eaf:.claude/settings.json#L4]
and allow 42 entries starting with bare Bash and PowerShell [freewilly@c1c2eaf:.claude/settings.json#L5-L48]. The same vendoring landed 13 minutes after Shio's, "vendor the engine into .roadkeep and always run that copy" [freewilly@89371b8], with the reason "Every distinct command path is a fresh authorization prompt" [freewilly@c1c2eaf:install-roadkeep.cmd#L12]. When entries vanished from the allow list (F401), a test was added whose comment says the file is committed "so a clone works rather than prompting on every call" [freewilly@c1c2eaf:tests/FreeWilly.Preflight.Tests/PackagingTests.cs#L276]. The only purpose the pin states for the hook is refusing hand edits of the governed files: "roadkeep denies a hand-edit of ROADMAP, CHANGELOG and IMPROVEMENTS through this" [freewilly@c1c2eaf:tests/FreeWilly.Preflight.Tests/PackagingTests.cs#L311].
- roadkeep. The guard's own prompts were cut back as a defect: "The guard asks about every commit that stages a governed file, though git add and git commit never write it" [roadkeep@91754240:docs/CHANGELOG.md#L1136],
fixed on 2026-09-21 as "stop asking about git staging or reading a governed file (RK1689)" [roadkeep@054faeed]. Its committed settings hold no allow rules [roadkeep@91754240:.claude/settings.json]; the local settings file is not committed, so the posture it runs under is outside the pin.
- polyweave. The committed settings allow every shell command, "Bash(*)" [polyweave@6d1c136:.claude/settings.json#L5],
and register the imported guard and a hook that refuses Write over an existing file [polyweave@6d1c136:.claude/settings.json#L13-L52].
Independence
Two independent origins at least. roadkeep's RK1689 is its own recorded defect. Shio and freewilly count as one: the vendoring commit carries the same subject in both, 13 minutes apart, Shio first, and the two allow lists have the same shape, so freewilly's posture is treated as copied from Shio. polyweave's surface was imported whole on its first day (see F400), so its allow list is not counted as a separate origin, though its form differs.
Counter-evidence
roadkeep also added a prompt on purpose: a shell command naming a governed file is "matched and answered with" [roadkeep@91754240:docs/CHANGELOG.md#L989] ask, because what the command does with the file is the user's call. So a prompt was kept where a refusal could not decide. freewilly's product will not grant permissions in a consumer's configuration: "an allowlist is a permission grant" [freewilly@c1c2eaf:tests/FreeWilly.Preflight.Tests/AgentDiscoveryTests.cs#L15], so the install proposes the line and writes none. winwright commits no allow list at all [winwright@861b82e:.claude/settings.json#L1-L38]; its posture is not observable at the pin. Claims about a local bypassPermissions mode in roadkeep and freewilly rest on uncommitted files and are not evidence. No committed control limits shell commands other than those naming a governed file.
Grade
R3: roadkeep and the Shio-freewilly pair are two independent origins in two projects. S2: the strongest observations are commits that record a prompt as a defect and remove it; the allow lists are configuration, and the test that holds freewilly's list has not been seen to fail.