---
version: 0.2.1
date: 2026-06-17
headline: "Hardens the kernel gateway against an adversarial review and adds the turn-tax benchmark — the extra error-code model turn the kernel deletes."
themes: ["gateway-hardening", "turn-tax-benchmark"]
highlights:
  - "Gateway auth: constant-time bearer compare over SHA-256, required `Bearer ` scheme — no timing/length oracle."
  - "Gateway DoS: ReadTimeout/WriteTimeout/IdleTimeout so a slow body or idle keep-alive can't pin a goroutine."
  - "Gateway MCP: protocolVersion negotiation, `jsonrpc:\"2.0\"` validation, per-frame recovery from an oversized stdio frame."
  - "Gateway hygiene: generic upstream errors (no cross-trust-boundary leak); loopback warning classifies by IP value."
  - "Turn-tax benchmark: prices the extra error-code MODEL turn (malformed/duplicate/poison) vs the 1-shot kernel."
---

**TL;DR** — A patch on top of v0.2.0's gateway and benchmark surface. The new `fak serve` gateway went through an adversarial review (security / correctness / direction / wire-compat) and this release folds in the confirmed hardening fixes — none critical, all defense-in-depth on a brand-new inbound network surface. Alongside it, a dedicated **turn-tax** benchmark prices the thing the kernel actually deletes: the extra error-code model turn a naive loop burns on a malformed arg, a duplicate read, or a poisoned result. 4 commits since v0.2.0.

## Gateway hardening — an adversarial review of the new inbound surface

Eleven findings were confirmed by an adversarial review (each verified against the source); the eight worth fixing landed. None were critical or high — they are defense-in-depth on the kernel's first inbound network surface.

- **Auth is constant-time and scheme-strict.** The bearer token is compared with `crypto/subtle` over SHA-256 digests (no timing or length oracle) and the `Bearer ` scheme is now required (no bare-token leniency).
  - *How:* `fak/internal/gateway/http.go` `withAuth`.
- **Slow-loris / idle-socket DoS closed.** The `http.Server` carries `ReadTimeout` / `WriteTimeout` / `IdleTimeout` so a dribbled body or idle keep-alive can no longer pin a goroutine + socket (`MaxBytesReader` caps SIZE, not delivery TIME).
- **MCP is more spec-conformant.** `initialize` negotiates `protocolVersion` against a supported set instead of echoing the client's requested revision; non-`"2.0"` `jsonrpc` is rejected (`-32600`); an oversized stdio frame is rejected per-frame instead of tearing down the session.
  - *How:* `fak/internal/gateway/mcp.go`.
- **No cross-trust-boundary leak.** An upstream model failure returns a generic message to the caller and logs the detail — the planner error embeds upstream response bytes that must not reach a (possibly unauthenticated) downstream client.
- **Honest exposure warning.** The no-auth loopback warning classifies the bind host by IP value (`net.ParseIP` + `IsLoopback`), so `127.0.0.1.evil.com` and the `:port` wildcard are no longer mistaken for loopback.
- **Verdict fidelity.** The wire surfaces `ESCALATE` for ANY non-core held verdict kind, mirroring the kernel's structural deny-as-value hold; the OpenAI error `type` is derived from the status class so a client retries a transient 502 correctly.

## Turn-tax benchmark — the extra error-code model turn, measured

- **`fak turntax`.** A dedicated benchmark that replays a class-labeled trace through the real kernel and prices the extra error-code MODEL turn a SOTA loop fires — a malformed arg, a duplicate read, a poisoned result — against fak's one-shot adjudication, keeping the safety floor on its own axis.
  - *Why:* the static latency bench couldn't price the turn the kernel actually deletes; this measures it per lever.
  - *How:* `fak/internal/turnbench` (`turnbench.go`, `render.go`); the `turntax` verb in `fak/cmd/fak/main.go`; class-labeled traces under `fak/testdata/turntax/` and `fak/experiments/turn-tax/`. Framing tightened (forced vs elision, a consistency guard) per an adversarial review; results in `fak/TURN-TAX-RESULTS.md`.
