Skip to content

Archive drift: verify diagnoses, refresh can hide — don't confuse the three modes

Guide

<!-- last-reviewed: do not apply expiry — knowledge entries are dated records (governance = supersession, not expiry; see knowledge-management.md §5) -->

Archive drift: verify diagnoses, refresh can hide — don’t confuse the three modes

  • Date: 2026-06-01 · By: The Archives (Archivist)
  • Topic: the archive-manifest.sh verify/update/refresh distinction — the drift-masking foot-gun
  • Status: active

Append-only, dated, one topic per entry. This is the inbox — captured first; promoted into the Archives SOPs/job aid (see Promotion below).

What we learned

scripts/archive-manifest.sh has three modes, and only one is safe to reach for when verify reports drift. Treating them as interchangeable is how a real source regression gets silently buried in the record.

  • verify (default, read-only) — recomputes every latest/ hash, checks each latest against its working source, and checks no first/ was mutated. It prints verify: N OK, N drift, N missing and exits non-zero on any drift/missing (so hooks/CI catch it — scripts/archive-manifest.sh:63-66). This is the only gate; it changes nothing.
  • update — rewrites the SHA-256 in each latest MANIFEST row from the latest/ file (re.sub(r"[0-9a-f]{64}", h, line, count=1), scripts/archive-manifest.sh:42-45). Use after you have intentionally refreshed latest/. It does not touch the working source.
  • refresh — shutil.copyfile(src, latest) for every row, then update (scripts/archive-manifest.sh:35-36). This is the foot-gun: it copies the current working file over latest/ and then re-checksums, so a latest != src drift always goes green — even when the source itself regressed. refresh makes the symptom disappear without telling you what changed.

The dead end: when verify flags latest != docs/foo.md, the instinct is “just run refresh to sync it.” That is wrong when the source is what drifted (a bad edit, a partial save, a revert). refresh will faithfully preserve the bad source and you lose the signal. The correct move is to diagnose with verify/cmp first, confirm the working source is the intended content, then update (checksum-only) — reserving refresh for the deliberate “I changed many sources on purpose, re-sync all latest” case.

Separately, FIRST MUTATED (scripts/archive-manifest.sh:46-50) is never a “re-run a mutating mode” situation — a first/ was edited, which the spec forbids (archive/SPECIFICATION.md §3). Restore from the origin commit; never re-checksum to hide it.

Why it matters

The whole org’s DoD leans on a single line — 0 drift — as proof of integrity (docs/documentation-program/README.md §10; docs/sop/change-management.md DoD). If the Archivist reflexively refreshes to turn the line green, that proof becomes a lie: the record now faithfully preserves a regression. The distinction between a diagnostic (verify) and a mutator (refresh) is the difference between the archive being trustworthy and merely looking trustworthy.

Next time

  • When verify reports drift, run verify / cmp to identify what drifted before mutating anything.
  • Use update (checksum-only) after an intentional latest/ refresh; use refresh only for a deliberate bulk source→latest re-sync, never as a drift “fix.”
  • On FIRST MUTATED, restore the immutable version from its origin commit; do not re-checksum.

Promotion

  • Promoted to: docs/sop/SOP-011-archive-integrity-verification.md (steps 3–4 and Guardrails) and docs/units/archives/job-aids/JA-010-omni-intake.md (If it goes wrong). Also surfaced in the Archives playbook (docs/units/archives/playbook.md).
  • Supersedes / superseded by: none. (Builds on docs/knowledge/2026-05-30-intranet-and-archive-automation.md, which introduced the script; this entry adds the verify-vs-refresh hazard, not yet covered there.)