Protocolosschema-versioning

schema-versioning

Spec canónica de protocols/schema-versioning/README.md, copiada sin reescribir.

ImplementadoSin versión del tren todavía· generada desde protocols/schema-versioning/README.md

Página generada desde protocols/schema-versioning/README.md. No se edita a mano: bun run docs:gen la regenera y bun run docs:check falla si difiere.

Schema Versioning Rules

Propósito

Definir las reglas de evolución de esquemas para todos los contratos del sistema Styx: mensajes del bus NATS (cmd/qry/evt), mensajes IPC (Bun ↔ Zig), y contratos de serialización de media.

schemaVersion

  • Bus NATS y socket de control del daemon comparten el sobre v2 de spire (dec-0119, dec-0120; MKS2508/spire spec/ENVELOPE_V2.md): su primer byte es la versión del sobre (2) y cada mensaje lleva el contract_version (u16 ≥ 1) de su contrato.
  • Cada contrato (packages/api-contracts/src/bus/*.ts: requestContract / eventContract) declara su version, independiente del sobre. Un cambio incompatible de un contrato es una versión nueva del contrato; un cambio del formato del sobre es una versión nueva del sobre, nunca una extensión.

Reglas de compatibilidad

Backward compatibility

Un schema nuevo (v2) debe poder leer mensajes escritos con el schema viejo (v1).

  • Campos nuevos deben ser opcionales (tener valor default o ser marcados como opcionales).
  • No se puede cambiar el tipo de un campo existente.

Forward compatibility

Un schema viejo (v1) debe poder leer mensajes escritos con schema nuevo (v2) sin crash.

  • Campos nuevos son ignorados si el schema no los conoce.
  • El parser debe tolerar campos extra.

Unknown-field policy

FormatoPolítica
JSONMUST ignore, MUST NOT crash, MAY log warning, MUST discard al re-serializar.
ProtobufMUST ignore, MUST NOT crash, MUST preserve al re-serializar (protobuf wire format retiene unknown fields).
Contratos del bus (spire)Objetos cerrados (additionalProperties: false): un campo desconocido es invalid_request. Un campo nuevo es una versión de contrato nueva, que emisor y receptor despliegan a la vez (la tabla de rutas es una sola).

Deprecation windows

  • Deprecar campos con mínimo 2 versiones de aviso (ej. marcar como @deprecated en JSDoc + log warning).
  • Mínimo 1 versión entre deprecación y eliminación.
  • Durante el período de deprecación, el producer y consumer deben loguear un warning al enviar/recibir el campo deprecated.

Schema freeze

  • El formato del sobre (spire v2) no cambia sin aprobación explícita de waxin (el paso del MessageEnvelope v1 al sobre de spire lo aprobó el lock del 2026-09-28, dec-0119/dec-0120).
  • Cambios en schemas de contratos individuales son decisión del maintainer del servicio.

Aplicación

  • Runtime: spire valida petición y respuesta contra el contrato a los dos lados (TypeBox compilado en TS; validate() del espejo generado en Zig).
  • Compile-time: TypeScript asegura que los tipos están actualizados.
  • Documentación: Este directorio es la fuente de verdad para reglas de versionado.