Skip to main content
A policy snapshot is an immutable copy of the rules that governed a single decision, captured at evaluation time. Policies evolve — thresholds move, rules are added, conditions are refined — but a snapshot freezes the state that was actually in effect when MeshQu decided. That is what lets you answer “why was this approved, six months ago?” against the rules that applied then, not the rules that apply now.
Mental model: a policy is a living document with a version history; a snapshot is a photograph of the exact rules used for one decision. The decision pins the photograph, not the document.
This page is about the frozen rule state behind a decision. For the human-facing version lifecycle — drafts, maker-checker review, ratification, and the active-version model — see Policy Lifecycle. For how a decision replays against its snapshot, see Snapshot Pinning.

Why snapshots exist

Consider a policy that changes between a decision and an audit:
Without a frozen snapshot, re-evaluating against the current policy (v2) would wrongly return DENY, and the original decision would be unreproducible. The snapshot makes the Day-1 rules permanently available, so the decision is always explainable on its own terms.

What a snapshot binds

A snapshot is content-addressed: its identity is derived from the rules it contains, not from a sequential version number alone. Only behavioural rule fields are hashed: code, condition, severity, and when (when present). Documentation-style metadata — a rule’s name, description, or source_ref — is deliberately excluded, so editing a rule’s prose does not invalidate receipts that reference the snapshot. Inactive rules are excluded entirely.
Two rule sets that differ only in their when clauses hash differently — conditional applicability is behaviour, so it is bound. Two that differ only in a description hash the same — prose is not behaviour.

Content addressing and deduplication

Because identity is derived from content, identical rules produce an identical hash. If a later policy version reverts to a previously-seen rule set, MeshQu reuses the existing snapshot rather than storing a duplicate:
The snapshot hash binds both the rule content and the policy-version attribution it was derived from. That distinction matters for audit: reverting to byte-identical rules on a different policy version still yields a distinguishable snapshot, so the version lineage of every decision is preserved rather than collapsed.
Use both identifiers for what each is good at. The version number (“this used policy v3”) is human-readable lineage. The snapshot hash is content-addressable, tamper-evident proof that the rules weren’t altered after the fact. MeshQu keeps both on every decision.

Immutability

Snapshots are written once and never modified. This is enforced at two layers:
  • By construction — a snapshot is created via a find-or-create path. If a matching snapshot already exists for the tenant, it is reused; otherwise a new one is written. Existing rows are never updated.
  • At the database — an immutability trigger rejects every UPDATE and DELETE on the snapshot table. A privileged operator cannot silently rewrite a snapshot’s rules.
This guarantees three properties auditors rely on:
If you need to change the rules a policy enforces, create a new policy version — never attempt to alter an existing snapshot. A snapshot is a record of what was decided, not a place to store what you want to decide next. See Policy Lifecycle.

Snapshot, version, and policy

Three layers, different mutability:

Snapshots in the receipt

In v2 receipts, the snapshot is bound into the cryptographic proof two ways:
  • policy_snapshot_id — the UUID, identifying which snapshot.
  • policy_snapshot_digestsha256(canonicalJson({ id, rules, policy_versions, created_at })), binding the full snapshot content, not just its UUID. Approval-receipt lineage is carried transitively through this digest.
A v1 receipt binds the snapshot by policy_snapshot_id and evaluated_rules_hash; the full content-digest binding is the v2 addition. Both verify forever. See the Receipt Reference for the exact payloads.

See also