YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
The Reset Certificate
Was that episode a fresh trial β or was it still wearing the last one?
Every benchmark number rests on a reset. If state carries over, the next measurement is partly a memory of the last β and a policy can look steadier, calmer, and safer than it is.
This instrument settles that by measurement. It walks the rig itself, discovers every home of state, runs an episode, resets the way your harness resets, and names whatever the reset failed to restore. What it cannot read, it prints. What it cannot measure, it says so beside the verdict.
That matters where decisions follow the numbers: a lab deciding a policy is ready, a facility trusting a robot beside residents, an insurer asking which exact policy ran and whether its evaluation was clean, a buyer checking that a used robot truly arrived in its factory settings.
One reset, a sequence, or a whole fleet β each judged against its own fresh reference, each with its own verdict, limits on its face.
A certificate does not ask to be believed. It asks to be re-run.
Files
- cert.py β the verifier core (snapshot, anchor, diff, echo classification, verdict classes, and the sequence judge). Harness-agnostic.
- ADAPTER.md β how to point the instrument at your own harness: the environments the two paths need, the twelve-member Rig interface, and the anchor wiring.
- mdk.py β the Microduck adapter + CLI (worker / run).
- stub.py β a second, stateful policy shape used as a test rig.
- jstub.py β the jittered stub: the same shape with non-determinism injected into its stepping (the STATE-CLEAN live attempt).
- tests.py β the instrument's own tests:
python3 tests.py. - LICENSE β MIT, the package's own licence.
- requirements.txt β the verified environments, transcribed from ADAPTER.md.
- plant/ β scratch copy of the BAM package carrying one planted third write (the falsifier). Never a shipped tree.
- plant_fuse/ β scratch copy of the BAM package carrying the horizon fuse: a counter no reset restores, arming a write only from the second reset onward. Never a shipped tree.
- proof/ β every leg's saved output.
Run it
Against any microduck_rl checkout (the anchor build runs as a separate process on its own):
python3 mdk.py run --tree <checkout> --reset <mode> \
--seed 7 --declare-commands
Reset modes: naive (mj_resetData alone), full (the patched contract: reset_episode + reset_action_history), eponly, nonestate, noclock. Add --plant
Against a fleet β many devices judged in one run:
python3 cert.py fleet --devices 12
certify_fleet judges each device independently against
its own fresh reference, in the one run: every device earns
its own full verdict with its leaks named, a device whose
build raises is recorded ERROR while the fleet judges the
rest, and the run closes with a fleet summary β the device
count, the verdict counts, and the wall time of the whole
run. The sequence judge is available per device as an
option. A fleet verdict is exactly the per-device verdicts
and nothing more: no device inherits another's result, and
the summary claims no horizon wider than each device's own
printed profile.
Against the stub's second policy shape:
python3 stub.py run --variant clean|leaky
Against the jittered stub (the STATE-CLEAN attempt β genuine non-determinism in the stepping, so the verdict rests on the measured final-state deviation):
python3 jstub.py run --jitter J (J=0 is the control)
Verdict classes
- BIT-IDENTICAL β discovery diff empty, and a 750-step dynamically excited trace matches a fresh rig bit for bit.
- STATE-CLEAN β diff empty, trace hash differs but the final state lands within the stated tolerance (1e-6) of fresh, deviation measured and printed. The tolerance is measured on the final state, not along the trace path.
- STATE-ONLY β diff empty, no trace leg ran. Weaker; says so.
- FAIL β differing fields named, each classified leak or echo (an echo clears when the true write-set is restored).
Differing fields the judged episode provably did not read β the
trace matched fresh bit for bit with them standing (diagnostics,
high-water marks, visual state) β are printed as INERT on the
certificate: named, with the operational evidence, never silently
dropped and never counted as leaks. When the trace diverges,
attribution is impossible and every differing field stays a leak.
The discovery walk covers array and scalar attributes β
an owner's own and its class's alike β and descends into
struct sub-objects two levels; struct lists (contacts, solver,
timers) and anything deeper are printed as opaque handles. Methods
are not state and are the walk's one stated exclusion. Episode
seeds are parameters (--ep-seeds on the CLI), not constants.
- REFUSED-AT-ANCHOR β two independent builds disagree at episode start; the differing fields are named and no reset is judged. Construction-time RNG draws land here.
No class is ever upgraded silently. A snapshot is provenance-stamped (model hash, harness, step count, sim time) and refused once the rig has stepped; certifying without one is an error, never a default. Per-episode state the design intends to vary is DECLARED with its sampler and reported as declared β undeclared differences are leaks by definition.
Every certificate also prints beside its verdict: the judged profile (episodes Γ steps Γ episode seeds β the horizon the verdict actually covers); the part of the final state its deviation cannot measure (fields captured as tokens only β RNG stream states, byte strings, object arrays β whose final tokens differ are printed as not measurable by count and name, never silently scored as zero deviation; the deviation itself is measured over the union of the two final states, so a field that exists on one side only is priced β as an unbounded deviation, when its value was captured, and named beside the deviation β or named with the token-only fields, never invisible; a difference the arithmetic cannot order β a NaN on either side, infinity met by infinity, or an exact magnitude no float can carry β is likewise never scored as zero: its field is printed as not measurable in full, the elements of it the arithmetic can order are priced and printed beside the name, and the deviation prices as unbounded; integer differences are measured in exact arithmetic wider than the field's own dtype, so none wraps or is erased, and a field whose two sides disagree in kind β integer against float β is priced element for element in exact rational arithmetic, the integer side never converted into the float dtype, so none is erased at the seam between kinds either; complex differences are measured by the exact modulus of the difference β the squared modulus is an exact rational, zero only when the two values are equal, and only the worst element's modulus is converted β so a difference carried purely in phase prices at its true modulus, never at zero; the exact measurements walk a field's elements in turn (measured on the house rigs: integer roughly 0.2β1.6 microseconds per element, mixed roughly 6β17, complex roughly 22β35; linear in the field's size), and all of these names print whether or not the traced episode diverged); on rigs whose walk records opaque handles, the limit of the naming promise (those contents are identity-checked only; a write inside one cannot be named, only detected as a verdict change where the judged horizon reaches its effect β the limit is evaluated over the snapshot, the post-reset state, and the final state, so a handle an episode itself creates is disclosed in the run that judged it); and, on a FAIL that names no field, a line saying the measured divergence is carried outside the walked state β an unnamed FAIL is a reachable output, and the certificate explains it in the same breath as the verdict instead of leaving it bare. That line stands down when the deviation has already named a field that carries the divergence (a one-sided field priced unbounded, or a difference the arithmetic cannot order); a token-only naming does not stand it down.
Standing practice β the words are re-derived with the code
Every instrument change ships, in the same pass, with a re-derivation of the words that describe it: CONTRACT.md and the staged follow-up post are re-read against the new outputs, clause by clause and claim by claim, and corrected where the change moved what they may say. The code has a regression battery (tests.py, re-run after every change); the words have this step. Twice in a row β rounds 2 and 3 β the standard's page and its staged send were found one change behind the instrument, because each was verified against the code as it stood when its own lane read it and a parallel change invalidated the check in silence. A round is not closed while the words trail the code.