feat(trace): tape format versioning — version-stamped tapes, refuse-on-mismatch (#411)#453
Merged
Merged
Conversation
…n-mismatch (#411) The tape is becoming a persisted artifact (--trace-on-fail CI archives, attached-tape bundles #413, the eigsdap stepper #418, the EigenOS M11 journal), so it now names its own provenance. Decision recorded in docs/TRACE.md: version-and-reject, never migrate — no compat promise, matching the no-backcompat policy everywhere else. - Every tape opens with 'V <format> <runtime>' (TRACE_FORMAT_VERSION=1 + EIGENSCRIPT_VERSION), emitted by both the hosted EIGS_TRACE fopen path and the embed sink install; a journal appended across sink sessions carries one header per session. - Replay refuses on missing/malformed header, format mismatch, or runtime-version mismatch: hosted EIGS_REPLAY _exit(3)s at startup (never falls back to a live run — that's the silent divergence the header exists to prevent); eigs_set_replay_tape returns 0 without installing; a mismatched mid-stream header aborts the take loop. - No override flag: the tape is text, editing line 1 is the deliberate override. Residual gap documented: dev builds share a version string, so equality is necessary-not-sufficient. - tests/test_replay.sh: header-presence check, both-tier untampered control, and four planted-fault refusal cases (format, runtime, headerless, empty), each requiring exit 3 + the documented message. Handcrafted-tape fixtures now derive the real header off a recorded tape so they survive future bumps. Gates: full suite + ASan(detect_leaks=1) 2531/2531 both; embed-smoke OK; liferaft replay byte-identical N=0; tidelog replay byte-identical N=7 (file reads only). Closes #411 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ten findings from the high-effort review of PR #453, all addressed: - Unopenable EIGS_REPLAY is now fatal (_exit(3)), was warn-and-run-live — the most common operator error (typo'd/deleted tape path) was the one silent fallback left standing after the header work. - trace_set_replay_mem now validates EVERY session header of a concatenated journal at install time and swaps atomically: a refused or OOM install leaves the previously active tape, position, strict mode, and enablement untouched (fixes the strict-clobber, the half-armed OOM state, and the destroyed-previous-tape non-atomicity), and a mixed-version journal can no longer _exit(3)/abort() the host mid-eval — refusal always lands at the return-0 seam. - Torn mid-stream V lines ('V', 'V<tab>…') now refuse loudly via the widened take-loop gate + malformed-header message, instead of slipping through the skip-anything-else record filter. - --version/--help are handled before trace_init, so a stale exported EIGS_REPLAY can't fail pure queries with exit 3. - Coverage: embed_smoke gains the refusal contract (headerless refused, mixed-version refused at install, atomic-swap survival); test_replay.sh gains unopenable-path, torn-mid-stream, and stale-env --version cases (17 replay cases total). Gates: full suite + ASan(detect_leaks=1) 2534/2534 both; embed-smoke OK; liferaft replay byte-identical N=0; tidelog replay byte-identical N=7. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The tape is becoming a persisted artifact (
--trace-on-failCI archives, attached-tape bundles #413, the eigsdap stepper #418, the EigenOS M11 journal), so it now names its own provenance.The decision (issue #411, option 1): version-stamped tapes, refuse-on-mismatch. No compatibility promise, ever — version-and-reject, never migrate, consistent with the no-backcompat policy everywhere else.
What changed
V <format> <runtime>(TRACE_FORMAT_VERSION= 1 +EIGENSCRIPT_VERSION), emitted at both tape-open sites: the hostedEIGS_TRACEfopen path and the embed sink install. A journal appended across sink sessions carries one header per session; replay verifies each.EIGS_REPLAYexits with status 3 at startup — it never falls back to a live run, because a plausible-looking live run is exactly the silent divergence the header exists to prevent;eigs_set_replay_tapereturns 0 without installing the tape (embed seam);Vaborts the take loop (strict or not).Verification
tests/test_replay.sh: header-presence check, untampered-tape control replayed JIT on and off, and four planted-fault refusal cases (tampered format, tampered runtime version, headerless, empty file), each required to exit 3 with the documented message. 14/14.detect_leaks=1): 2531/2531 both.make embed-smoke: sink→eigs_set_replay_taperound-trip through the header, OK.liferaft/test/replay.shbyte-identical, N-records=0;tidelog/test/replay.shbyte-identical, N-records=7 (file reads only).EIGS_TRACE/EIGS_REPLAYsurface (its tape mentions are the in-memory temporal history).Closes #411
🤖 Generated with Claude Code