# Local evidence classification Status: implemented Updated: 2026-08-29 Standard: `net-kingdom/canon/standards/security-layer-model_v0.7.md` §9.6 Companion: `net-kingdom/SECURITY-COMPANION.md` §6 Local audit records and the durable outbox prove the records they hold were **not altered or truncated after arrival**. They do not prove that an event never sent did not happen. Sound sentences: - the archive proves the records it holds were not altered or truncated after arrival - absence of a record is not evidence of non-occurrence Unsound sentences, not used here: - the audit record proves it happened - there is no record, so it did not happen - the trail is complete ## Classification | Kind | Test | Local form | | --- | --- | --- | | **Load-bearing** | a control's soundness depends on the event being present | authorization denials; `account.status_changed`; `tenant_account.status_changed`; `prepared_account.revoked`; `family_invitation.revoked` | | **Attributive** | forensic reconstruction; no control branches on presence | user/profile/membership-added/catalog/registration/hat events | | **Heartbeat** | positive claim that can itself go missing | `user_engine.evidence.heartbeat` | Successful mutations enqueue local audit and outbox in the same store transaction. That prevents accidental omission (crash between save and emit) of the *local* record. Drain to `audit-core` is after commit. ## Cadence Rate monitoring cannot detect suppression of rare denials and revocations. The required form is a **heartbeat**: `UserEngineService.record_evidence_heartbeat()` emits a positive claim with counts of load-bearing classes already on the local trail. The payload sets `completeness_claimed: false`. Expected interval: one hour when a drain loop is running. The heartbeat is the claim that can go missing; it is not a completeness proof. Adversarial omission at a compromised source is a known residual. Nothing in this model prevents it.