Skip to the content.

Security visual — the capability floor: allow the useful, deny the dangerous

One picture of the trust boundary. Every tool call a model proposes is adjudicated before it runs. The floor allows the everyday tool set so the agent is useful, and refuses destructive calls by argument valueBash is allowed, but Bash{command:"rm -rf /"} is denied before the shell ever sees it. This is the deployable, file-authored form of fak’s “permissions as the floor” thesis, shown on the real Claude Code dogfood (fak/examples/dogfood-claude-policy.json).

Companion to fak/POLICY.md (the manifest schema + author/validate workflow); the why this layer, not a content guardrail argument is in COMPARE-security-model-vs-guardrails, a private companion — not published in this repo (it lives in the paired fak-private research tree). Generated 2026-06-18.


The visual — where the deny happens

   model proposes a tool call                         the kernel adjudicates              effect
   (untrusted, ring-3)                                 (BEFORE dispatch)                   (ALLOW and DENY)
 ┌──────────────────────────┐      tool_use      ┌──────────────────────────────┐
 │  "run: rm -rf /tmp/x"     │ ─────────────────▶ │  Deny[tool]?            ──┐    │
 │  "run: ls -la"            │                    │  self-modify glob?       │    │
 │  "Edit .git/config"       │                    │  arg-value predicate?    ├──▶ │  ALLOW ─▶ run the tool
 └──────────────────────────┘                    │  allow-list / prefix?    │    │  DENY  ─▶ refused, with a
            ▲                                     │  else DEFAULT_DENY     ──┘    │            closed-vocab reason
            │  refusal + reason (POLICY_BLOCK / SELF_MODIFY / DEFAULT_DENY)       │            (never reaches shell)
            └─────────────────────────────────────────────────────────────────┘

“ring-3” in the visual. ring-3 is the least-privileged CPU protection ring (ordinary userspace, as opposed to ring-0 kernel mode). The visual casts the model as that unprivileged userspace and the harness as the kernel adjudicating every syscall (tool call) from evidence the model did not author. The ring-3 inversion in fuller form — model as untrusted ring-3 userspace, harness as kernel — is in docs/notes/EXPLAINER-trust-floor-two-lenses-2026-06-17.md.

The deny is structural, not a model judgement: an injection that talks the model into proposing rm -rf changes nothing — the call is refused at the boundary. The refused call never reaches the shell, the filesystem, or the network.

The chart — what the default dogfood floor allows vs denies

Proposed call Verdict Reason Why
Bash ls -la, cat, grep, git commit ALLOW everyday dev work
Read / Edit / Write a normal file ALLOW the agent has to do its job
Bash rm -rf … / rm -f … DENY POLICY_BLOCK destructive removal — denied by argument value
Bash sudo … DENY POLICY_BLOCK privilege escalation
Bash git push … DENY POLICY_BLOCK the agent can commit, but not publish
Bash curl … \| sh DENY POLICY_BLOCK remote-code-execution pipe
Bash :(){ :\|:& };: DENY POLICY_BLOCK fork bomb
Bash dd if=… of=/dev/sd… / mkfs … DENY POLICY_BLOCK disk wipe
Edit/Write into .git/, .ssh/, internal/kernel/, VERSION DENY SELF_MODIFY can’t rewrite the kernel or secrets
any tool the floor never named DENY DEFAULT_DENY fail-closed — nothing is allowed by default

The load-bearing idea: the deny is on the argument, not just the tool name. A coarse tool like Bash is one allow-listed capability, but its command value is gated by arg_rules (RE2 deny-patterns), so the floor distinguishes ls from rm -rf without forking the kernel.

Prove any verdict without launching a session

# one call, adjudicated against the shipped floor:
fak preflight --tool Bash --args '{"command":"rm -rf /tmp/x"}' \
  --policy fak/examples/dogfood-claude-policy.json
#   => verdict=DENY reason=POLICY_BLOCK by=monitor

fak preflight --tool Bash --args '{"command":"ls -la"}' \
  --policy fak/examples/dogfood-claude-policy.json
#   => verdict=ALLOW reason=NONE by=monitor

# eyeball the entire floor (allow-list, arg rules, self-modify globs, redactions):
fak policy --check fak/examples/dogfood-claude-policy.json

The same matrix is locked as a regression test (fak/internal/adjudicator/dogfood_manifest_test.go::TestDogfoodManifestVerdictMatrix), so a manifest edit that silently widens the floor fails CI.

How to use / change it