---
version: 0.17.1
date: 2026-06-18
headline: "Dogfood audit fixes: text-form tool calls now hit the kernel, port guard, clearer health."
themes: ["dogfood", "agent", "gateway"]
highlights:
  - "Text `<tool_call>` blocks are lifted into structured calls — no longer bypass adjudication."
  - "Dogfood fails loud on a stale kernel instead of silently attaching to it."
  - "`/healthz` reports `planner: live|mock` — `engine:mock` no longer reads as a mock model."
  - "Warn when the resolved model is ≤~3B (flaky agentic tool use)."
---

**TL;DR** — Auditing the raw `⏺ <tool_call>` we saw in a dogfood session turned up
one real correctness hole (tool calls emitted as text bypassed the kernel) plus
two robustness gaps in the dogfood launcher. All fixed; the kernel plumbing itself
was already correct.

## Text-embedded tool calls hit the kernel again (#agent)

- **What changed** — a model that emits its tool call as a Hermes
  `<tool_call>{…}</tool_call>` *text* block (the weak-local-model failure mode) now
  has it lifted into structured `Message.ToolCalls`.
  - *Why:* the gateway adjudicates only structured calls, so a text-form call
    bypassed the kernel boundary entirely — silently breaking the "every proposed
    call is adjudicated" guarantee, and rendering raw in Claude Code.
  - *How:* `internal/agent/toolcall_fallback.go:LiftTextToolCalls`, applied in
    `HTTPPlanner.Complete`. Conservative — structured calls are never clobbered;
    malformed/nameless blocks are left untouched.

## Dogfood launcher robustness (#dogfood)

- **What changed** — fail loud before launch if the port is already serving, with
  the holder pid and remediation; after launch, assert `/healthz` reports our model.
  - *Why:* the `until curl healthz` probe would otherwise wire Claude Code to a
    stale kernel left on the port by a prior run.
  - *How:* `fak/scripts/dogfood-claude.sh` pre-flight guard + model-identity check.

- **What changed** — warn when the resolved model is ≤~3B, pointing at
  `FAK_DOGFOOD_MODEL=qwen2.5-coder:7b`.

## Clearer health (#gateway)

- **What changed** — `/healthz` now carries `"planner": "live"|"mock"`.
  - *Why:* `{"engine":"mock","model":"qwen2.5:1.5b"}` read as "the model is mock";
    `engine` is the kernel's syscall engine, a separate concern.
  - *How:* `internal/gateway` — `Server.live` from `cfg.BaseURL`, surfaced in
    `handleHealth`.
