Methods notebook · Anya · 2026 · the loop-closing branch
Teaching an agent to read its own logs
Systemoffline map-reduce trawl over an agent's own session transcripts → a rewritten lean CLAUDE.md, rules promoted from evidence rather than memory
StatusPhase 1 shipped (single-summarizer, bias-screened) · Phase 2 multi-model panel designed & deferred · human-in-the-loop by design
Sourceproject_claudemd_aggregation.md · the live CLAUDE.md · tools/trawl/

Human memory over-weights the dramatic incident and forgets the papercut that happened twelve times. The fix is the one you'd apply to any measurement problem: stop guessing and mine the record. A coding agent leaves an extraordinarily complete one — so this is the project that reads it back to itself.

§0The problem with writing your own rules from memory

An AI coding agent works better when it carries a file of behavioural rules: "surface a plan before editing," "don't relaunch a failed agent without asking," "this Mac has no python, use python3." The first version of mine was written the obvious way. I sat down with the agent and we wrote the rules from intuition, from what felt like the recurring friction.

Human memory is a poor aggregator of recurring friction. You remember the dramatic incident and forget the papercut that happened twelve times, so rules written from memory over-weight the memorable and miss the chronic. It's a sampling failure more than a human one: people and models both miss long-tail patterns spread thin across many sessions, because no single session feels significant enough to encode. And a coding agent leaves an extraordinarily complete record — every session is a full transcript, and a separate pipeline was already summarizing them. The raw material for evidence-based rules was sitting in ~/.claude/ the whole time.

The shape of the result: an offline, map-reduce trawl over the agent's own logs that surfaces recurring friction with confidence tiers, and promotes the real patterns into the rules it runs on next session. A self-improving memory loop, with a human holding the final pen.

§1Two corpora, because they catch different things

The trawl reads two independent records of the same sessions, because they fail differently:

Reading both matters because the opinionated summaries surface friction the factual ones can't see (a model flags "the agent moved too fast" where the compaction record just lists what got done), while the factual ones anchor the opinionated ones (a friction claim is worth more when a verbatim user interruption backs it). interpretation Triangulation is the method.

§2Why map-reduce, and why map must not judge

A hundred-plus summaries is, worst case, north of 800k tokens: you cannot read it in one context, and more importantly you shouldn't, since aggregating findings across a giant context is exactly where long-context attention degrades. Many small readers, each given a clean batch, beat one model squinting at the whole pile. So the architecture is deliberately split:

The non-obvious constraint is why map must not tier: a pattern that shows up once per batch across six batches looks single-incident to every map agent. Only the post-aggregation global view sees that it recurred. observation Tiering before aggregation structurally cannot work — so it's forbidden at the map step.

↳ one-way gates annotated: map: no tiering · an LLM never hand-transcribes a UUID (see §4)

The pipeline An architecture diagram of the map-reduce pipeline: two corpora feed a row of parallel map agents that emit flat observations, a mechanical reduce step clusters them and counts how many distinct sessions each cluster spans, and a final human-plus-agent judgment step assigns confidence tiers and writes rules into the memory file. One-way gates carry the discipline — map never tiers, and an LLM never hand-transcribes a UUID. The pipeline — map-reduce over an agent's own session logs Many small readers on clean batches beat one model squinting at 800k tokens. Judgment lives only at the end. CORPUS model summaries opinionated · biased compaction summaries factual · neutral MAP ×N parallel batch 1 → observations batch 2 → observations … ~30 summaries each ⊘ no tiering · no cross-session claims REDUCE · mechanical cluster similar observations count distinct sessions / cluster an LLM never hand-copies a UUID REDUCE · judgment human + agent assign tiers bias-screen draft rules the only step allowed to judge MEMORY CLAUDE.md + memory The non-obvious constraint: map must not tier. A pattern that appears once per batch across six batches looks single-incident to every map agent — only the post-aggregation global view sees it recurred. Tiering before aggregation structurally cannot work, so it is forbidden at the map step. And frequency is never trusted on its own: any high-count cluster matching the summarizer's known bias profile is disqualified until transcript-verified. User-action signals stay trusted regardless of who surfaced them.
The pipeline An architecture diagram of the map-reduce pipeline: two corpora feed a row of parallel map agents that emit flat observations, a mechanical reduce step clusters them and counts how many distinct sessions each cluster spans, and a final human-plus-agent judgment step assigns confidence tiers and writes rules into the memory file. One-way gates carry the discipline — map never tiers, and an LLM never hand-transcribes a UUID. The pipeline — map-reduce over your own session logs Many small readers beat one squinting at 800k tokens. CORPUS model summaries opinionated · biased compaction summaries factual · neutral MAP ×N parallel each agent reads ~30 summaries → flat observations ⊘ no tiering · no cross-session claims REDUCE · mechanical cluster similar · count distinct sessions an LLM never hand-copies a UUID REDUCE · judgment human + agent: tier · bias-screen · draft the only step allowed to judge CLAUDE.md + memory Map must not tier: a pattern seen once per batch across six batches looks single-incident to every map agent — only the global view sees it recurred. So tiering is forbidden at map. And frequency is never trusted alone: a high- count cluster matching the summarizer's bias is disqualified until transcript-verified. User- action signals stay trusted regardless.
Fig 1 — the pipeline. Two corpora — opinionated model summaries and factual compaction summaries — feed a row of parallel map agents that each read one ~30-summary batch and emit flat observations. A mechanical reduce step clusters the observations and counts how many distinct sessions each cluster spans. A final human-plus-agent judgment step assigns confidence tiers and writes the rules into the agent's memory file. The one-way gates carry the discipline: map never tiers, and an LLM never hand-transcribes a UUID.
structure map-reduce with a split (mechanical / judgment) reducetype architecture diagramsafety flow reads off left-to-right structure, not colour

