Skip to content

audit: stratum.audit/verify-chain + IAuditable#24

Merged
whilo merged 1 commit into
mainfrom
feature/audit-chain
May 11, 2026
Merged

audit: stratum.audit/verify-chain + IAuditable#24
whilo merged 1 commit into
mainfrom
feature/audit-chain

Conversation

@whilo
Copy link
Copy Markdown
Member

@whilo whilo commented May 11, 2026

Summary

New stratum.audit namespace with the same protocol shape as datahike's audit, so bridges across repos pass results through without translation.

  • IAuditable protocol: -merkle-root (cheap, may return nil; never throws) and -recompute-merkle-root (returns a result map: {:status :ok|:mismatch|:unsupported, :root, :errors, :reason}).
  • verify-chain walks the dataset commit DAG from a branch HEAD, recomputes each dataset commit-id and each referenced index commit-id under :crypto-hash?, advisory-flags non-crypto-hashed indexes.
  • :deep? true walks every reachable column's PSS tree directly from konserve (bypassing CachedStorage LRUs), recomputes each node's address via cached-storage/gen-address, and surfaces any leaf/branch whose bytes no longer hash back to its address.
  • IAuditable extended for live PersistentColumnIndex and StratumDataset so callers can verify in-memory handles too.

Supporting change

cached-storage/attach-pss-handlers extracted so audit (and any other caller that needs to deserialize PSS nodes from a raw konserve store without standing up a full CachedStorage) can wire the Fressian read handlers up cheaply.

Companion datahike work

The matching datahike branch (feature/audit-chain on replikativ/datahike) lazily delegates its stratum-secondary -recompute-merkle-root into stratum.audit/-recompute-merkle-root when this lib is on the classpath; older stratum versions degrade to :unsupported :reason :stratum-audit-unavailable.

Test plan

  • clojure -M:repl then run stratum.audit-test — 12 tests / 35 assertions pass
  • Clean walk reports :ok
  • dataset-cid-recipe-coverage documents the layer-1 boundary (only fields hashed into the cid recipe are caught)
  • Tampering a cid-bearing field on a stored dataset commit → layer-1 :mismatch
  • Tampering a stored index commit → layer-1 :mismatch with the column flagged
  • Tampering a PSS leaf at the konserve store level → :deep? reports :mismatch with :audit/merkle-mismatch at the right address
  • Dataset without :crypto-hash?:advisory
  • verify-pss-tree-from-cold standalone helper: clean + tampered
  • IAuditable on live PersistentColumnIndex and StratumDataset

New stratum.audit namespace mirrors datahike's audit shape so bridges
can pass results through without translation:

- IAuditable protocol: -merkle-root (cheap, may return nil; never throws)
  and -recompute-merkle-root (returns a result map: :ok/:mismatch/
  :unsupported with :root and :errors).
- verify-chain walks the dataset commit DAG from a branch HEAD,
  recomputes each dataset commit-id and each referenced index commit-id
  under :crypto-hash?, reports advisory for non-crypto-hashed indexes.
- :deep? walks every reachable column's PSS tree directly from konserve
  (bypassing CachedStorage LRUs), recomputes each node's address via
  cached-storage/gen-address, and surfaces any leaf/branch whose bytes
  no longer hash back to its address.
- IAuditable extended for live PersistentColumnIndex and StratumDataset
  values so callers can verify in-memory handles too.

cached-storage: extracted attach-pss-handlers so audit (and any other
caller that needs to deserialize PSS nodes from a raw konserve store
without standing up a full CachedStorage) can wire the Fressian read
handlers up cheaply.

Tests cover clean walk, dataset-cid-recipe-coverage boundary, layer-1
mismatch on cid-bearing fields, layer-1 mismatch on index commits,
deep-walk leaf tampering, advisory mode without :crypto-hash?, the
verify-pss-tree-from-cold helper, and IAuditable on live values.

Signed-off-by: Christian Weilbach <christian@weilbach.name>
@whilo whilo merged commit 3f3df88 into main May 11, 2026
5 of 6 checks passed
@whilo whilo deleted the feature/audit-chain branch May 11, 2026 06:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant