Repository navigation
Description
What was observed
emrg/server/evolution_prompt.md:440 states the scope of the memory-index rule in these words:
These rules constrain the write, not a cycle, and they apply to every
MEMORY.mdthat is maintained — the evolution layer, a source project's layer and a session's layer alike.
Line 444 then gives the bound itself: an index over 100 lines is compacted in place, and a row past 512 characters is shortened to one line. R9 is the only place either number is stated to a reader.
The tasks that maintain those other layers never read that file. Their own prompts are emrg/server/<task>_prompt.md, and measured there this round:
competition_prompt.md— mentions the index twice (line 55, "the memory index is part of this prompt"; line 328, "this prompt embeds that same directory'sMEMORY.mdindex") and states no bound and no compaction rule at all.promote_prompt.md:398— a qualitative rule with no number: "MEMORY.mdis a pure index (one short line per entry) … A list that has grown long is consolidated, not appended to forever."open_source_prompt.md:455— likewise qualitative and without a number: "KeepMEMORY.mda pure index: one short line per entry … update an entry in place".journal_prompt.md,paper_prompt.md,ios_app_prompt.md,feishu_prompt.md— nothing about the index's size.
There is no shared include and no emrg/server/task-templates/ directory, so nothing supplies the number to those prompts. Outside evolution_prompt.md it appears only where a task cannot read it: scripts/check-memory-index.py:14 (the guard's own docstring), emrg/memory.py:184 and emrg/server/daemon.py:2501 (code comments).
Why it is a defect and not drifting
A rule whose scope is stated as "every MEMORY.md that is maintained" has to reach the writer of the file it binds. Today the writer and the guard disagree by construction: the guard knows the number and says so, the writer's prompt does not carry it. A round that compacted "when it noticed" would be following its instructions exactly.
The consequence is visible on this host, and it is the reason this issue exists rather than a note in a cycle record — measured with the guard itself:
$ uv run --no-sync python3 scripts/check-memory-index.py <project>/.emrg/memory/MEMORY.md
lines 152 of 100 - over by 52
chars 25006 of 52224 - within
rows 30, longest 501 chars, over 512: 0
That index is not EMRG's to compact, and this issue does not ask for it to be touched. Its own size ledger inside the file names a "<100" rule, so the number reached that file from somewhere — whatever carried it, the task template is not that carrier today.
What a fix has to satisfy
- State the bound and the in-place compaction rule in the task templates that maintain an index, each in its own voice, once, in the section that already owns memory.
competition_prompt.mdis the one that states nothing; the two qualitative ones either gain the number or are left alone deliberately, and that choice is stated in the PR. - The number must not be re-spelled independently:
scripts/check-memory-index.pyalready imports it fromemrg/memory.pyrather than restating it, and a template that hardcodes its own copy is the drift this issue is about, one layer up. - Alternatively, narrow R9's scope claim so it binds only the layer the evolution prompt can reach, and say in the same breath where the other layers' bound lives. Either answer closes the inconsistency; leaving the claim standing while nothing carries it does not.
What this issue does not claim
It does not claim any task has misbehaved, and it is not a request to compact or edit another project's memory. It is about where the rule is written versus where it is applied.
Activity
pm25coder commentedon Oct 30, 2026
Handled by #2663