# Schema Bump
When `SCHEMA_VERSION` changes, the change must be atomic across four surfaces.
Partial bumps are how silent drift gets shipped.
## Triggers
A bump is required when any breaking change from
[wire-contract-review.md](wire-contract-review.md) lands. It is **not**
required for additive changes (new variant on an open enum, new optional field
with `skip_serializing_if`) — those need a new wire-test assertion only.
## Procedure
```bash
make bump-schema VERSION=lifeloop.vN REASON="<one-line rationale>"
```
(Direct invocation:
`cargo run --bin lifeloop-bump-schema -- lifeloop.vN "<rationale>"`.)
The tool handles two of the four surfaces atomically (temp-file + rename
with explicit lib.rs rollback if the tombstone promotion fails):
1. Updates `SCHEMA_VERSION` in `src/lib.rs`.
2. Writes `docs/tombstones/<old-version>.md` with a removal-criteria stub.
Manually complete the remaining surfaces in the same commit:
3. Update `tests/wire_contract.rs` so every assertion that pins
`schema_version` reflects the new value.
4. Update `README.md` and `docs/product-thesis.md` if they cite the version
explicitly.
Then run `make verify` and commit all four surfaces in a single commit. The
commit message should reference the rationale and link to the tombstone.
## Tombstone hygiene
Each tombstone must specify removal criteria — a concrete condition under
which it can be deleted (e.g. *"after two quarters with zero observed
`lifeloop.v0` receipts in production"*). Tombstones without criteria are
forbidden by AGENTS.md and accumulate as silent technical debt.
Migration notes must tell consumers exactly what to change. "See the source"
is not a migration note.