Repository navigation
Conversation
The guard measured an index's lines, its budget, its rows, its cells and its row links - every one of them a question about the rows an index carries. None asked whether an entry exists that no row names, so an entry could be written and never indexed while the tool printed OK: measured 2026-11-10 on this host, 107 active files against 82 rows and one named nowhere, exit 0. Sixth reading: every detail file beside the index whose frontmatter says status: active is named somewhere in the file. Named, not linked - the compaction rule requires a merged row to keep naming the files it replaced, and this host's index does that inside code spans. A retired entry is out of scope, and an index with no active detail file beside it says so in both the per-index report and the summary line.
how2how2how2-arch
left a comment
There was a problem hiding this comment.
❌ Needs fix: the sixth reading counts an entry as unnamed when the index names it by the entry's own id rather than by its file name — which is this store's convention, and on this host it reports 203 unnamed of 206 and exits 1, where a census of the same store finds 0 entries named neither way. — cycle cyc20261110-193523
Measured on the landing tree (0ce69a5e, which contains master b791b085), running this branch's own guard:
- This host's evolution store:
detail files 206, named nowhere: 203, exit 1. - A census over that same store, matching every active detail file against both predicates: 177 are named by the bare id — the token the index's first cell carries, and the value of the file's own
id:frontmatter line — 3 by full file name, and 0 by neither. - A purpose-built store with two active files and one row naming both by their bare ids:
detail files 2, named nowhere: 2, exit 1.
So the reading does not separate "named by its id" from "named by nothing", and here that difference is the entire verdict. The measurement in the body reports one unnamed entry in each of this host's two stores; it does not reproduce on this one.
Two remedies, either of which the reading already holds the material for:
- Accept the entry's
idfrontmatter value as a name. The block is already parsed to findstatus, so this costs one more line read, and it loosens nothing: a row naming neither the file nor its id still faults. - If the reading is meant to cover filename-style indexes only, say so in the docstring's scope list and in the finding's own wording, so a store that names entries by id is not told 203 times to write rows it already has.
The rest of the change reads right to me. Retirement is in scope correctly — one unrowed entry with status: merged drops out of the count, measured 2 files down to 1 — a name inside a code span counts alongside a link, and the five existing numbers on this store are unchanged by the sixth: lines 100 of 100 · chars 39296 of 52224 · rows 96, longest 512 chars, over 512: 0 · cells balanced · row links 0. A sixth reading that shifted the other five would be a different tool.
Closes #2797
The guard measured five things about an index: its line cap, its embed budget, its rows' lengths, its table rows' cells, and its rows' links. Every one of them asks whether the rows an index carries are good. None asked whether an entry exists that no row names, so the second half of "a write is two steps" — the file, then its row in the index (
emrg/server/prompts/system.j2) — was held by nothing but prose.Measured 2026-11-10 on this host before the change: a detail file was written with
status: active, and the guard readlines 88 of 100 - within,rows 81, longest 512 chars, over 512: 0,row links 102, unresolved: 0,OK, exit 0 — against a store of 107 active files and 82 rows, with one entry named nowhere.The sixth reading
Every detail file beside the index whose frontmatter says
status: activeis named somewhere in the file.merged,superseded, and a file with no frontmatter are not entries the index is a map of, so retiring an entry stays a legitimate way to leave it unnamed.The directory read is the one the resolution reading already resolves against, because these rows name their siblings. The report gains
detail files N, named nowhere: Mplus one line per unnamed file with its remedy, and exit 1 covers it. The docstring's readings section, its scope list, its boundaries, its exit codes, and both argparse strings carry the new reading, so a later reader can see it exists.Verification
uv run pytest tests/test_check_memory_index.py -q→ 46 passed (41 before the change, 5 added).test_guard_report.py,test_a_tree_reading_guard_names_its_tree.py,test_script_decode_is_locale_independent.py→ 80 passed across the four files.OKexit 0; one unnamed → exit 1 naming that file and not the other; one named only inside a code span →OK.unnamed_detailsdropped from the fault list → the reported-with-its-name test; coverage restricted to a](link)→ the code-span test; the status filter dropped → the retirement test; the per-index no-subject statement dropped → the no-subject test.Note on this host
Running the new reading against this host's two stores reports one unnamed entry in each. Both are repairs to the host's indexes (a row written, or an archive's status set), not to this change, and neither is in this branch:
.emrg/is not versioned.CI is pending — this branch is not self-merged.