{
  "markdown": "# logbook\n\n[![ci](https://github.com/promptwheel-ai/logbook/actions/workflows/ci.yml/badge.svg)](https://github.com/promptwheel-ai/logbook/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/%40promptwheel%2Flogbook)](https://www.npmjs.com/package/@promptwheel/logbook)\n\n**Coding agents often skip git history. It is large, and an arbitrary slice\ncan give the wrong picture.**\n\nEvery feature gets added by someone who can read the code but not the\ndecisions behind it: the module that was rewritten three times, the approach\nthat was tried and reverted, the \"fix\" last quarter that was actually a\nskipped test. Fresh agent sessions often start without those decisions. Code\nmaps (Graphify and friends) tell them where things are, not what happened. The\nlogbook mines the existing git history — up to the newest 20,000 commits — and\nwrites a compact recall layer that your agent is instructed to consult.\n\n```\nnpx -y @promptwheel/logbook init\n```\n\nOne line: it reads the history, writes the brief, and adds a history workflow to\nyour agent config (AGENTS.md, CLAUDE.md, or .cursorrules).\n\n```\n  1,326 commits · 322 files · 7.3 years · 354 authors\n\n  ✓ wrote LOGBOOK.md     hotspots · do-not-retry · suppression ledger\n  ✓ wrote events.jsonl   1,326 structured events\n  ✓ wrote JOURNEY.md     the repo's story, told back to you\n```\n\n![logbook running on zustand: files written, then the colorized journey and Almanac](https://raw.githubusercontent.com/promptwheel-ai/logbook/master/logbook-journey.gif)\n\nSingle file. Zero npm dependencies. It never touches your source code or\ngit history, and no repository data leaves your machine — it writes only\nits own brief files (and `init` adds a block to your agent config).\n\n## Why \"logbook\"\n\nBecause you need a compact index of the decisions its detectors can recover\nwithout pulling every book out of the library. In a random 400-repo sample of\nthe top 2,500 GitHub repositories, 34% of full logs exceeded a 150k-token\ncontext estimate. Logbook turns that record into a bounded brief and\nverifiable leads; it does not claim complete decision recall.\n\n## The three artifacts\n\n| File | What it is | Who it's for |\n|---|---|---|\n| `LOGBOOK.md` | The brief a fresh session needs: hotspots, **do-not-retry** (reverted approaches), the **suppression ledger** (the times a test was skipped or a warning hushed), assertion-weakening events, fragile areas | Your agent. Drop it in context — `CLAUDE.md` can point at it |\n| `events.jsonl` | One structured event per analyzed commit: shape (src/test/config/docs), adds/dels, suppressions found in the diff, assertion deltas | Your tools. The data layer |\n| `JOURNEY.md` | Your repo's history as a hero's journey: The Call, The Threshold, The Abyss, The Long Winter, the Whispered Bargains | You. Run `logbook journey` to see it in color |\n\n## Usage\n\n```bash\nnpx @promptwheel/logbook              # analyze the current repo\nnpx @promptwheel/logbook path/to/repo # or any repo\nnpx @promptwheel/logbook journey      # the story, in color (writes nothing)\nnpx @promptwheel/logbook journey --compare  # rank your almanac vs the top 2,500 GitHub repos\nnpx @promptwheel/logbook audit        # what is STILL suppressed in HEAD, and since when\nnpx @promptwheel/logbook doctor       # read-only artifact/wiring/skill/query health check\nnpx @promptwheel/logbook context --file path/to/file --revert  # bounded, paged query view\nnpx @promptwheel/logbook context --file src/a.ts --file src/b.ts # multi-path OR query\nnpx @promptwheel/logbook annotate SHA \"why it happened\" --by WHO   # persist WHY a commit happened\nnpx @promptwheel/logbook --json       # events to stdout (writes nothing)\n\n# era-scoped archaeology\nnpx @promptwheel/logbook --since 2024-01-01 --until 2025-01-01\n```\n\nOptions: `-n/--max N` (commit cap, default 20000) · `--compare` · `--out DIR` · `-q/--quiet`\n\n`context` preserves the filtered `query` order but serializes it into pages of\nat most 20 events and 8 KiB, with an opaque `NEXT` cursor and explicit\n`END complete`. It is a delivery format, not relevance ranking; use `query`\nwhen you need the raw JSONL interface. A cursor is bound to the repository\nHEAD, filters, analysis window, and ordered event set; if any changes, restart\nfrom the first page. Repeat `--file` to match commits touching any supplied\npath; remaining filters still combine with that union. Repeat the same filters\nwith every `NEXT` cursor. On a default-window cold run, the CLI creates or refreshes\n`events.jsonl` after page one so `NEXT` pages reuse the scan; it never changes\nsource or Git history. Non-default `-n` or `--since`/`--until` windows remain\nuncached, so each CLI page rescans that explicit window. Across 7,123 measured\nevents, the 0.8 representation used 72.7% fewer bytes than the raw rows\n([method and scope](docs/context-format.md)).\n\n## The ledger is batched\n\nThe expensive part (scanning 20k commits of diffs) runs once, in bounded\nwindows, and every consumer reuses it: if `events.jsonl` is present and\nmatches HEAD it is loaded instantly; if new commits landed, only they are\nscanned and merged. Measured on a 20k-commit repo: 43s cold, 0.4s with a\nprior run on disk, 4ms on repeat calls in an MCP session. Escape hatches:\n`LOGBOOK_NO_CACHE=1` forces a full rebuild; `LOGBOOK_WINDOW=N` tunes the\nscan window.\n\n`--compare` uses a percentile table baked into the CLI from a 2,500-repo fleet\nrun — still zero dependencies and zero network calls.\n\n## Trust and diagnostics\n\nGit subjects, paths, authors, and annotations are repository-controlled input.\nLogbook stores the event record unchanged, but sanitizes those values when it\nrenders Markdown or agent-facing audit output and labels the result as untrusted\nevidence. Generated files are replaced atomically one at a time; the two\nMarkdown artifacts carry matching HEAD, event-count, scope, and ledger-hash\nrecords that bind `events.jsonl`. A multi-file refresh is not transactional, so\nan interrupted bundle is detected on the next check.\n\nRun the read-only doctor when a report looks stale or when filing a bug:\n\n```bash\nnpx -y @promptwheel/logbook@latest doctor\n```\n\nIt checks generated-record freshness and ledger integrity, current agent wiring\n(including a shadowing `AGENTS.override.md`), an installed Logbook skill, and a\nreal path query. It does not separately hash user edits to the Markdown prose.\nIt writes nothing, returns nonzero on a failed check, and prints a compact report\nsuitable for pasting into an issue or launch-thread reply.\n\n## Wire it into your agent\n\n`logbook init` does this for you. Manually, it's one block in your\nCLAUDE.md (or AGENTS.md / .cursorrules) so every fresh session is instructed\nto read the history first:\n\n```markdown\n## Repo memory\nBefore planning or editing:\n1. Read LOGBOOK.md at the repo root completely before any history query.\n2. If Historical signal is LOW, use it only as a hotspot map. Otherwise,\n   inspect task-relevant do-not-retry entries and fragile areas.\n3. For complete do-not-retry coverage, inspect all relevant paths:\n   npx -y @promptwheel/logbook context --file path/to/file --revert\n   Repeat --file for each other relevant path. If output says NEXT, repeat the\n   identical filters with --cursor TOKEN until END complete before concluding.\n4. Treat findings as leads, not verdicts. Verify claims with git show SHA and\n   confirm that the constraint still applies to the current tree.\nRefresh the record: npx -y @promptwheel/logbook\nCheck what is still silenced: npx -y @promptwheel/logbook audit\nWhen you investigate WHY a listed commit happened and verify it in the\ndiffs, persist it (replace SHA, the sentence, and MODEL with your own\nmodel name; never annotate guesses):\nnpx -y @promptwheel/logbook annotate SHA \"one specific sentence\" --by MODEL\n```\n\nWiring installs the history workflow instead of relying on the agent to invent\nit. It is still an instruction, not a guarantee; observed consultation remains\nimperfect, so confirm it for high-risk work.\n\n## Lazy enrichment: the record says WHAT, your agent persists WHY\n\nThe ledger can tell you a refactor was reverted; it can't tell you it was\nreverted because webpack4 broke. Your agent figures that out anyway the\nfirst time a task collides with the revert — `annotate` keeps the finding\ninstead of discarding it at session end:\n\n```bash\nlogbook annotate c08adc2 \"WeakMap cache added to dodge a React-Compiler lint warning; reverted to direct ref mutation\" --by claude\n```\n\nLOGBOOK.md is updated immediately (a later session that finds fresh\nartifacts on disk may never re-run the CLI), and the do-not-retry entry\ncarries the why:\n\n```\n- 2024-09-15 c08adc2 revert useShallow refactor in #2701 (#2703)\n  - why (inferred by claude, 2026-07-11): WeakMap cache added to dodge a React-Compiler lint warning; reverted to direct ref mutation\n```\n\nAnnotations live in `annotations.jsonl` — sha-keyed (immutable, so they\nnever go stale as facts), attributed, dated, last write per commit wins.\nThey are **judgments layered on the record, never mixed into it**: the\ndeterministic ledger stays untouched, the whys render with provenance and\na disclaimer. Measured on the A/B benchmark: an agent whose logbook carried\nthe whys stated real failure causes as design constraints at plan time\n(+2% read tokens), where the un-enriched agent planned an investigation —\nand, on zustand, guessed the cause wrong. One caution: annotations age as\nconstraints even though they never invalidate as facts — a \"broke webpack4\"\nreason stops binding once webpack4 is dead, so the date is always shown.\nCommit the file for a shared team memory, or gitignore it for a private one.\n\n## The audit: archaeology becomes a to-do list\n\n`logbook audit` joins the ledger's dates with what is still true in HEAD:\n\n```\n  describe.skip  test/express.static.js:137  since 2019-05-02 (7.2y)\n\n  1 live suppression · oldest 7.2 years\n```\n\nThat is express, today: its static-file test suite has been skipped for\nseven years. The ledger tells you when it happened; the audit tells you it\nis still happening. And when a suppression has been removed and RE-added,\nthe audit shows the fight log: `re-silenced ×3 (+-++--+)` — a test someone\nkeeps trying to fix, and keeps losing to.\n\n## Context economics\n\nIn a random 400-repo sample of the top 2,500, the median LOGBOOK.md was\n**~1,000 estimated tokens**. The sample's median full `git log` was 82× that,\nand 34% exceeded a 150k-token estimate. This is potential context avoided only\nwhen a session would otherwise ingest raw history:\n[docs/context-economics.md](docs/context-economics.md).\n\n## Does it actually change agent behavior?\n\nOn selected history-dense planning tasks, yes—with an important boundary. In a\nlater screen of ten new, less history-selected tasks, the packaged Logbook arm\ndid not beat strong raw-Git instructions (2/10 safe plans versus 3/10). Every\nknown receipt was indexed, but none reached the agents through Logbook queries,\nidentifying retrieval and consumption as the bottleneck. See the evidence-status\nnote in [docs/wrong-work-benchmark.md](docs/wrong-work-benchmark.md). In the\noriginal A/B test, an agent asked to plan a `useShallow`\nrefactor in zustand walked straight into re-attempting a refactor that was\nmerged and reverted in 2024. The same agent with LOGBOOK.md in context\nstarted from the revert, inferred the repo's characteristic failure class\nfrom the do-not-retry list, and planned to pin the old failure with a test\nfirst. Full transcripts: [docs/does-it-change-agent-behavior.md](docs/does-it-change-agent-behavior.md).\n\nIn a six-task internal experiment across deliberately history-dense planning\ntasks, agents without supplied history proposed already-reverted or completed\nwork in 4 of 6 tasks; agents supplied the full generated LOGBOOK.md did so in\n0 of 6, for about +4.7k tokens of context. This was planning-only, internally\ngraded, and selected for historical landmines. Method and scope:\n[docs/wrong-work-benchmark.md](docs/wrong-work-benchmark.md).\n\n## Honest scope\n\n- Findings are **leads, not verdicts**. A suppression commit means \"a human\n  should look here,\" not misconduct. Large assertion removals are usually\n  feature deletions — they're tagged as such.\n- Detection is regex over commit subjects and diffs (lineage: a calibrated\n  classifier from a 1,800-PR study of agent-authored code). It will miss\n  clever evasions and flag some innocents. That's the right trade for a\n  zero-dependency tool that runs in seconds — and it's a deliberate division\n  of labor: the logbook is the cheap, deterministic recall layer; the agent\n  reading it is the precision layer that triages leads against the task.\n- It reads what survived. Squash and rebase erase in-branch attempts (a\n  tried-then-reverted change nets to zero in the squashed diff), and\n  uncommitted experiments were never visible at all. The logbook\n  complements an agent journaling during the work — `annotate` is the\n  bridge for exactly that — it does not replace it.\n- Shallow clones starve the analysis — the logbook will tell you to\n  `git fetch --unshallow`.\n\n## The logbook records; the referee judges\n\nThis tool is one half of a pair. The logbook tells you a test was skipped\nin March. [promptwheel](https://github.com/promptwheel-ai/promptwheel) — the\nreferee — proves whether today's \"win\" came from the code or from editing the\ntests. Past tense and present tense of the same question: *did this actually\nimprove?*\n\nMIT.\n",
  "bytes": 13437,
  "sha": "37fc78f0280e312506b72b4b79f25e532fea7974a1655f740b98356e725836ea",
  "repo_slug": "promptwheel-ai/logbook",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_promptwheel_ai_logbook_09196ab4/readme"
}