Ledger records what your coding agents write, and why.

Point at any line or function, months later, and see which agent and model wrote it, in which session, and the prompt that asked for it. Nothing leaves your machine until you choose to share it.

Ledgeryour-project / app/views.pyai · claude-code
app/views.pyline 9 of 9
  1. 1from django.http import JsonResponse
  2. 2
  3. 3
  4. 4def health(request):
  5. 5 return JsonResponse({"status": "ok", "version": 1})
  6. 6
  7. 7
  8. 8def ready(request):
  9. 9 return JsonResponse({"ready": True})
Answerlothal-ledger why
$ lothal-ledger why app/views.py:9
app/views.py:9  ai  (commit 29160534d20e Add health and ready views; local)
        return JsonResponse({"ready": True})
model: claude-opus-5-5
wrote s_f6f5dfd133f5b2::t_d3f4a8f83bd286
  claude-code session 49717cb1-d669-4c1d-80e9-82ecff0cf51b (ended, 2026-10-19T17:49:56Z – 2026-10-19T17:50:23Z)
    call PostToolUse Bash toolu_01ETwMvNiV98c8hUrGrDHeGC at 2026-10-19T17:49:59Z
    turn 384c973a-80af-4e66-9001-33db75053bb3 (event) started 2026-10-19T17:49:57Z
      prompt: Run exactly this one shell command and nothing else. Do not use a file-editing tool and do not commit:
              
              printf '\n\ndef ready(request):\n    return JsonResponse({"ready": True})\n' >> app/views.py
commit sessions:
  claude-code 49717cb1-d669-4c1d-80e9-82ecff0cf51b
  claude-code 8cde7826-34b3-4e13-bfe1-f265da012fde
Ledger · whyLine 9 came from a shell command Claude Code ran, not from its edit tool, and Ledger still names the session, turn, model and prompt. A recorded session of our fixture repository, its prompts scripted; the answer is copied from the terminal.

How Ledger works

  1. 01

    It records as your agents work

    Claude Code, Codex, Cursor and omp run as before. Ledger notes every file an agent writes, with its session, turn, model and prompt, in milliseconds and without ever blocking the agent or a commit.

  2. 02

    Ask who wrote a line, and why

    Point at a line or a whole function, today or next year. The answer follows the code through commits, rebases and renames, and a line no agent wrote says so instead of guessing.

  3. 03

    Your agents can ask too

    Ledger is an MCP server in each agent. Before it changes code, an agent can call why and search, and leave its reasoning behind with record_decision.

  4. 04

    Share it with your team

    Team sync needs an account: lothal-ledger login signs you in. What you record from then on is shared, prompts redacted on your machine first, and a teammate's why answers for lines written on your machine.

Get started

From install to a first answer in a minute.

No account and no root. Ubuntu on x86_64; macOS on Apple silicon is built and smoke-tested.

curl -fsSL https://github.com/Lothal-App/lothal-ledger-releases/releases/latest/download/lothal-ledger-installer.sh | sh

Then open a new shell, or source the env file the installer names.

  1. 01

    Turn it on

    In the repository you work in: hooks for every agent it finds, and git hooks in free slots only.

    cd ~/src/your-project
    lothal-ledger enable
  2. 02

    Work as usual

    Use your agent, then commit. Amends, rebases and squash merges keep the record.

    claude   # or codex, cursor-agent, omp
    git commit -am "Add retry budget"
  3. 03

    Ask

    Any line, or a function by name. blame, sessions and search read the same record.

    lothal-ledger why src/http.py:42
    lothal-ledger why src/http.py:fetch
Privacy

Your machine first.

Nothing leaves without an account

Until you sign in, Ledger works only on your computer: the record is a local database and nothing is sent anywhere. lothal-ledger disable removes everything enable installed.

Prompts are redacted before they leave

When you share, prompts and context are redacted on your machine first. Teammates see which agent wrote a line; they read your prompt only with a content grant, and each such read is logged.

Agents are recorded, people are not

Ledger notes what an agent writes, never a person typing. A line no agent wrote reads unattributed, never someone's name.