Skip to content
fitme·story
Case studies
v7.10 · 2 min read · 2026-06-22

Contract-Fixture Consumer Adoption (E-15) — closing the W16 cross-repo silent-pass (v7.10)

The /control-room/framework page threw a TypeError in production for 13 days with green CI the whole time: the FitTracker2 producer emitted `timestamp`, the fitme-story consumer expected `event.ts`, and both repos' test suites agreed on the wrong shape (W16). The fix is a contract-sampling discipline — validate what a consumer reads against the producer's REAL sampled output, never a hand-authored fixture. The FT2 substrate shipped 2026-06-07; E-15 closes the cross-repo consumer half: a unified checker (shape = hard fail, freshness = asymmetric), a PII-safe audit-log canonical sampler, and a weekly re-sample cron.

Producer↔consumer shape drift
13 days
in production — both repos' tests agreed on the wrong shape, so drift only surfaced as a prod TypeError.
Drift caught at consumer CI
100%
required-key drift fails contract:check against the producer's real sampled output before merge.
What do T1 / T2 / T3 mean?
T1Instrumented — from a ledger/commit
T2Declared — stated, not measured
T3Narrative — estimate from memory

Contract-Fixture Consumer Adoption (E-15)

Status: shipped 2026-06-22 (fitme-story#252 + FT2 #790). Closes the W16 silent-pass class end-to-end across both repos.

The incident that named the discipline

On 2026-05-24 (W16), the /control-room/framework page threw a TypeError in production for 13 days with green CI the whole time. The FitTracker2 gate-coverage producer emitted a timestamp field; the fitme-story consumer expected event.ts; and both repos' test suites agreed on the wrong shape, so neither caught the drift.

The lesson: a consumer test that hand-authors the producer's shape validates nothing — it just re-encodes the same assumption on both sides. The fix is to validate against the producer's real sampled output.

What shipped

The FT2 substrate (scripts/sample-contract-fixtures.py, make check-contract-fixtures, warn-only in pr-integrity-check.yml) shipped 2026-06-07. E-15 closed the cross-repo consumer half:

  • scripts/check-contract-fixtures.ts — a unified checker. Shape (required_keys) = HARD fail (the incident class). Freshness = asymmetric: WARN for FT2-produced fixtures fitme-story vendors (it cannot self-re-sample them), HARD for fitme-story-owned contracts. Validates the vendored fixtures and the live src/data/features/*.json consumer (113 files).
  • scripts/sample-audit-log-contract.ts — the audit-log canonical sampler. fitme-story is that contract's canonical producer (the UCC auth stream lives in Upstash Redis here). It sanitizes each record via sanitizeForPublicExport before write (the fixture is committed and publicly reachable), and no-ops cleanly without Redis creds.
  • .github/workflows/contract-resample-weekly.yml — Mondays 07:00 UTC. Re-samples audit-log and re-vendors the FT2 fixtures via a fresh clone, each step guarded on its secret, and opens a PR on change.

A verification-first surprise

Outcome

npm run contract:check → PASS; 16/16 new tests + aggregator 9/9 green; FT2 post-merge integrity-check 0 findings and check-contract-fixtures all fresh (0.0d). Producer-shape drift now fails at consumer CI time instead of in production, and a weekly cadence keeps the fixtures honest.

Cross-references

Honest disclosures
  • Freshness is ASYMMETRIC by design — WARN (not hard) for FT2-produced fixtures fitme-story vendors but cannot re-sample; HARD only for fitme-story-owned contracts (audit-log) where it controls re-sampling.
  • The warn-only → blocking flip was deliberately NOT done: FT2's contract-fixtures cron is drift-only + warn-only per operator decision D2 (2026-06-18), and the fitme-story consumer gate is day-0 and must soak warn-only first. The flip date is an operator decision.
  • fixture_staleness_days is T2 (declared) — the 15-day figure is the observed sample age at session start, verified by the first scheduled cron fire rather than continuous instrumentation.
Kill criterion · not fired
  • Freshness check too strict — breaks fitme-story CI when an FT2-produced fixture goes stale between syncs (the consumer cannot self-re-sample those).
  • The audit-log sampler leaks PII into the committed, publicly-reachable fixture.
  • Consumer tests hand-author the producer shape (the W16 anti-pattern), so drift still passes silently.