Skip to content

Back to the catalog

Tracekit: Tamper-Evident Intent-Reasoning-Action Auditing for Autonomous Coding Agents
arxiv.orgpaper

Tracekit: Tamper-Evident Intent-Reasoning-Action Auditing for Autonomous Coding Agents

Tracekit is an open-source, dependency-free system that logs three cross-checked channels (human intent, model self-reported reasoning, and actual executed actions) for autonomous coding agent sessions into a hash-chained, externally anchorable ledger, hooking into Claude Code's lifecycle events and reconstructing multi-agent hierarchies. The paper's experiments show the ledger detects all 1,600 tested tamper mutations (edits, deletions, reordering, forged inserts, torn writes) with anchoring needed to catch tail truncation/full re-chaining, that a regex-based tool-call gate blocks only 41% of harmful calls while over-blocking benign ones and is trivially evaded, that in 14 real Claude Code runs the agent never acted on 4 planted indirect prompt injections, and that an LLM reviewer catches 100% of seeded misaligned steps in traces versus 82% for rule-based flags. The authors release the system, harness, and all traces.

TL;DR A hash-chained, tamper-evident audit ledger for Claude Code agent sessions that catches every tested log tamper attempt and exposes how weak regex-based tool-call gating is against harmful commands and prompt injection.
Also seen from another angle🧠 AI →
Document

What it is

Tracekit (arXiv:2609.35659v1, Bravish Ghosh, Sept 2026) is ~2,000 lines of standard-library Python plus one HTML file, no third-party dependencies, that audits autonomous coding-agent sessions across three channels — human intent, model self-report, actual actions — into a hash-chained ledger. It hooks Claude Code lifecycle events; other agents join via an SDK or HTTP ingest API. The existing summary covers the design and top-line results, so what follows is the operational detail an operator needs to decide whether to deploy it: the overhead, the defaults, and the stated limits.

How it works

Each record is SHA-256(canon(record without hash)) with a prev link to the previous hash; canonicalisation is sorted-keys, no insignificant whitespace (a JCS subset). Secrets matching credential patterns are masked and long strings truncated (keeping a hash) before hashing, so the ledger never stores the secret. Appends take an exclusive lock, recover the last valid record by reading backwards (so a torn final line after a crash never restarts the chain from genesis), and fsync before releasing.

Anchoring is the load-bearing part. The chain alone catches in-place edits, deletes, reorders, forged inserts and torn writes — but tail truncation and full re-chaining pass chain verification in every trial and are caught only against an external anchor. Detection of a re-chaining attacker follows the closed form P_detect(k) = 1 − (k−1)/2N; at an anchoring interval of k=300 records detection falls to 0.47. Anchor tightly.

Preconditions / Affected

Threat model assumes the harness (Claude Code) faithfully invokes hooks and that at least one anchor (a ledger head hash) is stored where a log-tampering adversary cannot reach it. Tested with headless Claude Code claude -p version 2.1, Python 3.11.15.

Explicitly out of scope: an agent achieving its goal through side effects invisible at the tool-call level (e.g. a script silently opening a socket). That needs OS-level enforcement; Tracekit does not provide it.

What to do

  • Set TRACEKIT_FAIL_CLOSED=1. By default the hook fails open — on internal error or unreadable policy it exits 0 and the call proceeds (flagged policy_error). Only with FAIL_CLOSED=1 are such calls denied.
  • Keep the anchoring interval small given the 0.47-at-300 detection curve; treat the regex policy gate as a tripwire for honest mistakes, not a sandbox (it blocked only 18/44 harmful calls and is trivially evaded by rewrites).
  • Require the bearer token whenever the observer is exposed beyond localhost — every endpoint enforces it there.

Caveats

  • Reasoning text was unavailable in practice. The provider withheld all 27 thinking blocks in the real runs, so self-report was limited to visible prose — the "reasoning" channel is only as good as what the model surfaces outside hidden thinking.
  • Overhead is negligible: median hook 23.9 ms (24.6 ms at 100k records), ~2,436 records/s append with per-record fsync, chain stays correct under 16 concurrent writers — so cost is not a reason to decline, but none of that addresses the fail-open default or the missing reasoning text.
  • The LLM reviewer's 100% catch rate came with a false-positive rate of 1/14 on unmodified traces, and rests on seeded-fault splicing rather than naturally occurring misbehaviour.

Technologies named here

Techniques named here

  • Hash-chained tamper-evident ledger
  • External anchoring
  • Pre-execution policy gating
  • Indirect prompt injection
  • Seeded-fault splicing
  • LLM-based trace review