Skip to main content

Module surface

Module surface 

Source
Expand description

The tool surface a run was sent, kept once and cited by hash.

§The gap this closes

RunConfig records the system prompt in full, and says why: “the text lets a replay rebuild the request.” It records the tool surface as names, with a doc comment naming the risk it saw — “a tool added, removed or renamed between recording and replay changes what the model could have done.”

Add, remove and rename are the three that never happen. Re-describe is the one that happens constantly — 49 commits touched tool definitions in three weeks of this store — and it is invisible to a list of names. Render order is tools → system → messages, so a replay was rebuilding the second half of the prefix byte-exactly and the first half from whatever the registry says today. Every description edit since a recording silently changes the bytes the model sees before anything else.

Measured: 12 of 13 counterfactual probes came back inconclusive, on a pinned seed and a quiet box, deterministically across repeats — median divergence one tool call in. Six probes in one session, with steer points from 10 to 33, all gave up at the same call: a trajectory-dependent cause cannot do that, and a per-session constant can.

§Why a hash and a store rather than the specs inline

Costed rather than preferred: the specs are 69 KB against a 25 KB average session file, so inlining would quadruple the session store and put, in most sessions, more bytes of tool description than conversation. A hash alone is cheap and gives up the rebuild, which is the point of recording it.

So the specs are written once per distinct surface and cited by hash — the precedent is ValidationRecord’s rules_hash, “keyed to the exact rule set measured, because a tally that mixes generations measures nothing.” Surfaces change tens of times over a corpus, not once per session, so the store dedupes to a few megabytes where inlining would cost tens.

§Three states, and the one that matters is Unknown

A names-only recording must never read as matching. Every session written before this field exists — all of them, on the day it lands — is Fidelity::Unknown, and a probe over one is inconclusive for a named reason instead of mysteriously. That is the whole reason this is Option<String> and not String: absent is not equal, the rule crate::homeostat and crate::backlog both state at length.

Fidelity::Differs needs no blob at all — comparing today’s hash against the recorded one answers it — so legibility arrives the day the field ships and rebuildability accumulates afterwards. That ordering is worth more than either half alone: it turns an inconclusive probe from a mystery into a labelled cause immediately.

§What it does not do

It does not recover the existing corpus. Nothing can: those recordings never held the specs, and the descriptions they were sent are only in git history that cannot be matched to a session. The appraisal corpus and the validation ledger start from zero the day this ships, and anyone budgeting on the sessions already on disk should read that first.

Nothing here is ever deleted, for the same reason a published bundle is not: a surface blob is what makes an old session replayable, and a retention policy over it would quietly cost the recordings it was keeping.

Structs§

SurfaceStore
Where surface blobs live. One file per distinct surface, named by its hash.

Enums§

Fidelity
How faithfully a replay can reproduce what a recording was sent.

Functions§

fingerprint
A stable identity for one tool surface.