Repository navigation
A rant record names its agent under agent, not project #2533
Description
What is observed
A rant record in ~/.emrg/rants.jsonl names the agent it targets through a field called project:
{"timestamp": "2026-10-22T18:14:59.409195+08:00", "project": "emrg", "status": "completed", ...}The field's name is written and read in five places that must agree, each as a hand-written string:
| Site | Role |
|---|---|
emrg/server/rants.py _RANT_FIELDS |
the canonical field order, and the positional map for legacy array rows |
append_rant / list_rants |
the writer's parameter, and the reader's filter |
emrg/tools/submit_rant_tool.py |
the project parameter's schema and every use of it |
emrg/server/daemon.py |
the rant wire message's field |
emrg/server/promote_prompt.md |
a built-in template that calls the tool with project= |
Nothing fails when one of them keeps the old spelling: append_rant writes whatever key its caller passed, list_rants filters on a key nothing writes any more, and the filter silently answers no rants. The evolutionary loop reads its own feedback channel through exactly that filter.
What is expected
The field that names a rant's agent is agent, spelled that way in the canonical field order, in the writer, in the reader's filter, in the tool's parameter, in the daemon's wire message, in the template that calls the tool, and in both clients' payloads.
What the fix must satisfy
- One spelling, no compat read. The reader filters on
agentand onlyagent. A reader answering both spellings keeps alive the ambiguity the rename removes. - The migration rewrites the raw JSON, never a normalized record.
_normalize_rantbuilds a dict from the canonical field order, so a record read through it after the rename comes back with the old value dropped — not empty, gone. The migration must therefore parse the file's lines and rename the key in place. A test must prove a record survives with its value, because reading it the obvious way destroys exactly what is being moved. - The migration runs once, from the daemon's process entry, and the reader never writes. Same separation
emrg/config.pymigrate_legacy_registryand the task table's key migration already use: called fromemrg/server/__main__.py, in no path a test suite drives, so no suite run can rewrite a host's live ledger under a daemon still reading the old key. - Every other field keeps its value and its order, and a record carrying both keys keeps
agentand dropsprojectrather than gaining a second value. An absent ledger is not created; an unreadable one is left exactly where it lies. - Legacy array rows convert. A row stored in the pre-2026-08-18 array shape maps by position, and that position is unchanged by the rename — a test pins it, since a silent shift there would give every old row its neighbour's agent.
- The tool refuses to write a record with no agent, as it refuses today, and its "not a registered name" warning still names the candidates.
Scope boundary
The rant record's field only. The user-visible label (i18n key rants.project), projects_list and the project picker keep their names here and move in a later stage of the same rename, together with ProjectMemoryStore, _project_name and the memory scope string.
Activity
argszero commentedon Oct 23, 2026
Handled by #2534. The registry's command and frame names and the repo-wide rename land as further commits on the same branch, not as PRs of their own.