Skip to content

Records and Replay ​

Current responsibility: persist run manifests, ordered lifecycle events, sealed artifacts, mutable user annotations, and zip exports. The first version supports integrity checks, torn-tail recovery, SSE event waiting, and export of sealed records. Run metadata queries are served by verification and reused by the Records tab. Export is this module's own route and must not be conflated with the query endpoint. See the parent scope, repository rules, and the development task guide.

Change Guide ​

GoalEdit hereConditional / reused path
Change provenance/hash displayRecordsView.tsxReuse verification's run query. Do not add a second metadata endpoint.
Change sealing, integrity or recoverystore.py and relevant verification/fuzzing testsWriter services only if the store contract changes.
Change zip contentsRecordStore.export_zip in store.py, export coverage testsroutes.py for HTTP headers/errors only; api.ts or view only if URL/download interaction changes.
Add a scientific artifactProducing worker/bridge plus verification artifact write pathExisting generic RecordStore may need no change. analysis is a reader, not the layers.json writer.
Change saved counterexample annotationsfuzzing service/schema/viewRecordStore annotation methods are reused unless persistence guarantees change. Annotations are not part of the artifact seal.
Add persisted command receiptsstore.py annotation allowlist and the owning serviceFuzzing writes fuzz_control_requests.json for per-run request-ID deduplication; receipts are included in export and never replayed as commands.

Run metadata belongs to verification's schema/query; an added metadata field requires its owning schema change and npm run gen:types. Import and scientific snapshot replay remain planned, not available export features.

Flow Diagram ​

The query, artifact producer and export routes have different owners. Arrows are labeled with the transferred data or operation.

BlockCode and contractNeighbor handoff
Run metadatahooks.ts reuses the run query and RecordsView.tsx renders RunOutverification
Artifact producerverification/service.py writes worker results, layers and fuzzing artifacts and seals themRun lifecycle
Annotation writerfuzzing/service.py saves user annotations through RecordStoreSaving counterexamples
Artifact readersanalysis/service.py reads layers; fuzzing reads fuzzing data and annotationsanalysis, fuzzing
Exportapi.ts supplies exportUrl; routes.py checks existence/seal and calls store.py export_zipDownloaded zip; no second metadata API

Validation ​

Run the existing record and fuzzing coverage:

bash
.venv/bin/python -m pytest visual_bench/verification/test_verification.py
.venv/bin/python -m pytest visual_bench/fuzzing/test_fuzzing.py
.venv/bin/python -m pytest visual_bench/fuzzing/test_control.py
npm test

Observable behavior: the Records tab shows verification's selected run metadata, the export button requests the records route, incomplete runs report that export requires a sealed record, and the downloaded zip contains only relative run paths plus sealed artifacts, events, hashes, and available annotations. These are validation instructions, not a new test result.

REC-05 acceptance on 2026-11-06: the full default suite included 19 passing fake-provider fuzz control tests, including persisted receipt lookup after completion with no repeated command. Full-suite commands/counts are recorded in execution validation.

Reference and Backlog ​

Current files and routes

Current Files and Routes ​

FileResponsibility
store.pyRecordStore: per-run directories, atomic writes, ordered events.jsonl, sealed artifact hashes, mutable annotations, event waiting, and zip export.
propagation.pyPropagationWriter: full propagation index, deduplicated float32 blobs, atomic live publication, and progress coalescing at 10 notifications/s plus the final flush.
bab.pyBabWriter: append-only BaB tree log (bab.jsonl), each line flushed before its notification; notifications coalesced to 2/s plus the terminal; a closing end line. RecordStore.bab_log reads complete lines from a byte offset.
../analysis/test_propagation.pySynthetic storage/index/API tests: deduplication, throttling without history loss, seal/blob corruption, export and explicit size limits.
routes.pyGET /api/runs/{run_id}/export, owned by records. Returns a zip only for a sealed run.
api.tsExport URL helper. Run metadata query is imported from verification's client path.
hooks.tsRun record query shared with verification and the export action.
RecordsView.tsxProvenance, hashes, status, native reference, and export button.
../verification/test_verification.pyRecord integrity, recovery, and lifecycle coverage.
../fuzzing/test_fuzzing.pyFuzzing artifacts and saved annotation export coverage.

