Mechanism 4 of 4 · Memory & the learning loop
The absence this makes loud: a lesson nobody vouched for.
Agent-written memory is telemetry, not truth. Left alone it becomes a pile of confident assertions that the next agent will read as established fact — and the cheapest way to get a wrong one promoted is simply to say it twice.
Ingest
You don't write these lessons. The loop reads harness transcripts — Claude Code's JSONL today, behind an adapter protocol so other harnesses plug in — scrubs them at extraction time, and turns episodes into candidate memory shards.
More of the work here than you'd expect is refusing to learn from noise. Harness-injected pseudo-user records — system reminders, hook output, compaction summaries — look exactly like things a person said; in the real corpus they were 19 of the 42 surviving messages. A malformed line is a warning and a skip, never a dead run, and the watermark that tracks progress is owned by the adapter and opaque to everything else.
The unit is the episode, not the event. What's worth remembering is almost never a single message — it's a thing that was tried, went wrong, and got corrected.
Promotion
A candidate shard climbs a ladder to become a published lesson. The ordering of that ladder is the mechanism, not an implementation detail: vetoes are evaluated first, and a veto is not outvoted by evidence.
The distinct-source rule
Recurrence is the strongest signal available for whether a lesson is real. It is also trivially faked by a single confused run repeating itself — so the counter counts sources, not occurrences.
Artifacts
A published lesson that stays in a memory store is a lesson somebody has to remember to search for. The loop's last step turns recurring lessons into the actual infrastructure that would shape the next run — and it drafts the real file, rendered, ready to read as a diff.
--- name: two-engine-check description: Run the suite on SQLite AND Postgres before calling a change done. --- SQLite and Postgres have separate vector-search implementations. Only the Postgres run executes the real <=> SQL and the migration chain from empty. A change is not done until both pass.
Classification is batched, and scope is normalised before anything is created — so "migration guard" and "the migration guards" don't become two competing recommendations. Drafting is keyed on a hash of the lesson text, so re-running the loop is free. A scheduled job that bills you for re-deriving yesterday's answers is a scheduled job somebody turns off.
The boundary
This is the one place in the whole loop where a person is not optional. Everything to the left of the line is machinery. Nothing crosses it.
Recommendations that create a new private file — a skill, a hook, a subagent definition — can be installed additively, because nothing of yours is being overwritten. Anything that would edit a file you own is returned as contents for you to apply. And before recommending anything, the loop inventories the artifacts it didn't write, so it resolves against what you already have rather than proposing a fourth version of it.
Telemetry
Artifacts are tracked after they land, and retired when they stop earning their place. Which raises the question this whole site is about: what do you render for a thing whose use you cannot observe?
| Tier | Uses | What the number means |
|---|---|---|
| hook | 14 | Observed firing fourteen times. It is doing something. |
| rule | 0 | A real zero, and it is information — you shipped a rule nothing has hit. |
| fact | NULL | This tier's use cannot be observed. 0 would be a claim we can't make. |
Zero is a result. Unknown is not. Only one of them is safe to render as a number — and a dashboard that prints 0 for both is a dashboard that will eventually get an artifact retired for being unused when nobody ever checked.
The same rule now applies to lessons. Observe has a catalog; reach and outcomes are computed. Publishing something the next agent never found is a miss, not a silent success that looks like the lesson landed.