Skip to content
INV-ARC-016: Lawful Existence and Audit Lineage

INV-ARC-016: Lawful Existence and Audit Lineage

Reference Number Version Effective Date Supersedes Authority Level
INV-ARC-016 2.3 2026-10-14 2.2 Constitutional

Important

v2.3 (2026-10-14), developer-documentation modernization pass. Corrected a mislabeled Authority Level: this is a Tier 1 (INV-ARC) document and must read Constitutional, not Foundational – “Foundational” is reserved for INV-CORE (Tier 0). No substantive rule in this document changed.

I. Purpose

Define the principle of lawful existence: physical database persistence alone does not constitute a valid application entity. A protected row is lawful only if it was created through an authorized CTH execution path and carries verifiable audit lineage.

II. Scope

Applies to all state mutation paths for protected tables.

A protected table is any table whose row-level mutations must produce an AuditEvent chain entry, as declared in DOM-OPS-002.

Protected tables include:

  • monetary truth lineage,
  • operational lineage,
  • constitutional economic policy lineage,
  • and other constitutionally protected mutation surfaces.

III. Authority Level

Constitutional within INV-ARC. Derived from INV-CORE-000 Section III.3, Deterministic and Traceable Financial Logic, and governed within the hierarchy described by INV-CORE-001.

IV. Dependencies

  • docs/INVARIANT/CORE/INV-CORE-000_CORE_INVARIANTS.md
  • docs/INVARIANT/CORE/INV-CORE-001_CAPABILITY_BASED_ARCHITECTURE_AND_AUTHORITY_MODEL.md
  • INV-ARC-006_COMMAND_BOUNDARY_FOR_MUTATION.md
  • INV-ARC-007_GET_MUST_BE_PURE.md
  • DOM-OPS-002_AUDIT_LINEAGE_INTEGRITY.md
  • DOM-CLASS-003_ECONOMIC_POLICY.md
  • docs/SPEC/SPEC-SEC-001_CREDENTIALS_AND_IDENTITY_LOOKUP_CODE_CONTRACT.md (incorporated in part; see Section VII)

V. Core Rule

A row in a protected table that was written outside a lawful CTH execution path (an active FEAT context or SystemAuditAuthority) is not a valid application entity, regardless of its physical presence in the database.

This invariant applies equally to:

  • monetary truth,
  • operational truth,
  • constitutional economic policy truth,
  • effective-dated economic policy history,
  • and future economic law objects.

The auditor of a protected row’s lawfulness is the HMAC-SHA256 chain maintained by DOM-OPS-002. A row is lawful if and only if:

  1. Its lineage_event_id references an AuditEvent whose payload_digest matches the row’s current protected field values, and
  2. That AuditEvent sits within a continuous, unbroken chain for its scope.

Constitutional economic policy truth is held in each owning domain’s own append-only, effective-dated table (DOM-CLASS-003 §V); DOM-OPS-002 §5.4 declares which of those tables are protected. (2.2, operator ruling 2026-09-30: the class-wide policy_versions / policy_transitions tables formerly listed here were never authorized as canonical and are retired.)

Future economic law that lacks lawful lineage is constitutionally invalid regardless of physical persistence.

VI. Lineage State Taxonomy

Every protected row has exactly one of four lineage states. All code that reads, reports, or acts on lineage MUST use this taxonomy exclusively.

State Meaning Operational Response
VERIFIED lineage_event_id set; current payload digest matches the linked AuditEvent; chain is continuous Treat as lawful
UNVERIFIED lineage_event_id is NULL — row predates lineage rollout or sits in a table not yet covered by Phase 3b Do not treat as INVALID. Log as coverage gap. Operators shall track toward zero over time.
INVALID Lineage present but payload mismatch, chain broken, or HMAC invalid Reject in strict read paths. Trigger IntegrityStatus degraded. Treat as an incident.
DEGRADED Verifier infrastructure unhealthy (e.g., ChainHead missing, AUDIT_HMAC_KEY absent, DB error during chain walk) Mark IntegrityStatus degraded with reason. Produce neither false VERIFIED nor false INVALID results.

UNVERIFIED is a transitional state expected for pre-rollout rows. INVALID is an incident. These states must never be conflated in code, logs, or operator-facing output.

