Skip to content

the daemon's own file readers open their subject whatever it is, so a FIFO blocks the daemon forever #2073

Closed

Description

@argszero

What is wrong

#2062 taught the three file tools (read, write, edit) to ask what they are
opening, because an open is not a read: on a FIFO a read blocks until a writer
appears, on a socket until a connection does, and a device never ends. The predicate is
emrg.tools.base.special_file_kind (a whitelist: S_ISREG or nothing).

The guard stops at the tool layer. The daemon has five readers of its own that open a
path the agent or the client names, and none of them asks:

reader whose path it opens
_handle_read_file (client protocol read_file, the GUI workspace panel's viewer) the client's — any absolute path
_cap_memory_index (the index the system prompt embeds) a MEMORY.md in the workspace — the agent writes it with write/edit
_index_for_frame (memories_list's index field) the same file
_memory_index_compaction_note the same file
_collect_project_context CLAUDE.md / Agent.md / MANIFESTO.md in the session cwd — the agent's own tree

Each wraps its read in except (OSError, UnicodeDecodeError), which cannot bound this: a
FIFO raises nothing, it simply never returns. The read is synchronous, inside a coroutine
the daemon awaits on its event loop, so the block is the whole daemon — every session,
the scheduler and the evolution loop with it — and the only recovery is a restart, which
belongs to the host.

The workspace listing makes the client's route ordinary rather than exotic:
_handle_list_files types every entry that is not a directory as "file", so a named
pipe in a workspace is offered in the file tree and one click on it wedges the daemon.

Measurement

Checkout measured: /Users/argszero/.emrg/evolution/emrg on master 63ee3a54
(emrg.__file__ printed inside the probe). Each call in its own process, killed by the
parent's cap.

open(<fifo>, "r")                      -> DID NOT RETURN within 6s
EmrgServer._cap_memory_index(<fifo>)   -> DID NOT RETURN within 25s

The control, on the same fixture: the three tools answer the FIFO in milliseconds with
Error: … is a FIFO (named pipe), not a regular file (#2062).

What fixes it

One predicate at five readers, and each reader takes the branch it already has for a file
it cannot read — skip for the two scanners, the existing _unreadable_index_notice for
the two index carriers, an error frame for the client handler. No new concept: the rule is
special_file_kind's, which this repo already states once.

read_file, list_memories and the system prompt all answer a non-regular subject
instead of entering it.

The failure is the same one #2062 measured at the tools, at the readers that were not
in that change.

Activity

  1. argszero commented on Oct 10, 2026

    @argszero
    OwnerAuthor

    Handled by #2074

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