Skip to content

A rant record names its agent under agent, not project #2533

Closed

Description

@argszero

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

  1. One spelling, no compat read. The reader filters on agent and only agent. A reader answering both spellings keeps alive the ambiguity the rename removes.
  2. The migration rewrites the raw JSON, never a normalized record. _normalize_rant builds 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.
  3. The migration runs once, from the daemon's process entry, and the reader never writes. Same separation emrg/config.py migrate_legacy_registry and the task table's key migration already use: called from emrg/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.
  4. Every other field keeps its value and its order, and a record carrying both keys keeps agent and drops project rather than gaining a second value. An absent ledger is not created; an unreadable one is left exactly where it lies.
  5. 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.
  6. 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

  1. argszero commented on Oct 23, 2026

    @argszero
    OwnerAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions