Repository navigation
The register is written at session creation, and a directory is registered as itself #2527
Copy link
Copy link
Closed
Description
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":
os.path.realpath(cwd)first. A symlinked path is collapsed before the entry is
written, so an entry'spathis not the string the session holds.Agent.base_dir
stores its directory verbatim, so the register and the session disagree for every
symlinked directory.- A subdirectory is merged into its longest known parent. Opening a session in
repo/src/whenrepois already registered writes no entry forrepo/src— it
only refreshesrepo'slast_active. The exception is a directory that is itself a
git root. - 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 acwdregisters it whether or not a
session was opened there. - The name is
basenameand nothing makes it unique. Two different directories both
namedsrcproduce two entries both namedsrc.scheduler._resolve_agent_path(name)
resolves a task'sconfig.agentby 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,
pathverbatim equal to
str(session.cwd)— norealpath, noexpanduser, 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
basenameisname-2, a
thirdname-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_excludestays: registration is where a directory learns to ignore
.emrg/.- The non-regular-file guard stays: a FIFO, socket or device as
agents.ymlis neither
read nor rewritten.
Acceptance
- A session created in a directory writes one entry whose
pathequals
str(session.cwd)exactly — for a symlinked path as well. - A second session in the same directory adds no entry and moves
last_active. - A session created in a subdirectory of a registered directory adds an entry — the
direct evidence that the parent merge is gone. - The sub-session slot, the boss session and the upgrade session add no entry.
- Two directories with the same
basenameare namednameandname-2, and
_resolve_agent_pathreturns each one's own path. - The home directory adds no entry.
- On a non-regular
agents.yml, the register is neither read nor rewritten. - 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.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
argszero commentedon Oct 23, 2026
Handled by #2528