Skip to content

The register is written at session creation, and a directory is registered as itself #2527

Closed

Description

@argszero

What happens today

emrg/server/daemon.py::_touch_project writes an entry into ~/.emrg/agents.yml, the
register of directories this installation knows, whenever an inbound client message
carries a cwd.

Three normalisations inside it act against "the directory the session runs in is the
entry":

  1. os.path.realpath(cwd) first. A symlinked path is collapsed before the entry is
    written, so an entry's path is not the string the session holds. Agent.base_dir
    stores its directory verbatim, so the register and the session disagree for every
    symlinked directory.
  2. A subdirectory is merged into its longest known parent. Opening a session in
    repo/src/ when repo is already registered writes no entry for repo/src — it
    only refreshes repo's last_active. The exception is a directory that is itself a
    git root.
  3. The home directory is skipped (cwd == os.path.expanduser("~") → return).

Two further consequences:

  • The hook fires only on inbound messages, so every session the server creates itself
    never reaches it: the sub-session slot, the boss session, the upgrade session.
    Conversely a client that sends a message carrying a cwd registers it whether or not a
    session was opened there.
  • The name is basename and nothing makes it unique. Two different directories both
    named src produce two entries both named src. scheduler._resolve_agent_path(name)
    resolves a task's config.agent by that name, so the second directory silently takes
    over the first one's tasks.

What it must do instead

  • A directory a host opens a session in gets its own entry, path verbatim equal to
    str(session.cwd)
    — no realpath, no expanduser, no trailing-slash
    normalisation.
  • Registration happens when the session is created, not when a message arrives.
  • Two exceptions, both mechanical: the home directory (a session there would put its
    session directory under ~/.emrg/sessions/, beside the runtime configuration), and any
    directory under an existing agent's .emrg/ — a derived directory, not one the
    host opened.
  • Names are globally unique: a second directory with the same basename is name-2, a
    third name-3; the suffix is allocated once, when the entry is created, and is never
    recycled when another entry is removed.
  • The registration logic moves into its own module — emrg/server/agents.py::AgentRegistry
    — with no import of the daemon and no server state, so it is testable on its own.
  • ensure_local_exclude stays: registration is where a directory learns to ignore
    .emrg/.
  • The non-regular-file guard stays: a FIFO, socket or device as agents.yml is neither
    read nor rewritten.

Acceptance

  1. A session created in a directory writes one entry whose path equals
    str(session.cwd) exactly — for a symlinked path as well.
  2. A second session in the same directory adds no entry and moves last_active.
  3. A session created in a subdirectory of a registered directory adds an entry — the
    direct evidence that the parent merge is gone.
  4. The sub-session slot, the boss session and the upgrade session add no entry.
  5. Two directories with the same basename are named name and name-2, and
    _resolve_agent_path returns each one's own path.
  6. The home directory adds no entry.
  7. On a non-regular agents.yml, the register is neither read nor rewritten.
  8. The existing suite passes.

Out of scope, as its own change: the projects_list → agents_list protocol rename,
which needs the TUI and GUI to ship with the daemon.

Activity

  1. argszero commented on Oct 23, 2026

    @argszero
    OwnerAuthor

    Handled by #2528

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