Record layout under var/records/<run_id>/:

text
manifest.json                 immutable request and provenance
events.jsonl                  ordered lifecycle events
result.json                   final ACT result
layers.json                   recorded interval layer states
propagation.json              full observation index, live atomic snapshots then sealed on completion
bab.jsonl                     BaB runs: one line per committed ACT wave, the terminal and an end line; sealed on completion
blobs/<sha256>.f32             propagation tensor envelopes, deduplicated within this run and sealed
fuzzing.json                  fuzzing result when applicable
artifacts.json                sha256 seal for available artifacts
saved_counterexamples.json    mutable user annotation, included in export
fuzz_control_requests.json    queued command receipts keyed by request_id, included in export
diagnostics.json              worker warnings/logs/error location and engine snapshot (verification VER-12)
act_stdout.log                scrubbed tail of the worker's stdout (ACT's prints)
worker_stderr.log             scrubbed tail of the worker's stderr

Diagnostics files are written once when a run ends, for failed runs too, so they are not sealed; write_diagnostic accepts only these names. The export zip includes them; the reproduction snapshot is verification's GET /api/runs/{id}/snapshot, not this module's export.

Propagation is scientific evidence and joins the artifact seal. A blob contains canonical compact JSON {"dtype":"float32","shape":[...]}, a newline, and full little-endian float32 bytes; SHA256 covers the metadata and bytes together. Identical bytes with different shapes are different tensors. The filename is that digest; live reads verify it, and completed reads additionally require its artifacts.json entry. The worker writes blobs before atomically publishing the index, then notifies the supervisor. Progress can be coalesced; propagation.json retains every record. A failed/interrupted run may retain an explicitly partial, unsealed index (complete: false); this is accessible for inspection but never exported as a sealed completed result. The final index and all tensor blobs are included in export and reproduction snapshots. The legacy layer detail limit does not limit recording.

Focused storage and API check: .venv/bin/python -m pytest visual_bench/analysis/test_propagation.py.

Task acceptance, rationale, and planned capabilities

Tasks and Acceptance ​

IDDeliverableDepends onCompletion evidence
REC-01Persist immutable run metadata and final resultBASE-03Save/read a manifest and artifact for the native ACT run recorded in BASE-03 with identical hashes; no private absolute paths are required in a bundle.
REC-02Persist commit batches and snapshot boundariesREC-01, EVT-02A simulated interrupted write recovers the last committed prefix; incomplete references are never visible.
REC-03Implement replay, coverage, and resync readsREC-02Snapshot S plus following events reproduces recorded state; missing/expired history is explicitly represented.
REC-04Export fixed research data and figure configurationREC-03, ANA-02Export/import preserves numerical data, selected coordinates, guarantees, revision, and plot configuration; invalid bundle paths are rejected.
REC-05Persist fuzz control idempotency receiptsREC-01, VER-16The annotation allowlist includes fuzz_control_requests.json; fuzzing/test_control.py verifies that a duplicate after completion returns the original receipt without another pipe write. Receipt semantics remain fuzzing-owned.
REC-06Store the BaB tree logREC-01, EVT-02bab.jsonl: one JSON line per committed ACT wave or terminal record, flushed by the worker before its notification; readers return complete lines from a byte offset and leave a torn final line; the completed log is sealed and exported with the record. Tree meaning stays bab-owned.

Current status: REC-01 is implemented. REC-02 and REC-03 are partial through lifecycle events, recovery, and replay. REC-04 has sealed export only, not import. User annotations are written atomically, are not hashed into artifacts.json, and are included in exports.

Keep the first store local and small. Publish artifacts atomically, then write the seal. Event replay reconstructs recorded display state, never solver memory, and never executes imported commands. Missing history is not zero. Orphan artifacts may be cleaned only after committed references are checked.

Planned operations are createRunRecord, appendCommit, readSnapshot, readEvents, readArtifact, and exportBundle. Current equivalents live on RecordStore. Planned files such as repository.py, commit_log.py, and bundle.py are intentionally folded into store.py until later tasks require extraction.

Owner: B, with D and C integrating figure and data export. On completion, record exact commands and results, provenance, and limitations.