Builtin progress

The dead channel

The sophisticated one had been dead for months — and the document diagnosing it was wrong in two places.

20.6MB

Before designing this loop I already had a machine for the same job: a pipeline that observed sessions automatically, accumulated them, and distilled patterns out into “instincts.” Fully automatic via hooks, and carefully designed.

When I opened it up, 127 files and 20.6MB of observations had piled up, and the distiller had never run once. Zero instincts. Nobody noticed for months — because nothing errored.

DEAD — FULLY AUTOMATIC Observation hook zero human touch 127 files 20.6MB piled up Distiller never ran once Zero instincts died quietly ALIVE — SIMPLE, WRITTEN BY HAND Memory files I write them Injected every session actually read Still alive running today the one with more parts died first
The top one was fully automatic, so nobody ever looked at it. The bottom one needed hands, so it stayed in view.

The thing running well right next to it was far simpler: memory files written by hand. Injected into every session, actually read, and corrected by me when wrong.

That inverted the lesson. It died because it was fully automatic, and the other lived because it took effort. My original plan was written on exactly the opposite lesson — revive the dead one, then stack more automation on top.

Why automatic things die

“It died because it was automatic” sounds backwards, but the mechanism is simple.

Anything automated drops out of the observed set. Things that need hands come into view every time you put hands on them. I write the memory files myself, so I know immediately when I stop. The observation hook ran on its own, so there was no way to know it had stopped.

And the structure had no consequence for producing nothing. If the distiller doesn’t run, the instinct file just doesn’t appear — and sessions run fine without it. A failure with no cost is a failure that persists.

My initial diagnosis was wrong in two places

I put the design doc through an adversarial review, and two of the problems I had written down turned out not to be true.

  • “Observations aren’t accumulating” → wrong. 20.6MB were sitting right there. The real cause wasn’t a failing hook, it was a distiller that never ran. I had been pointing at entirely the wrong repair.
  • “The always-injected index is 3–4KB” → wrong. Measured again, it was 16.8KB — 4.2× over budget. The bodies, 98 files, came to 370KB, which is physically impossible to always inject, and the on-demand retrieval was never wired up at all.

A plan built on the wrong cause fixes the wrong thing, no matter how carefully it’s designed. Those two corrections deleted half the plan.

The lesson: when diagnosing your own system, the dangerous part isn’t what you don’t know — it’s what you think you know. I had “observations aren’t accumulating” as a premise without ever having measured it.

And that 20.6MB was syncing to backup

The observation hook captured whatever was read, fetched, or returned by a tool — verbatim. No source tagging, no secret masking. And all 20.6MB of it was quietly syncing to cloud backup.

“Only after human approval, and exclude anything from outside” was written plainly in the design doc. The code enforcing it was zero lines.

A rule that exists only in the document isn’t a rule. And this case is worse than most, because nobody was reading it, so there wasn’t even a violation — violating a rule requires knowing it, and code doesn’t know rules.

The cleanup was simple: turn off two dead hooks, delete the 20.6MB and 127 empty shells, run a secret scan. The scan came back at zero — but that was luck, not design.