Add a cross-version serialization compatibility fixture suite for persisted payloads
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 9
- Forks
- 17
- Avg merge
- 21h 36m
- Merged PRs (30d)
- 22
Description
Summary
Commit versioned "produced-by-vX.Y" fixtures for every persisted payload (ChoiceGraph + GraphManifest, RouteResult/RoutingDecision, ResultEnvelope, BuildStats, session files from ingest, SQLite event-log schema) and a test matrix asserting current code loads each older fixture per the compatibility rules — turning the version-compatibility policy (investigated in #477) into an executable regression suite.
Why this matters
Users persist graphs, sessions, and decisions (CLI build/ingest/replay, SqliteEventLog, JsonFileArtifactStore); silent load breakage across releases is the classic pre-1.0 trust killer. The repo already excels at schema drift gating for current shapes; what's missing is the backward-load dimension across released versions.
Current evidence
from_dictmethods are written default-tolerant ("Missing keys fall back to dataclass defaults so older payloads round-trip cleanly" —routing/router.py:183), but nothing tests against actual older-version artifacts.store/_sqlite_base.pymaintains_contextweaver_schema_version— migration scaffolding exists with no committed old-DB fixture test.tests/fixtures/has golden fixtures for current shapes only.- Open #477 "[Investigation] Define version-compatibility guarantees for persisted graph and result payloads" — this issue is the concrete implementation/regression layer that #477's policy feeds; reference it explicitly.
External context
Fixture-based backward-compatibility suites are how serialization-stable libraries (protobuf, pydantic ecosystems) verify load guarantees release over release.
Proposed implementation
- Add
tests/fixtures/compat/v0.14/…generated from the current release (ascripts/gen_compat_fixtures.pywriter, run at each release and committed — wire a reminder into the release checklist). - Parameterized loader tests: every fixture × current
from_dict/loader must succeed and satisfy shape assertions; SQLite: open an old-schema DB file and assert migration or a clear versioned error per the #477 policy. - On each release, append (never overwrite) the new version's fixtures; prune per the support window once #477 defines it.
AI-agent execution notes
- Inspect first:
serde.py,routing/graph_io.py,routing/manifest.py,store/sqlite_event_log.pymigration path,tests/fixtures/_normalize.py, CLIingestoutput shape. - Determinism: fixture generation must be seeded/clock-injected (relates to the injectable-clock candidate) so regeneration is reviewable.
- Don't hand-edit fixtures; only the generator writes them.
Acceptance criteria
- Committed v0.14 fixture set for at least graph+manifest, RoutingDecision, ResultEnvelope, session file, and a SQLite event-log file.
- A load-compat test module passing in CI; failure message names the payload type and fixture version.
- Release checklist (workflows.md or stability.md) updated with the fixture-generation step.
Test plan
The compat suite; a negative test with a deliberately incompatible fixture asserting the documented error; make ci.
Documentation plan
docs/stability.md persistence-compatibility section; CHANGELOG; release workflow doc.
Migration and compatibility notes
The suite documents rather than changes compatibility. Any incompatibility it reveals must ship with a migration note per existing policy.
Risks and tradeoffs
Fixture maintenance at each release (small, scripted); risk of enshrining accidental formats — coordinate with #477 so guarantees are intentional.
Suggested labels
testing, reliability, architecture
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with #477, then inspect serde.py, routing/graph_io.py, routing/manifest.py, store/sqlite_event_log.py, tests/fixtures/_normalize.py, and the CLI ingest output shape. Run the existing fixture tests and make ci to understand current coverage. Done means committed versioned fixtures, parameterized load tests with named failures, a negative incompatibility test, and the release and stability documentation updates.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, sqlite
- Domain
- backend, databases, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100