VII. HMAC Key Requirement

The AUDIT_HMAC_KEY environment variable is required at application startup. The application shall refuse to start if this variable is absent. It is separate from PEPPER_KEY and must never be shared between environments.

“At startup” is the operative clause and it is not satisfied by an equivalent check somewhere later. A verifier that raises on the first audited write fails inside a FEAT’s transaction, in front of a user, on a deployment that already booted clean — which is the failure mode this section exists to prevent. The DEGRADED row in Section VI is the state for a key that becomes unusable at runtime, not a licence to start without one.

Incorporation of SPEC-SEC-001

The handling requirements for AUDIT_HMAC_KEY as an environment variable — high entropy, environment-specific, never logged and never exposed in an application response — are SPEC-SEC-001 Section V.1a, which is incorporated here for that variable’s row and for the independent-rotation rule that follows the table. AUDIT_HMAC_KEY rotation is an audit-lineage verification event and must be planned separately from PEPPER_KEY, SECRET_KEY, and ENCRYPTION_KEY rotation; no code may fall back from one to another. This restates in code terms what the paragraph above already requires of key separation.

Two boundaries on that incorporation, stated so they are not read wider than intended:

  1. Only the AUDIT_HMAC_KEY row and the rotation-independence paragraph are incorporated by this document. The other rows of the Section V.1a table belong to the contracts that own those keys — INV-ARC-018 for ENCRYPTION_KEY and PEPPER_KEY, INV-ARC-019 for credential material.
  2. Section V.1a states the startup gate more broadly than this section does: it requires refusal when a required variable is “absent, blank, malformed, or uses a development/default value.” The implementation in app/__init__.py currently rejects only absent and blank values. The malformed and development-default conditions are a known, recorded gap rather than a requirement in force, and this section incorporates only the absent/blank gate it has always stated. Closing that gap requires its own change and its own verification; it must not be assumed closed on the strength of this reference.

VIII. AuditEvent Immutability

AuditEvent rows are append-only. No code path outside emit_audit_event() in app/services/audit_service.py may write to the audit_events table. UPDATE and DELETE on audit_events are prohibited in all environments.

IX. Lawful Write Paths

Two write paths are lawful for producing AuditEvent chain entries:

  1. Active FEAT context — the business mutation path. emit_audit_event() is called inside an active FEAT via audit_protected() after db.session.flush(), before the FEAT’s owning transaction commits.
  2. SystemAuditAuthority — the narrow system path for genesis bootstrap, verifier writes, and IntegrityStatus updates. SystemAuditAuthority carries no business actor fields; actor_type is always "system". It is prohibited inside any business mutation path.

Economic Policy Governance Clarification

Economic policy evolution MUST occur by appending rows to the owning domain’s own table, each carrying the instant from which it governs (DOM-CLASS-003 §V, §VII).

The following are prohibited:

  • direct mutation of immutable historical policy rows,
  • hidden delayed economic mutation,
  • orphaned future economic state,
  • a separate transition or activation record standing in for the owning row.

Immediate economic policy changes and delayed economic policy changes are equally subject to lawful lineage requirements.

X. Rebuild Intent

This invariant exists to make unauthorized, hidden, or convenience-based database mutations visible and operationally embarrassing. Its goal is not to prevent all possible privileged compromise, but to ensure that any mutation outside the canonical execution path is detectable during the nightly chain walk and surfaces through the Operations status-signal pipeline as a degraded state.

This includes hidden future economic law, delayed policy mutation that is not a visible effective-dated row of the owning table, and constitutional economic state that bypasses canonical policy governance.

XI. Downstream Consequence

DOM-OPS-002 owns the schema, emission protocol, and verification logic that operationalizes this invariant.

FEAT execution contracts must call audit_protected() for every write to a protected table.

Protected economic policy tables are those DOM-OPS-002 §5.4 registers among the owning domains’ tables (DOM-CLASS-003 §V). The retired class-wide lineage tables are not among them.

CI guardrails in scripts/policy_guardrails.py enforce this structurally.

XII. Amendment

Revisions must preserve the distinction between UNVERIFIED and INVALID, the two-path lawful write model, and the HMAC key startup requirement.

Edit canonical source on GitHub

Last updated: 2026-10-14