Rocket Telemetry Project Docs

ADR-002: Schema Governance & Compatibility Policy

Decision record for payload schema versioning, compatibility, and registry policy for mission payloads.

Metadata


Problem / Context

Payload schemas are defined by the mission pre-launch (e.g., "target 1 transmits CCSDS frames with telemetry struct A; target 2 transmits raw quantized I/Q"). The architecture (System-APIs-Contracts) defines several frame types and payload structures, but leaves open:

  1. Schema evolution: If a payload struct changes mid-mission (e.g., new field added), how do we handle mixed frame versions?
  2. Backward compatibility: Can central decode frames from nodes running older firmware?
  3. Forward compatibility: Can nodes running old firmware decode new schema definitions sent from central?
  4. Versioning scheme: How do we tag schema versions (semantic, git SHA, timestamp)?
  5. Migration windows: Do we require synchronized schema updates, or allow rolling updates?
  6. Fallback behavior: If central receives a frame with unknown schema version, drop it or fall back to raw?

Current State

  • Schemas are inline JSON in mission config (System-OperationalFlow)
  • No versioning mechanism defined
  • No migration strategy for mid-flight schema changes
  • Prototypes assume static schema for entire mission

Why This Matters

  • Robustness: Firmware updates should not break decoding if schemas change
  • Agility: Teams should be able to refine payload definitions without synchronizing across all nodes
  • Auditability: Schema history for post-mission analysis (did we decode correctly?)
  • Interoperability: If we add new targets mid-mission, how do they integrate without restart?

Deferred Decision Options

Option A: Semantic Versioning + Strict Compatibility

Approach: Use SemVer (major.minor.patch) for schemas. Major version bumps require schema migration plan; minor/patch are backward-compatible.

Pros:

  • Clear versioning semantics (everyone understands "major vs. minor")
  • Strict rules prevent hidden incompatibilities
  • Standard practice (HTTP APIs, gRPC, Protobuf all use versioning)
  • Schema registry tools exist (Confluent Schema Registry, etc.)

Cons:

  • Requires discipline: developers must commit to backward compatibility
  • Migration windows can be lengthy
  • For multi-target missions, different targets may use different schema versions simultaneously

Implementation:

  • Store schema in centralized registry: /opt/schemas/target-1-telemetry-v2.1.0.json
  • Mission config references schema by full version: "schema_id": "target-1-telemetry-v2.1.0"
  • Central decoder stores multiple schema versions (last 5 major versions)
  • Node accepts schema from central; validates against local schema version
  • If incompatible, node logs warning and attempts raw fallback

Option B: Git Commit SHA + Lenient Decoding

Approach: Tag each schema with the git commit SHA where it was defined. Accept any schema version; decode what you can, ignore unknown fields.

Pros:

  • Zero ceremony: schemas update whenever code changes
  • Lenient parsing: unknown fields don't break decoding (just ignored)
  • Auditable: git history is the versioning source of truth
  • Supports rolling updates: old nodes can decode new schemas partially

Cons:

  • No "compatibility guarantee" , you have to test it
  • Hard to understand versioning from user perspective (SHA is not human-readable)
  • Silent data loss if unknown field is critical (e.g., checksum field added but old decoders ignore it)
  • No way to prevent breaking changes

Implementation:

  • Schema file includes git SHA as metadata: "_schema_commit": "a3f4b5c0"

On this page