feat(core): add the change ledger - #240
Merged
Merged
Conversation
Sessions store a message stream and snapshots capture file state, but neither answers what people ask after a run: what did it change, why, and how do I undo that one thing? A message log means reading a conversation; snapshots are addressable but carry no intent. The ledger is the index over both. Two timelines, not one file with a type column: `changes` is high-frequency workspace edits, `governance` is rare and high-impact. Interleaved, the second would never be seen again. Stored under ~/.deepcode/projects/<key>/ledger/, not in the repo. Selfware keeps its log inside the instance, which suits a document workspace; here it would append to a tracked file on every edit and fill `git status` with noise during the exact activity being reviewed. `deepcode ledger export` covers wanting it committed. One write point in the loop, after a tool succeeds. Per-tool writes are the shape AGENTS.md rules out — a new mutating tool would silently go unrecorded. Deliberately not recorded: reads (nothing to say about them, and the traffic buries mutations), failed and blocked calls (a ledger of things that did not happen is worse than none), and file contents (so it never becomes a second copy of a secret). Bash is recorded with no paths, since "the agent ran this" is what an audit needs even when the effects cannot be declared. Writes never fail a tool call — a completed edit is worth more than its bookkeeping. Retention ships with the writer rather than as a follow-up; a log that only grows is one somebody eventually deletes wholesale. rollbackHint is absent when no checkpoint was taken, rather than guessing. Adds `deepcode ledger <list|show|export>`. `list` reports how many records a --limit hid: a truncated list that reads as complete is how someone concludes the agent changed less than it did. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR 3 of
docs/FLOATBOAT_ADOPTION_PLAN.md§2.B — the plan's largest single capability gap. Independent of the file-contract PRs; nothing in the permission path reads it.Sessions store a message stream and snapshots capture file state, but neither answers what people ask after a run: what did it change, why, and how do I undo that one thing? The ledger is the index over both, pairing each mutation with the request that motivated it and the checkpoint that reverses it.
deepcode ledger list deepcode ledger show chg-lz4k2p-01 deepcode ledger export --out audit.mdDesign decisions worth reviewing
Two timelines, not one file with a type column.
changesis high-frequency edits;governanceis rare and high-impact (contract edits, plugin installs, trust grants). Interleaved, the second is never seen again.Stored outside the repo (
~/.deepcode/projects/<key>/ledger/). Selfware keeps its log inside the instance, which suits a document workspace — here it would append to a tracked file on every edit and fillgit statuswith noise during the exact activity being reviewed.exportcovers wanting it committed.One write point in the loop. Per-tool writes are the shape AGENTS.md rules out: a new mutating tool would silently go unrecorded.
rollbackHintis absent when no checkpoint was taken, rather than pointing somewhere plausible.Deliberately not recorded
Bashis recorded, with emptypaths— its effects can't be declared ahead of time, but "the agent ranrm -rf build" is exactly what an audit needs. The pre-Bash git checkpoint already taken is what makes it reversible.Two properties that are tested, not just intended
Bookkeeping can never cost a completed edit.
FileLedger.appendreturnsnullinstead of throwing, and the loop additionally catches a host-supplied sink that throws. Tested with a sink that throwsdisk full— the write still executes and the run still endsend_turn.Retention ships with the writer, not as a TODO. A log that only grows is one somebody eventually deletes wholesale, losing the recent records too. Newest 5000, nothing past 90 days, trimmed as records accumulate.
Test plan
pnpm test— 1317 passed, 16 skipped (+28: 883 core, 227 cli)pnpm typecheck·pnpm lint·pnpm format:check·pnpm build·node scripts/check-docs.mjsnull, not a throw; oversized summary truncated rather than dropped; corrupt lines skippedmaxRecordstrim;maxAgeDaystrim with an injected clock; no-op when in windownotebook_path; Bash with no paths; rollback hint present/absentDocumentation
docs/change-ledger.md— why it's separate from sessions, storage location and the reasoning, record shape, what is not recorded, failure behaviour, retention, and the not-an-authority ruleRelease notes label
release-notes:featureRelated
Plan §2.B (PR 3). Research:
docs/research/floatboat.md§4.4(2).ledger rollbacklands in PR 4 with the No Silent Apply ceremony.🤖 Generated with Claude Code