Overview
Of the four evolution moves in vault-evolution, this is the only one that touches notes that already exist. Deciding that every decision-relevant atom must now carry last_verified, or every claim a corroboration_count, changes the contract for hundreds of files at once. Treat it with the same up-and-backfill discipline a schema change gets in migrations, where the migration is not done until the data is.
Change the spec first, then let the auditor write the worklist
Add the field to the type’s required list in vault-spec.yaml and run the auditor. Every note that lacks the field now fails the missing-field rule, and the JSON report lists them file by file. That list is the backfill worklist: scoped, finite, and enumerated by the tool that will later confirm it is done. Do not build the worklist by hand or by search; the auditor’s definition of “missing” is the one that will be enforced. The per-type mechanics are in vault-frontmatter-schema.
Scope-freeze the backfill before touching a file
A backfill that touches more than a handful of notes is a bulk write, and it gets the pause every bulk write gets in vault-audit: state the exact path list, state that the edit is a frontmatter addition and reversible in version control, and get sign-off before applying. The list came from the auditor, so it is already exact.
Prefer one value per note, written by a person who knows it or by a reviewed script that derives it. A blind global default applied to every file is not a backfill; it is a lie the schema now vouches for.
Never backfill a fabricated value
Writing today’s date into last_verified on a claim that was verified two years ago makes the vault assert something false about its own provenance, and every downstream check will trust it. The same holds for a guessed confidence, an invented source, or a corroboration_count nobody counted.
When the honest value is unknown, leave the field empty and leave the finding open. An open warning is accurate; a closed one built on a fabricated value is worse than no field at all. The verification discipline this protects is in source-verification.
Let autofix fill only what it can derive
The auditor’s mechanical tier will fill a missing id from the filename, created and modified from file mtime, status with the default, and the structural tags. Run it in dry-run first, then apply, and let it clear that layer of the worklist. It stops at every semantic field on purpose. What remains after autofix is the part of the migration that needs a human, and the boundary is spelled out in audit-rule-catalog.
Re-run and treat the delta as the proof
Run the auditor again after the backfill. The missing-field count for that field should return to zero, and the run should introduce nothing new. The difference between the two reports is the migration’s evidence: the first run enumerated the debt, the second shows it paid. Append both to the log so the migration is visible in the trend line.
Demote rather than delete when a field stops mattering
The inverse move is not the mirror image. When a field stops being required, move it out of the required list and leave it in the notes. It stays valid frontmatter, just unenforced, and the values it holds remain queryable. Stripping it from files is a bulk write with no benefit and a real cost if the field is needed again.
Ship it as a pull request in a shared vault
In a team vault the spec change and the backfill travel together on one branch, with the auditor’s pre- and post-run output in the description. Criticals block, the reviewer checks that no value was fabricated, and the merge lands the schema and the data as one change, per vault-pull-request-review.