Skip to content

emrg: an Agent is the directory a session runs in #2519

Closed

Description

@argszero

An Agent is the directory a session runs in

What is wrong today

There is no entity for "the directory a session runs in". A session takes a bare path
(Session(session_id, cwd)), keeps it as a plain attribute, and every module that needs
the state layout beside that directory spells the layout out again:

  • emrg/session.py — generate_session_id, session_dir, list_sessions
  • emrg/sessions_index.py — the walk that rebuilds the global index
  • emrg/memory.py — ProjectMemoryStore
  • emrg/server/daemon.py — the collector that reads a session's project memory, and the
    subject list in the memory-reflection prompt

The copies agree, which is exactly what makes them invisible: the layout can change in one
of them and every test still passes, because the answers stay equal until the day one copy
is edited alone. session_dir's own docstring asks for "an edit in one place rather than a
search for every copy of the expression", and four of the sites above bypass it.

What this change does

A new emrg/agent.py holds Agent: the one directory a session runs in, carrying
base_dir and the three derived paths emrg_dir, sessions_dir, memory_dir. It carries
no behaviour — no model, no history, no sandbox knowledge — because those belong to the
session that runs in it and to the daemon that schedules it, and a field here would be a
second place to keep a fact that already has an owner.

base_dir is stored exactly as given: no resolve(), no expanduser(), no
trailing-slash normalisation, and a str stays a str. The value is compared for equality
downstream against strings that are already recorded elsewhere (what a client sent, what
meta.json stored), so normalising it on one side only is how two spellings of one
directory start disagreeing.

Session holds an Agent. Session(session_id, agent) still accepts a path and wraps it
on the spot, so no existing caller changes; cwd becomes a read-only property answering
agent.base_dir, which leaves every reader of session.cwd untouched. It is a property
rather than a field because a second assignment could move a session's files and its cwd
apart with nothing recording which one is right.

The sites above ask the Agent instead of spelling the layout. session_dir,
generate_session_id and list_sessions keep their signatures and delegate, so no caller
changes and no second convention is introduced.

Acceptance

  1. Agent stores what it was given: a trailing slash, a .. and a ~ survive unchanged,
    and a str stays a str while a Path stays a Path.
  2. Session(sid, path) and Session(sid, Agent(path)) produce the identical session
    directory and the identical cwd; session.cwd cannot be assigned.
  3. No module builds a <dir>/.emrg/{sessions,memory} path — the layout exists in Agent
    and nowhere else — and a prompt that merely names the layout is not a producer.
  4. The existing session, index, memory and prompt-template suites pass, the only edit being
    a stand-in that models what a session now holds.
  5. Mutation arms, each watched red: resolve() on base_dir; expanduser() on
    base_dir; a second spelling of the sessions path; a re-introduced copy of the layout
    in the daemon.
  6. The three-platform CI matrix is green.

Not in this change

Registering directories, the projects.yml → agents.yml migration, renaming project to
agent across configuration, records, protocol and both clients, and the daemon split are
not here. Each is separately verifiable, and each follows in its own issue opened
together with the pull request that does it.

Activity

  1. changed the title [-]emrg: project disappears — an Agent is the directory a session runs in[/-] [+]emrg: an Agent is the directory a session runs in[/+] on Oct 23, 2026
  2. argszero commented on Oct 23, 2026

    @argszero
    OwnerAuthor

    Handled by #2520

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