dgenio / dgenio/contextweaver

Add a cross-version serialization compatibility fixture suite for persisted payloads

Open
#613 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

architecture complexity:complex priority: medium reliability testing
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_dict methods 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.py maintains _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

  1. Add tests/fixtures/compat/v0.14/… generated from the current release (a scripts/gen_compat_fixtures.py writer, run at each release and committed — wire a reminder into the release checklist).
  2. 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.
  3. 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.py migration path, tests/fixtures/_normalize.py, CLI ingest output 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.