§3The confidence discipline (the part that's actually the point)

Frequency is not evidence. This is the crux, and where the project stops being a log-grep and starts being eval methodology.

The tiers, and the axes behind them:

The frequency trap

Phase 1 ran on a single summarizer model. That model has a systematic editorial bias — it consistently over-reports "the agent moved too fast" and "the agent was preachy," and invents narrative "detours." That bias recurs across sessions by construction, so it clears the "2+ sessions" Tier-A bar trivially, looking exactly like a real recurring pattern. observation Frequency cannot tell a true pattern from a biased reader repeating itself.

The defense: any Tier-A candidate that pattern-matches the known bias profile must be transcript-verified before promotion — frequency is disqualified as evidence for it. Meanwhile, user-action signals (a real interruption, an explicit correction) stay trustworthy regardless of which model surfaced them, because they're grounded in what the human actually did, not what the summarizer asserted. interpretation Knowing your instrument's bias and routing around it is the whole game.

Friction clusters ranked by session span A schematic bar chart of friction clusters ranked by how many sessions each spans, with cluster counts shown as representative. Some of the tallest bars are flagged suspect because they match the summarizing model's known editorial bias, while some shorter bars are trusted because a real user action backs them — frequency and trustworthiness are different axes. Frequency isn't evidence Friction clusters by distinct-session count · bar height ≠ trust ⚑ 9 agent rushed ⚑ 8 too preachy ⚑ 6 invented detour 5 grep- first ⚑ 5 over- formatted 4 verify premise 4 diagnostic ≠ directive 3 tool-trust gate 3 under- documented ⚑ suspect — matches reader bias trusted — user-action backed The tallest bars are suspect (a biased reader repeating itself); some short bars are trusted.
Friction clusters ranked by session span A schematic bar chart of friction clusters ranked by how many sessions each spans, with cluster counts shown as representative. Some of the tallest bars are flagged suspect because they match the summarizing model's known editorial bias, while some shorter bars are trusted because a real user action backs them — frequency and trustworthiness are different axes. Frequency isn't evidence Friction clusters by distinct-session count · bar height ≠ trust ⚑ suspect — matches reader bias trusted — user-action backed ⚑ 9 agent rushed ⚑ 8 too preachy ⚑ 6 invented detour 5 grep-first ⚑ 5 over-formatted 4 verify premise 4 diagnostic ≠ directive 3 tool-trust gate 3 under-documented The tallest bars are suspect (a biased reader repeating itself); some short bars are trusted.
Fig 2 — friction clusters ranked by how many sessions each spans. Some of the tallest bars are flagged suspect — they match the summarizing model's known editorial bias and need transcript verification; some shorter bars are trusted because a real user action backs them. Frequency and trustworthiness are shown to be different axes.
source tools/trawl/ reduce output (clustered observations, distinct-session counts)type schematic — cluster counts representative; suspect = bias-profile match, pending ledger wire-upsafety trusted vs suspect by hatch + flag glyph, not colour

§4The failure that taught the most

The Phase-1 reduce agent failed, and the failure is more instructive than a success would have been. Two things broke. First, the agent's Write was blocked by a permission scope it didn't have, so it was forced to dump its report as chat text instead of a file. Second, and this is the keeper: forced to emit the report inline, the model confabulated session IDs. It had correctly read all 24 observation files, but when it assembled the clustered output it invented the per-cluster UUID lists: of ~30 IDs it cited, exactly one existed in the real corpus; the rest resolved to nothing. observation

The lesson generalizes hard: an LLM must never hand-transcribe a unique identifier. Carrying 68 exact UUIDs verbatim through a clustering operation is precisely the long-context transcription task models fabricate under. The fix is architectural, not a better prompt:

# every observation gets a short stable tag
model clusters by tag        # never touches a UUID
deterministic script: tag → session-count   # resolved from ground truth

(Fixing the Write permission alone would not have fixed the confabulation: they were independent failures, and conflating them would have shipped a still-broken pipeline.) That's the kind of bug that only shows up when you actually run the thing and then check the output against ground truth instead of trusting it, the same discipline the whole eval line is built on, pointed at its own tooling.

§5Knowing your instruments

Phase 2 (deferred) uses a deliberately temperament-diverse panel of summarizer models, not repeat runs of one: the point is to catch where readers disagree. The panel was drawn from a 9-model bake-off on a single ground-truthed session: a balanced anchor; a calm, well-calibrated reader that actively de-escalated a false-positive the others flagged; a mechanically-precise one that caught concrete waste the others underweighted; and a cheap wildcard that uniquely surfaces process-anxiety texture but hallucinates (so it leads, never decides). Several models were explicitly disqualified, including chronic under-flaggers that inject false negatives and one quant so aggressive it dropped an entire section.

The hardest task for all of them, measured: attribution — deciding whether the user or the agent owned an action, from casual indirect phrasing. That's the signal most worth a human's judgment, so it's the one least outsourced.

Caveats & status

This is explicitly human-in-the-loop: decision-support, not an autonomous self-rewriting agent, because an LLM promoting its own behavioral rules unsupervised is how bias compounds. Phase 1 shipped single-summarizer, bias-screened; the multi-model panel that would cross-check it is designed but deferred.

Build notes & lineage

This is the loop-closing branch: the same measurement instinct as the vivisection lab — ground-truth verification, instrument-bias modelling, frequency-isn't- evidence — applied this time to the agent doing the work. Companion: the mem0-processor pipeline that produces the summaries this mines. Trawl infra: tools/trawl/ (preprocess.py, agent1/agent2-map.md, the tag-based reduce, trawl_reduce.py). Map agents run as background subagents; the reduce is interactive. Run locally on a 16 GB Mac Mini.