# Audit Chain Integrity Discipline — fleet operating standard (excerpt)

_Source: `docs/OPERATING_STANDARDS.md § Audit Chain Integrity Discipline (canonical)`. This is fleet
doctrine, published here verbatim in the parts that establish the claim. No redactions were required —
the standard contains no secrets, credentials, or customer data._

**Summary.** `audit_events` is append-only post-write. Once a row exists, its content is frozen — the
row's `event_hash` was computed against its payload at insert time, and `prev_hash` chains it to the
row before. Retroactive `UPDATE`s erode tamper-evidence **even when the touched columns aren't in the
hashed payload**, because a verifier can no longer distinguish "operator-authorized scrub" from
"attacker mutation."

**The rule (abridged):**

1. No `UPDATE audit_events SET …` post-write — period.
2. The only exception: updates touching ONLY the designated redaction-metadata columns
   (`redacted_at`, `redacted_reason`), and only when carrying an inline
   `-- caliber-allow: audit-redaction <rationale>` annotation.
3. Write-time scrubbing (`scrub_pii_jsonb`) is the correct pattern — the hash incorporates the
   scrubbed payload.
4. Adding a column to the hashed payload is a chain-boundary event requiring an explicit `chain_seq`
   cutoff.
5. `audit_verify_chain(account_id)` is ground truth. `mismatches > 0` OR `broken_links > 0` is a P1
   finding.

**Grandfathering (the incident).** The CrewOS `20260507c` label-scrub migration `UPDATE`d
`entity_label_snapshot` and `actor_label` — **both non-payload columns** — and predates this standard.
It is grandfathered because (a) the columns are not in the hashed payload, so chain integrity is
intact, and (b) **the affected rows were inside the `foundryos-test` sandbox account and were swept on
sandbox tear-down.** Future migrations of the same shape are forbidden.

**Verifier provenance.** Phase F sandbox e2e of the CrewOS Payment Plan Scheduler (2026-05-01) ran the
audit-chain verifier against the `foundryos-test` sandbox and reported **20 mismatches + 1142
broken_links**. Investigation traced the pattern to `20260507c` retroactively `UPDATE`ing label fields.
The chain still verified (the scrubbed columns were non-payload), but the anti-pattern was the lesson.

**Enforcement.** Caliber criterion **C49 (Audit Chain Integrity)** — Major 2pt, Engineering family,
scanner `system/caliber/lib/c49-audit-chain-integrity.mjs`. No bootstrap grace; the grandfathered
migration is named explicitly. Added 2026-05-01; mirrored in `system/SYSTEM_REGISTRY.md` and
`system/_operator/ENGINEERING_OS_STANDARD.md` (`E-ENG-AUDIT-CHAIN-INTEGRITY`).
