Your agent's sessions already know what to fix.

harness-ledger works with Claude Code, Codex and Cursor: it reads the transcripts your agent already saves, names the piece behind each problem, and checks whether the fix worked.

npx skills add guilhermebkel/harness-ledger -g
How harness-ledger works A tangle of session events converges into one line with three steps, read, map and suggest, then fans out to the pieces of your harness: AGENTS.md, skills, subagents and hooks. A dashed line returns to the start for the before and after comparison. $ npm test✕re-read src/app.tsyou: use pnpmpermission denied✕fix loop x4same request, 7th time AGENTS.mdskillssubagentshooks 1READparse transcripts 2MAPinventory harness 3SUGGESTclassify and cost 4 COMPARE before and after you accept a change How harness-ledger works A tangle of session events converges into one line with three steps, read, map and suggest, then fans out to AGENTS.md, skills, subagents and hooks. A dashed line returns to the start for the before and after comparison. $ npm test✕re-read src/app.tspermission denied✕fix loop x4 AGENTS.mdskillssubagentshooks 1READparse transcripts 2MAPinventory harness 3SUGGESTclassify and cost 4 COMPARE before and after

A report you can check line by line.

Each suggestion names the piece to change, what it cost, and the session and line that prove it.

Analyzed 41 sessions (last 30 days)3 suggestions

Enforce a rule that already exists

subagent: test-runner

Ran npm test 11 times in 6 of 41 sessions. The repo uses pnpm test, and AGENTS.md line 3 already says so.

Timeat least38 min
Tokens210k
Money$1.90

Counted from each failed npm test until pnpm test ran, reasoning included.

Proofsession 3f2a… line 14
session 91bc… line 7
+4 more
Fix
A hook that rewrites npm test to pnpm test in this repo, not more text.
ThenCompare test-runner after a few sessions to see if it stopped.
Illustrative output.

A script counts. Your agent judges.

Numbers have to be reproducible, so the model never estimates one. What the model adds is judgment: telling real friction from ordinary work and writing the fix.

Run it on the strongest reasoning model you have.

  1. 1

    Read

    local script

    Parses the session transcripts your agent already saves on your machine. Nothing to log, nothing to set up.

  2. 2

    Map

    local script

    Inventories the harness: the instructions file, skills, subagents, commands, hooks, MCP servers and plugins.

  3. 3

    Suggest

    your agent

    Groups signals by cause, separates real friction from ordinary work, classifies each finding and writes the change. The script supplies every number.

  4. 4

    Compare

    local script

    After you accept a change, later runs compare that piece before and after, in errors, corrections, time and cost.

Each finding gets a class. The class picks the fix.

Rule exists, but is ignoredThe instruction is there. The agent doesn't follow it.Enforce it with a script, hook or check.
Partial or outdated instructionIt exists but is incomplete, or contradicts the repo today.Fix the text in the right piece.
Missing instructionNothing in the harness covers it.Add it where it belongs.
Structure changeA pattern repeats across sessions.Turn it into a skill, subagent or script, or remove an unused piece.

More text is rarely the fix.

When a rule is already written and the agent ignores it, the answer is a hook or a check, not a longer prompt. The skill tells those cases apart.

Problems in a piece you don't control become recommendations. Findings already suggested, rejected or changed are listed, never repeated.

The signals it reads:

failed commandsfix loopswrong commandsrepeated file readssubagents re-readinguser correctionsrejected planspermission denialsrepeated requestsmanual proceduresheavy contextunused piecesoversized piecesAPI errors

Costs come with their limits.

Time, tokens and money are counted by a local script. The numbers are why you can trust a finding, so each one says what it is.

  • Each number says what kind it is.At least, at most or about: a lower bound, an upper bound or an estimate. Numbers of different kinds are never added together.
  • Each number says how often."11 times in 6 of 41 sessions", so one bad session doesn't pass for a habit.
  • They measure what was spent, not what you'll save.A saving is claimed only after a before and after comparison shows it.
  • Your agent's own figure sits beside the estimate.Claude Code records its cost per session. The report shows both and never sums them.
  • Thin evidence is marked partial.With the reason, instead of being rounded up into a finding.

Your sessions never leave your machine.

Read in place

Transcripts are read where they are, never copied, never sent. Only derived, redacted findings are stored, in .harness-ledger/ in your project.

Secrets stay out

Every string that can reach a report goes through redaction. Hooks and MCP servers are kept as names and shapes, never their commands, arguments or env values.

No telemetry

When the script meets something it can't map, the report offers a link to a prefilled GitHub issue holding only names and counts. You read it and decide whether to send it.

Your retention, untouched

Claude Code deletes transcripts older than 30 days by default; Codex and Cursor keep theirs. The skill tells you how much history you have and never changes that setting.

Claude CodeSupported
CodexSupported
CursorSupported

Questions

Does it change my harness?

Only if you ask it to, one suggestion at a time, with confirmation, and only in harness files: instructions, skills, subagents, commands, hooks and settings. Pieces from plugins or managed settings are never edited. Findings about them become recommendations.

How much history does it need?

It works from the first run, on whatever sessions you have. Patterns across sessions need a few sessions to show up, and before and after comparisons need a minimum on each side. Below that, the report says the evidence is partial instead of guessing.

How accurate are the costs?

They are estimates with a stated method. Time excludes idle gaps, tokens come from the transcripts, and money comes from a price table you can override in .harness-ledger/config.json. Each signal says whether its number is a lower bound, an upper bound or an estimate.

A finding looks wrong for my project. What do I do?

Reject it and it won't come back. If the rule behind it seems off, ask for a rule question: the script builds a prefilled issue with the signal and your own words, and nothing from your sessions.

Stop tuning your harness by feel.

Let your sessions show you.

npx skills add guilhermebkel/harness-ledger -g
/audit-harness

Open your agent in the project, pick its strongest reasoning model and run it. The installer asks which of your agents (Claude Code, Codex, Cursor) should get the skill. It runs the same way in all of them. It works on the sessions you already have. Requires Node.js 20+.

Star on GitHub