Skip to content

attach restarts a dead session without consent when stdin is not a TTY (EOF defaults to yes) #214

Closed

Description

@schickling-assistant

@myobie, Compounding Manager reports a pre-existing behavior from a live smoke test of #209 (evidence: schickling/dotfiles#8391 comment 6620845281).

Observed: pty attach <name> on a session that pty classifies as dead (here: a record whose daemonStartToken does not match the live PID) prints Restart? [Y/n]. When stdin is not a terminal or is at EOF, the answer defaults to yes. attach then removes the old record, spawns a new daemon that reruns the stored command, and attaches to it. --force behaves the same. Reproduced with 74e4dbb and with rust.5 (65bf24d), so #209 did not introduce it.

PTY_ROOT="$ROOT" pty attach negative < /dev/null
# Session "negative" exited with code unknown.
# Restart? [Y/n] Session "negative" restarted.

Code path at 74e4dbb: attach.rs:189,227-264 and ask.rs:13-30.

Why it matters: agents call attach non-interactively. A non-interactive caller cannot consent, yet the stored command runs again. For mutating commands this repeats side effects (same concern as #204).

Question: should a prompt with no answer (no TTY or EOF) default to "no" and exit non-zero, so that a restart needs an explicit y or a flag such as attach -r?

Safety part passed: the unrelated process that reused the PID was never attached to or signalled.

Posted on behalf of @schickling
field value
agent_identity agent/compoundingtech/compounding-manager
session 01a1d992
agent_persona generalist
agent_supervisor unavailable
agent_tool OMP
agent_tool_version 18.12.5
agent_runtime OMP 18.12.5
agent_model anthropic/claude-opus-5-5
worktree unknown

Activity

  1. myobie commented on Nov 4, 2026

    @myobie
    Contributor

    I measured this at main ddfcf093, with no terminal.

    What the code does today

    • attach on a dead session prints the last lines and asks Restart? [Y/n] (attach.rs#L231).
    • ask.rs reads one line with no terminal check, and only a lone n declines. EOF reads as an empty answer, so </dev/null restarts (ask.rs#L13-L31).
    • --force only allows attaching from inside another session. It never answered the prompt, so it restarts the same way.
    • -r restarts without asking. --no-restart refuses with exit 1 before the stored command is considered, and it is the safe flag for callers today.

    A correction. ask.rs says a closed stdin proceeds "exactly like Node", and I repeated that on #204. It's wrong for EOF. I built the pinned Node reference (f005432a) and ran it with no terminal, on Node 22 and on 24. At EOF its readline question never resolves, and the process exits 0 without restarting. It does restart on any piped line but n, an empty line included.

    stdin Node Rust at ddfcf093 Rust with #215
    </dev/null exit 0, not restarted restarted exit 1, not restarted
    an empty line restarted restarted exit 1, not restarted
    other input restarted restarted exit 1, not restarted
    y or yes restarted restarted restarted
    n exit 0 exit 0 exit 0
    -r, </dev/null restarted restarted restarted
    --force, </dev/null exit 0, not restarted restarted exit 1, not restarted

    The change, decided and in #215.

    • An unanswered prompt declines. Off a terminal, only y or yes restarts, and EOF never does.
    • With no answer, attach exits 1 and keeps the exited record. It says Answer y, or pass -r to restart it without asking.
    • These are unchanged: a terminal's Enter restarts, n exits 0, -r restarts without asking, and --force answers nothing.

    Decision 0020 records the departure from Node. A script that relied on a non-interactive restart must pass -r.

    The other prompt with this shape is pty restart's Kill and restart? [Y/n]. With </dev/null it stops a running session and starts it again. Node exits 0 and leaves the session running. #215 leaves it unchanged; it's listed there for a separate fix.

  2. added a commit that references this issue on Nov 4, 2026
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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions