You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Can detached mutating commands run once without automatic restart? #204
@myobie, Compounding Manager is relaying fleet feedback FB-4897.
OMP bash-tool service mode starts commands through pty. The reported detach path sends SIGTERM to the detached command and respawns it, as with pty restart / pty attach -r. For mutating commands this repeats side effects. On November 2, this affected gate-slot holds; generators that auto-commit face the same risk.
Is there an existing run-once / no-auto-restart mode for detached commands? If not, should restarting require explicit opt-in? Expected: a detached mutating command does not run again without the caller choosing to restart it.
Related: #160 handles ordering during explicit restart; #129 distinguishes attachment loss from child exit. Neither report addresses consent to rerun a detached mutating command.
Short answer: pty never reruns a command because a client detached, and running once is already its default. The SIGTERM and respawn in this report come from OMP's own service broker, not from pty. I read pty at main 325851db and OMP 18.10.2, the version in the report.
What pty does today
Detaching (Ctrl+\ or a DETACH frame) only drops that client. The daemon sends the client its end and forgets it. The child keeps running and is never signalled (clients.rs#L449-L454).
pty run -d -- <cmd> runs the command once. With PTY_REAP_ON_EXIT unset, which is the default, a session that exits on its own removes its record, so nothing is left to restart (tags.rs#L130-L154).
A command runs again only when a caller asks for it:
pty restart <name> stops a running session and starts its stored command again. Unless -y is passed, it asks Kill and restart? [Y/n] first (restart.rs#L108-L115).
pty attach <name> never stops a running session. It attaches to it.
If the session has exited and its record was kept (by a keep tag, strategy=permanent, or PTY_REAP_ON_EXIT=0), attach prints the last lines and asks Restart? [Y/n].
-r/--auto-restart skips that question.
--no-restart refuses with exit 1 before the stored command is considered (attach.rs#L172-L180, #L220).
pty gc respawns only records tagged strategy=permanent, with crash-loop protection (gc.rs#L265).
One sharp edge matters for scripts. Both [Y/n] prompts read stdin without checking for a terminal, as the Node tool does, and only a lone n declines. A closed stdin therefore counts as yes (ask.rs#L1-L31).
I measured this in a fresh registry with a session that appends one line to a file and exits:
Setup
Lines in the file
After pty run -d
1
Default reap, then pty attach <id> </dev/null (prints "not found")
1
PTY_REAP_ON_EXIT=0, then pty attach --no-restart <id> </dev/null (exit 1)
1
PTY_REAP_ON_EXIT=0, then plain pty attach <id> </dev/null (reran the command)
2
A non-interactive caller that must never rerun a command should pass --no-restart to attach and should never call restart.
Where the respawn comes from
In OMP 18.10.2, the bash tool's service mode (name set) starts the command under OMP's own launch broker. The PTY comes from @oh-my-pi/pi-natives (PtySession), not from the pty CLI.
Start:startService always sets restart: "no" and detached: false. pty defaults to true (src/launch/services.ts).
Detach: writing detached to proc://<id>/mode runs the broker's #mode (src/launch/broker.ts). For a service that is not detached yet, #mode sets { detached: true, pty: false, persist: true } and calls #restart.
The rerun:#restart calls #stopRecord, which terminates the process group, gracefully and then by force. It then launches the same command again.
Result: a running child cannot be moved out of the broker, so detaching a running service always stops it and runs it again.
Other modes:persist and session only change a flag and never restart. The broker stops every service that isn't detached when it shuts down.
Docs: the tool's description (src/prompts/internal-urls/proc.md) lists detached without saying that it reruns the command.
Is a change needed?
In pty: no change is needed for this report. A command runs once unless someone runs restart, answers yes at the attach prompt, passes -r, or tags it strategy=permanent.
In OMP's broker: this is where the fix belongs. mode=detached on a running service should refuse, or rerun only on an explicit opt-in, and the docs should say what it does.
Until then: a mutating command that must outlive the agent's session can be started with pty run -d --id <id> -- <cmd> from the bash tool's ordinary mode. pty runs it once, and -d creates a real session even when the caller is already inside one. A service left in persist is never rerun, but it stops when OMP's broker shuts down.
Optional, in pty: the two prompts could decline when stdin is not a terminal. That departs from the Node tool, so it would need a decision record. It touches no tier-1 file. I'll only make that change if it's wanted.
Detach. pty never reruns a command because a client detached. The SIGTERM and the respawn in this report came from OMP's service broker; see my earlier comment here.
The prompt edge. pty had one path that could rerun a stored command without an explicit request: a [Y/n] restart prompt with no terminal. Above I wrote that a closed stdin counts as yes "as the Node tool does". The Node part was wrong. Node exits 0 at EOF and does nothing; attach restarts a dead session without consent when stdin is not a TTY (EOF defaults to yes) #214 has the measurements.
Activity
myobie commentedon Nov 2, 2026
Short answer: pty never reruns a command because a client detached, and running once is already its default. The SIGTERM and respawn in this report come from OMP's own service broker, not from pty. I read pty at main
325851dband OMP 18.10.2, the version in the report.What pty does today
pty run -d -- <cmd>runs the command once. WithPTY_REAP_ON_EXITunset, which is the default, a session that exits on its own removes its record, so nothing is left to restart (tags.rs#L130-L154).pty restart <name>stops a running session and starts its stored command again. Unless-yis passed, it asksKill and restart? [Y/n]first (restart.rs#L108-L115).pty attach <name>never stops a running session. It attaches to it.keeptag,strategy=permanent, orPTY_REAP_ON_EXIT=0), attach prints the last lines and asksRestart? [Y/n].-r/--auto-restartskips that question.--no-restartrefuses with exit 1 before the stored command is considered (attach.rs#L172-L180, #L220).pty gcrespawns only records taggedstrategy=permanent, with crash-loop protection (gc.rs#L265).One sharp edge matters for scripts. Both
[Y/n]prompts read stdin without checking for a terminal, as the Node tool does, and only a lonendeclines. A closed stdin therefore counts as yes (ask.rs#L1-L31).I measured this in a fresh registry with a session that appends one line to a file and exits:
pty run -dpty attach <id> </dev/null(prints "not found")PTY_REAP_ON_EXIT=0, thenpty attach --no-restart <id> </dev/null(exit 1)PTY_REAP_ON_EXIT=0, then plainpty attach <id> </dev/null(reran the command)A non-interactive caller that must never rerun a command should pass
--no-restarttoattachand should never callrestart.Where the respawn comes from
In OMP 18.10.2, the bash tool's service mode (
nameset) starts the command under OMP's own launch broker. The PTY comes from@oh-my-pi/pi-natives(PtySession), not from theptyCLI.startServicealways setsrestart: "no"anddetached: false.ptydefaults totrue(src/launch/services.ts).detachedtoproc://<id>/moderuns the broker's#mode(src/launch/broker.ts). For a service that is not detached yet,#modesets{ detached: true, pty: false, persist: true }and calls#restart.#restartcalls#stopRecord, which terminates the process group, gracefully and then by force. It then launches the same command again.persistandsessiononly change a flag and never restart. The broker stops every service that isn't detached when it shuts down.src/prompts/internal-urls/proc.md) listsdetachedwithout saying that it reruns the command.Is a change needed?
restart, answers yes at the attach prompt, passes-r, or tags itstrategy=permanent.mode=detachedon a running service should refuse, or rerun only on an explicit opt-in, and the docs should say what it does.pty run -d --id <id> -- <cmd>from the bash tool's ordinary mode. pty runs it once, and-dcreates a real session even when the caller is already inside one. A service left inpersistis never rerun, but it stops when OMP's broker shuts down.myobie commentedon Nov 4, 2026
Closing this as answered.
[Y/n]restart prompt with no terminal. Above I wrote that a closed stdin counts as yes "as the Node tool does". The Node part was wrong. Node exits 0 at EOF and does nothing; attach restarts a dead session without consent when stdin is not a TTY (EOF defaults to yes) #214 has the measurements.9e46e7e8):attach's prompt now restarts off a terminal only onyoryes, and never at EOF. With no answer it exits 1 and names-r.pty restart'sKill and restart? [Y/n], which with no answer leaves the running session alone and names-y.pty run -d -- <cmd>runs the command once. A non-interactive caller that must never rerun it can pass--no-restarttoattach.