test(core): persisted-schema round-trip fuzz + reject future checkpoint versions (#31)#49
Merged
Merged
Conversation
…nt versions (#31) Adds core/tests/test_persisted_schema_roundtrip.rs — a dependency-free, seeded round-trip fuzz over the persisted graph (LoopCheckpoint, RunRecord incl. all three 3.3.0 AgentEvent variants, SubagentTaskSnapshot, TraceEvent, VerificationReport, Message/ContentBlock, and the largest root SessionData), asserting serialize→deserialize→re-serialize stability. Plus cross-version coverage: backward-compat (pre-3.3.0 payloads missing schema_version / identity fields / using the `todos` alias load with defaults), forward-compat (unknown fields ignored — guards rolling cluster upgrades against a stray deny_unknown_fields), the untagged ToolResultContentField and the persisted untagged PermissionRule dual-form hazards. Closes a real gap surfaced while writing it: LoopCheckpoint documented that loads from a future schema version must be rejected, but no impl enforced it. Adds LoopCheckpoint::ensure_loadable() and calls it in both the file and memory store load paths, so resume_run surfaces the error and the live-run sink starts fresh rather than misinterpreting an incompatible checkpoint.
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.
Follow-up #31 (persisted-schema round-trip fuzz across versions).
What
New
core/tests/test_persisted_schema_roundtrip.rs— a dependency-free, seeded (xorshift) round-trip fuzz over the persisted graph:LoopCheckpoint,RunRecord(incl. all three 3.3.0AgentEventvariants),SubagentTaskSnapshot,TraceEvent,VerificationReport,Message/ContentBlock, and the largest rootSessionData. Asserts serialize→deserialize→re-serialize stability (stronger thanPartialEq, which several of these don't derive). Plus cross-version coverage:schema_version/ the identity fields (tenant_id/principal/agent_template_id/correlation_id) / using the legacytodosalias all load with correct defaults.#[serde(deny_unknown_fields)]).#[serde(untagged)]ToolResultContentFieldand the persisted untaggedPermissionRule(bare-string vs{rule:...}) hazards.Fix: reject future checkpoint schema versions.
LoopCheckpointdocumented that loads from a future, incompatible schema version must be rejected, but no impl enforced it. AddsLoopCheckpoint::ensure_loadable(), called in both the file and memory store load paths — soresume_runsurfaces the error and the live-run sink starts fresh rather than misinterpreting a checkpoint whose field semantics may have changed.Verification
Some(serde_json::Value::Null)→Noneasymmetry inOption<Value>fields (a serde property, fixed in the generator, not a code defect).loop_checkpoint5/5,store36/36). CI gates green locally:cargo fmt --all --check,cargo clippy --workspace --lib --bins -D warnings; new test is clippy-clean.SessionData+PermissionRulecoverage that an initial pass missed).Pointer-stable, additive; no public API change beyond the new
LoopCheckpoint::ensure_loadable()method.