# Canonical Model Backward-Compatibility Playbook

This playbook captures the policies and workflow required when evolving the canonical
`StellaOps.Feedser.Models` surface.

## Principles

- **Additive by default** – breaking field removals/renames are not allowed without a staged
  migration plan.
- **Version-the-writer** – any change to serialization that affects downstream consumers must bump
  the exporter version string and update `CANONICAL_RECORDS.md`.
- **Schema-first** – update documentation (`CANONICAL_RECORDS.md`) and corresponding tests before
  shipping new fields.
- **Dual-read period** – when introducing a new field, keep old readers working by:
  1. Making the field optional in the canonical model.
  2. Providing default behavior in exporters/mergers when the field is absent.
  3. Communicating via release notes and toggles when the field will become required.

## Workflow for Changes

1. **Proposal** – raise an issue describing the motivation, affected records, and compatibility
   impact. Link to the relevant task in `TASKS.md`.
2. **Docs + Tests first** – update `CANONICAL_RECORDS.md`, add/adjust golden fixtures, and extend
   regression tests (hash comparisons, snapshot assertions) to capture the new shape.
3. **Implementation** – introduce the model change along with migration logic (e.g., mergers filling
   defaults, exporters emitting the new payload).
4. **Exporter bump** – update exporter version manifests (`ExporterVersion.GetVersion`) whenever the
   serialized payload differs.
5. **Announcement** – document the change in release notes, highlighting optional vs. required
   timelines.
6. **Cleanup** – once consumers have migrated, remove transitional logic and update docs/tests to
   reflect the permanent shape.

## Testing Checklist

- `StellaOps.Feedser.Models.Tests` – update unit tests and golden examples.
- `Serialization determinism` – ensure the hash regression tests cover the new fields.
- Exporter integration (`Json`, `TrivyDb`) – confirm manifests include provenance + tree metadata
  for the new shape.

Following this playbook keeps canonical payloads stable while allowing incremental evolution.
