T.M.B. #6 — the loop is the experiment. B.1–B.5 measured does the library beat the model. B.6 measures does the system improve itself — and shows it, with a before/after you can re-run. Retrieval is deterministic, so the demo is exact.

What’s being measured

The thesis all along: model + forest + graders + retry loop → result → train → system. B.6 is the first bench of the last two arrows — the part where the result feeds back and the system gets better. Two feedback channels:

  • MODEL channel (the angler). Every passing run is distilled into a certified (prompt, code) pair — verified-correct by an un-bribable grader, not a vibe. That’s the training set for a model of our own. (The fine-tune is the next brick; the data flows now.)
  • FOREST channel. Closes end-to-end with no GPU. The library grows (crystallize) and prunes (garbage-collect), and — heeding the rule that self-improvement without a gate tears down — it only ever proposes.

The headline: fail → grow, on screen

A real gap in the forest as it shipped: ask for “list all files recursively including every subdirectory” and the word “recursively” lexically pulls fs.cp (copy) to the top, burying the right answer fs/promises.readdir at rank #3. The coder weights the top hits — so this mis-ranking is a real failure.

The loop catches it, crystallizes the fix (an alias teaching the forest the task-language its docstring lacks), re-embeds, and re-measures:

ROUND 1  (forest as-is)
  retrieves:  fs.cp, fs/promises.cp, fs/promises.readdir, fs.mkdir
  fs/promises.readdir ranks #3   ❌ buried below the wrong API

CRYSTALLIZE → teach the forest the right word, re-embed the corpus

ROUND 2  (forest grew)
  retrieves:  fs/promises.readdir, fs.readdir, fs.cp, fs/promises.cp
  fs/promises.readdir ranks #1   ✅ displaced fs.cp — gap closed

That’s the whole thesis in eight lines: the system got something wrong, learned the right word from its own experience, and is permanently better — every future request for recursive listing now retrieves the correct API. And the learning is a reviewable one-line diff, not an inscrutable weight update. That legibility is the point — you can see exactly what the library learned, approve it, and revert it.

The safety that makes it not tear down

Self-modification is the dangerous part — so the forest channel is conservative by construction:

guardwhat it doesproven
propose-onlywrites a review queue, never edits silentlycrystallize + GC both
archive, don’t deleteGC moves to archive/, append-only reverta throwaway verb archived + logged
cold-start guardGC refuses to act below N observationsat 4 obs it flagged 48 good aliases as “unused” — and held
grace periodfreshly-authored capsules are exemptreported 0 unused verbs while flagging stale aliases

The cold-start number is the honest one to dwell on: with sparse usage data, everything looks unused. A naive GC would have gutted the library. The guard is the difference between a system that builds up and one that eats itself — which is the whole “does a self-modifying system tear down?” question, answered in code.

The receipts still hold

The pass-rate benches ran green through all the plumbing changes — the gate redesign and the shipped retrieval didn’t regress anything:

benchblindforest
B.4 — JS stdlib5 / 66 / 6
B.5 — Node core5 / 66 / 6

Honest scope: B.6 measures the loop’s machinery, not a new pass-rate. The “fail” is a retrieval mis-rank (deterministic, exact), not a code failure — a strong 7B rarely fails outright on common tasks, which is itself the consistent finding across every bench: the forest’s edge is narrow-but-real on a competent model, and the loop’s job is to keep widening the library where the model is weak. The model channel emits certified pairs but nothing trains on them yet (next brick). Code in the mmm-poc repo: forest.mjs, distill.mjs, gc.mjs, grow_demo.mjs — run the demo yourself.