Repository navigation
The evolution loop writes one cycle-record file per run and nothing reads it #2537
Description
The evolution loop writes one cycle-record file per run and nothing reads it
What is observed, and where
A checkout's evolution memory (<project>/.emrg/memory/) accumulates one
cycle-<id>.md file for every evolution cycle:
- 45 files, 380 KB, measured on 2026-10-23.
- 37 of them written the same day — one per cycle, so the growth rate is
the cycle rate, not an accident.
None of them is read, and none is even indexed:
grep -rn 'cycle-' scripts/ emrg/ tests/finds no reader; only stale.pyc
binaries match. The readers were deleted in emrg: delete the cycle-record readers and their two flags #2476, together with the two
command-line flags that pointed at the corpus.- No row of
MEMORY.mdlinks one. The onlycycle-file the index names is a
dated state archive, which is a different thing. - The bodies are never opened by anything, so their content is unreachable by
construction: a file nothing reads and nothing indexes is not memory, it is
litter that looks like memory.
The mechanism is in emrg/server/evolution_prompt.md, in two places:
- §4 Record tells the cycle to write its conclusions "so a later cycle can
find the record by cycle id" and hands it "The record'sid:
cyc{{ timestamp }}". A cycle that believes it owes a record per id mints a
file named by that id. - §1.3 tells the next cycle to "Read the last 3–5 cycle records in
memory" — a corpus that exists only because the loop writes it.
Why it persists
Deleting the files does not stop it, and that is the interesting part. The
deletion that removed the readers also removed the only thing that would have
noticed the files were still being written. One day after the files were
declared gone, there were 45 of them again.
A cycle is also told (§4) that the record's shape and location are "the memory
system's business" — a correct rule, adopted because of an earlier ruling that
the prompt must not name where memory keeps things. It leaves the cycle free
to choose a per-cycle file, and the id it was just handed makes that the
obvious choice.
What is expected instead
- No passage tells a cycle to read or write a per-cycle record file. The
loop should not create a file that no instrument opens and no index lists. - The obligation to write what the cycle concluded stays. §4 keeps telling a
cycle to write what it found, what it changed, how it was verified and what it
expects. Only the file-per-id shape goes. - The cycle id stays load-bearing. It is how a vote body is attributed and
how a report names a run; removing the file does not touch that. - §1.3's meta-review reads something that exists. It looks for the same
trivial change made repeatedly, the same feature fixed over and over, a change
with no lasting effect, and consecutive "nothing to evolve" cycles while rants
are non-empty. The memory index is already embedded in the prompt (§1.5 rules
out re-reading it as a file), and it is where those patterns are visible.
What the fix must satisfy
- No sentence in the rendered prompt instructs a cycle to read or write a
per-cycle record file, and none calls the cycle id a record's id. - §4 still instructs the cycle to write what it found, changed, verified and
expects. - The cycle id is still declared in the rendered prompt, and the guard that
reads it out of the render (tests/test_evolution_prompt_vote_body.py) still
discriminates: reverting the declaration reddens it. It must keep
anchored on the declaration and not on a barecyc…token, because the
instructed vote examples are cycle ids too and come first in the file — a
token scan would check the examples against themselves. - The existing prompt guards stay green, and the full suite with them.
Relationship to what already landed
The reader half landed as see #2475 — the machinery that globbed records,
parsed cycle ids out of their filenames and answered "which cycle follows this
one" is gone from scripts/review-queue.py, scripts/cast-vote.py and
scripts/check-vote-count.py. That issue's premise was that the corpus was
empty. It was empty the moment it was written, and it is 45 files again a day
later, because nothing removed the half that fills it. This is that half.
Activity
argszero commentedon Oct 23, 2026
Handled by #2538