The frozen JSON contract for differential reading plans.
This crate is the product boundary: every consumer (shadow-branch stack, TUI, forge review) depends on these types and nothing else. Consumer conveniences must not leak in here.
Contract rules:
schema_versionis 1. Readers must reject versions they do not know.- Deserialisation tolerates unknown fields, so additive changes are non-breaking.
groups/reading_planarenullwhen the grouping stage has not run. That is distinct from[], which would mean "grouping ran and produced nothing" and is always a bug.generator.stagesstates exactly which stages produced the document.- Optional fields serialise as explicit
null, never omitted.