Lesson 99: Annual Escalation Policy Version Bump and Migration Runbook - Evolving lesson78_* Schemas Without Orphan Hashes

Direct answer: An annual escalation policy version bump is a semver-tagged change set ([email protected]) plus a migration runbook that freezes in-flight Lesson 92–98 trains, backfills new columns, recomputes dependent hashes (dry_run_evidence_hash, kill_switch_evidence_hash, attestation_evidence_hash, Lesson 98 digest_evidence_hash), and records schema_migration_id on every touched row so auditors see lineage, not magic.

Phone illustration suggesting a versioned device OS bump that must not brick live traffic

What this lesson solves

Schema drift is how governance dies quietly. This runbook makes column adds as serious as database migrations: freeze, transform, verify, sign.

Prerequisites: Write access to CSV stores, a staging copy of Lesson 97 zips, and a change advisory slot. Expected time: about one hundred minutes including a tabletop on a breaking column rename.

What you will build

  1. lesson78_annual_escalation_policy_version_bump_policy.md (contract below)
  2. lesson78_schema_migration_runbook.csv (one row per migration attempt, including rollbacks)
  3. A policy semver tag in every lesson78_* filename or frontmatter block your tooling reads

Step 1 - Define migration gate classes

gate fail signal posture
M1 – Active send window external send scheduled during transform block migration or route sends through legacy reader
M2 – Partial backfill nullable new columns without default policy stop; define default_for_legacy_rows
M3 – Hash break recomputed hash differs but schema_migration_id missing fail audit
M4 – Digest desync Lesson 98 slide still cites old manifest_sha256 re-issue digest row

Step 2 - Author lesson78_annual_escalation_policy_version_bump_policy.md

Minimum sections:

  1. Purpose – evolve lesson78_* contracts once per year unless emergency patch; emergency uses PATCH with thirty-day sunset.
  2. Semver rulesMAJOR = renamed or removed columns; MINOR = additive nullable columns; PATCH = documentation-only if hashes unchanged.
  3. Freeze window – default seventy-two hours with no new Lesson 95 overrides except P0 incidents logged under emergency_migration_flag=true.
  4. Backfill – deterministic scripts checked into version control; no hand edits in prod CSVs.
  5. Hash recompute order – Lesson 92 → 93 → 94 → 95 → 96 → 97 → 98 dependencies; re-run in topological order.
  6. Rollback – keep prior CSV snapshot tarball addressable by migration_id; practice restore quarterly.

Step 3 - Author lesson78_schema_migration_runbook.csv

column purpose
migration_id stable id
from_semver / to_semver policy versions
freeze_start_utc / freeze_end_utc communication window
scripts_git_sha automation pointer
rows_touched_count integer
hash_recompute_job_id orchestration id
m1_m4_gate_status pass / fail
signer_engineering_id owner
signer_governance_id second owner
migration_evidence_hash sha256 over manifest + logs

Step 4 - Execute migration (55 minutes dry-run)

  1. Snapshot all Lesson 92–98 CSVs and Lesson 97 zips; hash tarball.
  2. Announce freeze with freeze_end_utc and P0 exception path.
  3. Run transforms in staging; diff row counts and key hashes.
  4. Apply prod during lowest-traffic window; stream logs to immutable store.
  5. Recompute downstream hashes; open a fresh Lesson 97 attestation stub if quarter boundary crossed.
  6. Sign migration_evidence_hash.

Step 5 - Tabletop - “we only renamed a column”

Renaming dry_run_id_ref without a MAJOR bump and compatibility view breaks partner automation. Outcome: M3 failure; ship compatibility shim for two releases.

Pro tips

  • Dual-write period – for MAJOR, run old and new column writers in parallel for one sprint if partners lag.
  • Feature flags – gate new hash fields behind policy_semver >= x in CI validators.
  • Docs – update lesson markdown examples the same day; stale docs are a control failure.

Troubleshooting

symptom likely cause fix
Rows explode after join one-to-many merge mistake revert snapshot; fix script
Attestation zip rejects manifest not regenerated rebuild manifest after migration
Board digest unchanged forgot Lesson 98 refresh open new digest_id

Common mistakes

  • Migrating Friday 4 p.m. without freeze comms.
  • Letting analytics drop columns they think are unused—hashes depend on them.
  • Skipping Lesson 94 recompute because holds were empty.

FAQ

Do we migrate Lessons 89–91 too?

Yes when their exports feed Lesson 92 inputs; include them in the same migration_id or declare explicit version pins.

What if only docs change?

PATCH only if byte-identical CSV outputs; otherwise bump MINOR.

Who approves MAJOR?

Engineering lead + governance lead + legal on column removals affecting disclosures.

Lesson recap

A schema bump without a runbook is a silent recall on your evidence chain. Version everything that touches a hash.

Next lesson teaser

Next: Lesson 100: Fiscal-Year Escalation Governance Closure Checklist seals the year—quarterly Lesson 97 zips, Lesson 98 digests, Lesson 99 migration, zero stuck verification rows, dual-signed fiscal_closure_evidence_hash, next-year charter.

Related learning

Treat semver as API compatibility, not marketing labels.