Skip to content

policy-fingerprint-order: fix X-12 - #43

Merged
kridaydave merged 2 commits into
mainfrom
fix/pr-19-policy-fingerprint-order
Nov 8, 2026
Merged

kridaydave merged 2 commits into
mainfrom
fix/pr-19-policy-fingerprint-order

Conversation

@kridaydave

Copy link
Copy Markdown
Contributor

Bugs

  • X-12: policy fingerprints disagree on list ordering (and field coverage), so semantically identical policies produce different keys across court/store/visibility

What was wrong

  • src/court.rs:187-211 (policy_key/push_list): sorted visibility lists before hashing, but only included private_paths, private_branches, embargo_until (not resign_key_id/embargo_recipients).
  • src/store.rs:1099-1108: export filter_key joined private_paths/private_branches in file order and omitted embargo_recipients, so reordering a no-op list changed the key and wiped the export cache.
  • src/visibility.rs:66-77 (audit_key): joined embargo_recipients/private_paths/private_branches in file order and omitted resign_key_id. Reordering private_paths (semantically a no-op) therefore changed store/audit fingerprints while the court key stayed identical.

Fix

  • Added VisibilityPolicy::canonical_fields() (and shared sorted list canonicalization) covering every visibility-policy field with list fields sorted, so semantically identical policies hash identically regardless of file order.
  • visibility::audit_key() now hashes canonical_fields().
  • court::policy_key() now includes all meaning-policy fields plus visibility.canonical_fields(), keeping list canonicalization and aligning visibility field coverage.
  • Store export filter_key now uses policy.canonical_fields() (with a comment explaining cache semantics).
  • Added regression tests: visibility::tests::test_visibility_fingerprint_canonicalizes_list_order and court::tests::test_policy_key_canonicalizes_list_order.

Persisted fingerprints / stored data: fingerprint format changes. The export cache marker (.oot/export/policy-key) will not match once and reset_export_cache_if_policy_changed triggers a safe full export rebuild, then writes the new canonical key. Persisted dockets and .oot/adjudications.jsonl keep their old policy_key values as append-only history; nothing validates or rejects old records, so reads remain fine but old/new key strings will differ (honest after the format/coverage fix).

Verification

CI green (fmt, clippy, tests, release build, adjudication) + the regression tests added (cargo fmt --all -- --check clean locally; no local build/test per swarm instructions)

@kridaydave kridaydave added the purging Batch purge: bug-fix swarm PRs label Nov 8, 2026
@kridaydave
kridaydave force-pushed the fix/pr-19-policy-fingerprint-order branch from ac6d2f7 to 049176e Compare November 8, 2026 18:07
…X-12)

Sort list fields and include every visibility-policy field in the canonical
fingerprint inputs so semantically identical policies (e.g. reordered
private_paths) produce the same key everywhere. Before, court sorted lists
but store filter keys and visibility audit keys joined in file order and
field coverage differed, so a no-op reorder wiped the export cache while the
court/docket policy key stayed unchanged.

Stored fingerprints change format: the export cache marker will mismatch once
and trigger a safe full rebuild; persisted dockets/adjudication log entries
keep their old keys as append-only history (no validation rejects them).
@kridaydave
kridaydave force-pushed the fix/pr-19-policy-fingerprint-order branch from e4b90c8 to c3130c1 Compare November 8, 2026 18:55
@kridaydave
kridaydave merged commit 85a9909 into main Nov 8, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

purging Batch purge: bug-fix swarm PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant