[FEATURE] Integrity protection for session history: resumed sessions silently accept edited transcripts
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
When I start claude, I assume the conversation the model works from is the one that actually happened. Today nothing guarantees that.
Session history lives in plain JSONL files under ~/.claude/projects/. Any process running as my user can edit them, and Claude Code loads the edited version on the next resume, fork or handover without a warning. The model then treats the edited content as its own past: instructions I never gave, tool results that never happened, harness messages that were never sent.
I tested this on Claude Code 2.1.286 (macOS). I created a short session with two Bash calls (echo ALPHA, then echo BETA), made four copies of the transcript and resumed each one with claude -p --resume:
| Copy | Edit | Result | Input tokens |
|---|---|---|---|
| control | none | resumes | 29,076 |
| gap | removed the ALPHA call and its result, parentUuid left dangling | resumes, no warning | 28,892 |
| relinked | same removal, chain repaired | resumes, no warning | 28,892 |
| half | removed only the ALPHA tool result | resumes, no warning | 28,892 |
Judging by the identical input token counts, Claude Code bridged the broken parentUuid chain and silently dropped the orphaned tool_use. The transcript has no checksum or signature over the history. Only thinking blocks carry a signature. Inserting entries should work the same way (not tested). The file also stores harness-rendered system content (renderedRole: "system"), so whoever writes to it could plant fake system reminders, not only fake user turns (inferred from the format, not tested).
The risk grows with autonomous use. In long multi-agent runs (an orchestrator plus workers, nobody watching the screen), all agents run as the same OS user and can write to each other's transcripts. One prompt-injected or misbehaving agent can rewrite another agent's history, and the user only sees the final summary. At scale, a single malicious dependency installed on many developer machines could do the same quietly.
Existing protection is partial. The auto-mode classifier blocks transcript tampering (#75874), but only in auto mode, and only by judging commands. Guards that match command text are easy to route around: in my test, a hook matching the ~/.claude path did not fire because the path sat inside a helper script.
Proposed Solution
Make history integrity the default and editing the opt-in, not the other way around.
- Signed receipt per response. The API returns a signature over a hash chain of the history so far (inputs, outputs, model). The public key is published, so anyone can verify the chain offline.
- Verify on every request. The client sends the latest receipt with the next request. The API recomputes the prefix hash and rejects a mismatch. This stays stateless, like thinking-block signatures, and it also catches edits to the in-memory history.
- Fail visibly on resume. A broken chain produces a clear warning or a hard stop, never a silent repair.
- Editing as an explicit step.
/compactand/rewindre-anchor through the API. Manual edits require an explicit opt-in flag (e.g.--allow-edited-history) and are marked in the transcript.
Alternative Solutions
- Local hash chain plus external anchor: A hook hashes each appended line into a chain and stores the head off the machine. This works today, but it only detects edits made after the fact, every user has to build it themselves, and it cannot prove what the model actually produced.
- OS-level sandbox: Limiting each agent to its own working directory prevents the attack but does not detect it, and it is not the default.
- Classifier rules: Helpful, but limited to auto mode and probabilistic.
Priority
High - Significant impact on productivity
Feature Category
API and model interactions
Use Case Example
I run long autonomous rollouts: an orchestrator session dispatches workers, workers report results, and sessions are resumed or forked for handovers. Today neither I nor the orchestrator can check that a worker's report, or the orchestrator's own resumed history, is what the model actually produced. With signed history, an edited session stops with a warning on resume, and I can trace "worker 3 reported PASS" back to a real, signed API response.
Additional Context
- Related but different: #101813 proposes a compatible mechanism (signed receipts), but for provenance of commits and PRs toward third parties after the session. This request is about the integrity of the agent's own context during the session. #48793 asked for attestation and was closed as stale. #78241 reports forged turns in a live session context.
- Known limits: Tool results and files that are read come from the local machine, so the provider cannot attest them. Truncating the tail of a history stays possible. Transcript entries that never reach the API stay unsigned.