esc-ledger is a small, dependency-free Python 3.10+ CLI that mines coding-agent transcripts for user interruptions, clusters recurring corrections, and measures whether a rule written later actually reduced recurrence. An interruption is a high-signal correction: the user stopped the turn rather than waiting for it to finish.
The project fills four gaps left by existing correction-capture tools such as claude-reflect: Esc events are weighted as signal, recurrence after a rule is measured, Claude and Codex transcripts share one ledger, and generated rules use negative constraints. The phrasing follows the finding cited by arXiv:2604.11088: useful agent rules are safer when expressed as a prohibition with a concrete precondition.
pipx install .
Runtime code uses only the Python standard library. Install pytest separately for development.
Scan the two local transcript stores. The scanner keeps raw text in memory only; JSONL contains text_redacted and never the raw text field.
esc-ledger scan --source all --since 2026-09-01 --out ledger.jsonl
# wrote 123 redacted records to ledger.jsonl
Cluster deterministically, with CJK character n-grams and English word tokens:
esc-ledger cluster ledger.jsonl --out clusters.json
# wrote 8 clusters to clusters.json
Measure recurrence against dated Markdown rules. Rules can be a file or a directory; dates come from YAML frontmatter (metadata.modified or date), a filename date, or the first heading.
esc-ledger recurrence --rules ~/.claude/projects/<project>/memory ledger.jsonl
Emit negative-constraint templates. Add --llm to use an OpenAI-compatible endpoint configured only by ESC_LEDGER_BASE_URL, ESC_LEDGER_API_KEY, and ESC_LEDGER_MODEL; requests use urllib and a 30-second timeout.
esc-ledger rules clusters.json
Write a readable Markdown summary:
esc-ledger report ledger.jsonl clusters.json --rules ~/.claude/projects/<project>/memory --out REPORT.md
| Source | Default path | Interrupt event | Follow-up extraction |
|---|---|---|---|
| Claude Code | ~/.claude/projects/**/*.jsonl |
user text containing [Request interrupted by user |
next valid user text within three user turns; slash commands and XML-like tags are skipped |
| Codex | ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl |
event_msg whose payload.type is turn_aborted and reason is interrupted |
next response_item.payload.item.role=user text, reading content[].type=input_text |
The Codex format was checked on 2026-10-22. A redacted example of the event line shape is:
{"timestamp":"2026-10-03T11:34:08.214Z","type":"event_msg","payload":{"type":"turn_aborted","turn_id":"…","reason":"interrupted","started_at":0,"completed_at":0,"duration_ms":0}}Everything runs locally. Before a record is written, redact.py masks values after password/token/secret/key words (including 密码, 口令, 密钥), digit runs of six or more, email addresses, phone numbers, and URLs. The CLI never uploads transcripts. The optional --llm command is the sole network-capable path and is opt-in; it sends only already-redacted cluster data to the endpoint you provide.
- Kimi and Antigravity transcript adapters.
- Hook mode for recording interruptions as they happen.
- Better rule attribution when a rule uses a synonym rather than a seed-lexicon keyword.
If this project saved you time, you can buy the author a coffee in crypto. Thank you! 如果这个项目帮到了你,欢迎用加密货币打赏支持,谢谢!
| Network | Asset | Address |
|---|---|---|
| TRON (TRC20) | USDT | TNGdTwE6opH6rmUyoG1JUR7FSyEb4k273R |
| Ethereum / BNB Chain / Polygon | USDT | 0x59c43144a862b351fa1086ae842d1327c9d91613 |
| Ethereum / Arbitrum / Base | ETH | 0x59c43144a862b351fa1086ae842d1327c9d91613 |
| Bitcoin | BTC | 1RS6tWXHregLfEsiPzVUCUBuhgDg5uTSV |
| Solana | USDT | HZguEXfTtLChNdJTxAYCbcGscaqikz8JYrEpUhEyeVd9 |
Please send only the listed asset on the listed network — other tokens or networks may be lost. 请按表中对应的网络转对应的币种,转错币种或网络可能无法找回。
Built by tommyapi.com