fix(runner): report the provider's own words, and stop pinning a model that never existed
Two faults, found in that order, both hidden behind the runner spawn bug
#622 fixed.
The acceptance fixtures substituted `kimi-k2.6` into every `{{model}}`
slot. Fireworks writes that decimal as a `p`, so the id never resolved:
probed live, `kimi-k2.6` returns 404 "Model not found, inaccessible,
and/or not deployed" while `kimi-k2p6` and `kimi-k3` return 200. Never an
auth or seeded-secret fault — the dev tenant reads mode=platform with the
default available, and swapping ONLY the model id turned steer-live from
red to 3 pass / 0 fail against live dev. Both live-dialing fixtures now
share one named constant pinned to `kimi-k3`, the platform default the
control plane already serves.
That took days instead of minutes because the runner discarded every
provider error message. NullClaw narrows each non-rate-limit,
non-context, non-vision fault into one error value but parks the real
text in a side channel and exposes a public accessor; this boundary
called @errorName on the narrowed value and never read it, so a mistyped
model and a rejected credential produced byte-identical output:
runner_crash / ApiError, naming neither the model nor the status.
`engine/failure_detail.zig` carries the provider's words onto the event.
The capture hangs off an errdefer below the run's secret set, so every
error unwinding past it — fleet init, message compose, the model dial,
the final redaction — is reported with the same evidence, with the scrub
set in hand. The error name always leads; logs and the error registry are
keyed on it.
- ApiError
+ ApiError: compatible: status=404 message=Model not found, …
It never swallows and never leaks. The function returns void (an errdefer
cannot propagate), so every outcome leaves a mark: a failed snapshot
records DETAIL_UNAVAILABLE, a line carrying a resolved tenant secret
records DETAIL_WITHHELD — dropped whole, never half-scrubbed (RULE VLT) —
and only "no provider was dialed" leaves it empty. Allocation-free on the
reporting path, because the error being reported may itself be an
allocation failure. Bounded, with a marked UTF-8-safe truncation.
Two more swallows of the same class, found auditing src/runner/: a
credential-response encode failure that vanished (the child's only
symptom was a timed-out read, indistinguishable from a slow mint) and
malformed activity frames dropped silently (a quiet live tail reads
exactly like a quiet fleet). Both now name themselves.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> K
Kishore Kumar committed
b03ca6c5df56bade838346dfbf56f72f301a9420
Parent: 224fa15