Disciplines · Proposals

Contract Compatibility Policy (YSD-2010)

1.

4sections3 minread

On this page

Version 1.0.0 — 2026-07-18. Governs every versioned study-workspace artifact class: contracts, events, taxonomies, saved views, and portable exports. Enforced automatically by libs/contracts/scripts/generate-study-schemas.ts --check (CI quality job), whose findBreakingChanges detector diffs the published schemas against the frozen per-major baseline (libs/contracts/schemas/study/baseline/v<major>/).

Versioning rules (all classes)#

  1. Semver, one version per namespace. The study contracts namespace carries STUDY_CONTRACTS_VERSION; events, taxonomy vocabularies, saved views, and portable-export manifests each carry their own semver version field in their envelope (schemaVersion / vocabulary version / viewVersion / manifest version).
  2. Breaking = major. A change the detector classifies as breaking (removed artifact, removed property, property type change, enum narrowing, newly-required property, additionalProperties tightening, union narrowing) MUST bump the major version, ship a new baseline via --write-baseline, and keep the prior major listed in SUPPORTED_STUDY_SCHEMA_VERSIONS for its published support window.
  3. Additive = minor. New optional fields, new enum values, new union variants, new artifacts. Old readers handle these through the parseWithCompat boundary (unknown-optional-field stripping with reported paths — never silent), property-tested in roundtrip.property.spec.ts.
  4. Never rewrite history. Baselines and prior-version canonical examples are append-only; a supported prior version's canonical examples must keep parsing under the current runtime (tested per version).
  5. Version-gated refinements are additive (clarified 2026-07-19, first applied by YSD-2100 in 0.4.0). A runtime refinement that keys on the record's own envelope.schemaVersion and applies only to versions that did not exist when the rule landed can never invalidate a previously-valid record, so it ships as a minor bump with the new requirement documented on the field. The exempt-version set is frozen in code (e.g. PRE_IDENTITY_SCHEMA_VERSIONS) and a canonical example at a prior version must prove the exemption keeps parsing (rule 4).

Per-class application#

Class Version carrier Enters detection when Extra rules
Contracts STUDY_CONTRACTS_VERSION + envelope schemaVersion already live (17 published) runtime refinements may only tighten with a major bump
Events (YSD-6xxx) event envelope schemaVersion event contracts publish through the same registry (STUDY_SCHEMA_REGISTRY) — mandatory at creation consumers must tolerate unknown event kinds (route to dead-letter, never drop silently)
Taxonomies (YSD-2035) vocabulary version taxonomy term schemas publish through the registry; term REMOVAL is always breaking; deprecation + migration rules ride minor versions migration rules required per YSD-2035
Saved views (YSD-2158) viewVersion saved-view schemas publish through the registry a view referencing removed query features must open in a degraded-but-honest mode, not fail silently
Portable exports (YSD-15xxx) manifest version export-manifest schemas publish through the registry exports embed the schema versions they were written with; importers use assertSupportedSchemaVersion and refuse unknown majors explicitly

The registry is the enforcement chokepoint: an artifact class cannot ship a schema without entering STUDY_SCHEMA_REGISTRY (the manifest-equality test fails otherwise), and everything in the registry is baseline-diffed in CI. Adding a class is therefore automatically adding its breaking-change detection — there is no per-class opt-in to forget.

Deprecation and support windows#

  • A major version remains supported (parseable, listed in SUPPORTED_STUDY_SCHEMA_VERSIONS) for at least one full release cycle after its successor ships, and until every persisted record of that major has been migrated (YSD-0011 migration plans) — whichever is later.
  • Dropping a version from the supported list is itself a breaking change: it requires a migration evidence entry in the program evidence log and a major bump.

Escalation#

A change the detector flags as breaking that the author believes is safe is NOT self-approved: it goes to the decision owner as a decision-log entry (same harness as Section 0.2), because "safe breaking change" judged by the change author is exactly the failure mode this policy exists to stop.