Skip to content

[RELEASE] tamper-evident hash chain (carries #2210)#2212

Merged
vivekchand merged 1 commit into
mainfrom
release/hash-chain-2210
May 28, 2026
Merged

[RELEASE] tamper-evident hash chain (carries #2210)#2212
vivekchand merged 1 commit into
mainfrom
release/hash-chain-2210

Conversation

@vivekchand
Copy link
Copy Markdown
Owner

Releases #2210 (closes #2200) to PyPI.

Summary

The feature already on main from #2210:

  • clawmetry/local_store.py — new chain_prev_hash / chain_hash columns on events (added via the existing _MIGRATIONS_V2 pattern, so existing stores upgrade cleanly), new chain_heads tracking table for per-node head hashes, _stamp_integrity() runs inside the same flush transaction as the row insert so hashes land atomically, and verify_integrity(node_id=None) walks the chain returning VALID or the first broken link.
  • clawmetry/cli.pyclawmetry verify-integrity [--node-id ID] subcommand (read-only store open; prints scope, checked count, pre-chain count, and result).
  • tests/test_integrity_hash_chain.py — 10 unit tests: genesis hash, sequential chain links, per-node scoping, pre-chain counting, tamper detection on each immutable field, and the critical acceptance test that a real backfill_event_costs does NOT invalidate the chain.

Why this design

events rows get mutable columns written post-insert: cost_usd and token_count (cost-backfill at local_store.py:3901) and even data itself (local_store.py:3980). A naive whole-row chain would break on every normal backfill and be useless for audit.

So the chain hashes only the immutable identity fields: id, agent_type, node_id, agent_id, session_id, workspace_id, event_type, ts. Those are set at ingest and never touched afterward. The chain detects deletion, reordering, and any tamper to identity fields. Swapping a row's data payload while keeping its identity intact is intentionally outside the chain's coverage (because data is mutable); a separate append-only audit artifact is the right follow-up if that becomes a buyer ask.

Done bar (FLYWHEEL)

  • Feature merged to main (feat(integrity): tamper-evident hash chain for event audit log (#2200) #2210 sha 5e59bb1e).
  • CI 23-check matrix green on the feature PR.
  • CHANGELOG entry under [Unreleased] (this PR).
  • release-on-merge.yml bumps the version + publishes to PyPI on merge.
  • Verify the new wheel is installable and clawmetry verify-integrity prints VALID against a live store (post-PyPI propagation).

No cloud bump

Daemon-side only. The hash columns ride the snapshot like any other event column; the cloud renders them as-is. No cm-cloud-* interceptor or route-policy entry needed for this release.

🤖 Generated with Claude Code

CHANGELOG entry for the per-node SHA-256 hash chain that landed in
#2210 (closes #2200). Off by default via CLAWMETRY_INTEGRITY=1; new
`clawmetry verify-integrity` CLI walks the chain and reports VALID or
the first broken link.

Hashes only immutable identity fields (id, agent_type, node_id,
agent_id, session_id, workspace_id, event_type, ts) so cost-backfill
and other post-insert enrichers do not invalidate the chain.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vivekchand vivekchand added the persona-skip Persona-pass cron skips this PR (backend-only, infra, or manually approved) label May 28, 2026
@vivekchand vivekchand merged commit 3332915 into main May 28, 2026
18 checks passed
@vivekchand vivekchand deleted the release/hash-chain-2210 branch May 28, 2026 07:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

persona-skip Persona-pass cron skips this PR (backend-only, infra, or manually approved)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: tamper-evident hash chain for event integrity (audit log)

1 participant