fak - Fused Agent Kernel
One binary you put in front of the agent you already run — it keeps your key, puts a default-deny floor under every tool call, and makes long sessions cheaper.
What It Is
fak is one Go binary you put in front of the AI agent you already run: Claude
Code, Codex, Cursor, or any OpenAI / Anthropic / MCP client. You keep your model,
your IDE, and your tools. You point one base URL at fak, and it gives you a handle
on the parts of a real agent loop that get expensive or go wrong:
- Cheaper long sessions. A 100k-token Claude Code conversation re-sends its whole
transcript every turn.
fak sheds the old turns while keeping the provider's
prompt-cache prefix byte-identical, so the discount survives instead of breaking.
- The right model per call. Send an easy read to a cheap model and a write-shaped
call to a careful one, chosen per tool call rather than per whole request.
- Fewer wasted turns. A repeated read served locally, a malformed call repaired in
place, a dead-end branch refused before the agent spends a turn on it.
- A trail you can audit. Every decision is a plain verdict:
ALLOW, DENY,
TRANSFORM, or QUARANTINE. It lands in JSON logs, an optional hash-chained
journal, and Prometheus metrics.
fak in one line: Put fak in front of the agent you already run. It makes long sessions
cheaper, routes each call to the right model, keeps unsafe tool results out of
context, and records every verdict. One binary, no rewrite, no key to start.
The 30-second picture, in numbers — every figure traces to
BENCHMARK-AUTHORITY.md. On a 50-turn × 5-agent run, fak's
reuse does ~4.1× less work than a tuned warm-cache stack (and ~60× less than the
naive re-send loop); reuse of the shared prompt prefix climbs to 6.95× across the
model ladder. (For speedup figures: 45× = Phase-0 batched-decode gate currently failing
at 40.98×; ~60× = headline session wall-time vs naive stateless; ~1.5–4× = realistic gain
vs tuned warm-cache stack.) The guard is cheap where it counts — the kernel's allow/deny decision is
~362 ns in-process per call (measured, Apple M3 Pro), not a network hop, and on the
gated reusable-CUDA-graph path (FAK_CUDA_GRAPH=1) the in-kernel GPU decode holds
~120 tok/s on an RTX 4070 (SmolLM2-135M), at parity with llama.cpp Q8_0.
fak guard also reports live prefill vs decode tok/s on /metrics, so a slow first
request gets an answer instead of a shrug.
Pick your path: wrap the agent you already run in one command
(fak guard), stand up an always-on gateway and point any CLI at
it (fak node), put fak in front of any OpenAI /
Anthropic / MCP endpoint (fak serve),
or — if a hard security floor is why you're here — jump to
For security teams.
It does this by sitting on the tool-call path as a kernel. The model proposes a
call. fak decides whether that call exists, whether its arguments are allowed,
whether the result may enter context, and what gets reused. The same boundary that
saves you tokens is also where a dangerous call gets refused. That is why teams who
need a hard security floor reach for it too (see
For security teams).
agent --> proposed tool call --> fak kernel --> allowed tool / denied call
tool --> raw result --> fak kernel --> admitted context / quarantine
Start Here
No key, no model, no GPU. Pick the line that matches how you got fak.
Installed the binary (curl ... install.sh | sh, see Install)? These run
from the bare binary anywhere — no clone, no Go, no examples/ dir. They use the
built-in default floor:
fak preflight --tool refund_payment --args "{}" # -> DENY (DEFAULT_DENY): unknown tool, fail-closed
fak preflight --tool search_kb --args "{}" # -> ALLOW: a read-shaped name is not blanket-blocked
fak preflight --tool shell_rm_rf --args "{}" # -> DENY (POLICY_BLOCK): refused by structure
fak preflight --tool exfiltrate --args "{}" # -> DENY (SECRET_EXFIL)
fak agent --offline # the injection / destructive-op A/B, fully offline
Cloned the repo (you have the Go source tree + examples/)? Build first, then run the same proof against a
named example floor, where the deny is by argument value: