Two coupled behaviors, measured 2026-08-26 on macOS with 0.30.0→0.30.1:
1. An up-started mesh is only discoverable while its processes live. cotal meshes rows for meshes registered with meshes add persist in ~/.cotal/meshes/ and carry the registered tag. A mesh started by cotal up shows a row with no tag, derived from runtime state. When the stack's processes die, the row vanishes: the operator gets ✗ no mesh named "X" is running - see cotal meshes, and cotal meshes shows nothing — no record the mesh ever existed, no root path, no restart affordance. To someone who did not start the stack themselves this reads as data loss ("my mesh is not even registered, wtf" — verbatim operator reaction).
2. cotal up runs the whole stack as children of the invoking process, with no daemonize option. Broker, delivery daemon and manager all die with the invoking process tree. When the invoker is an agent session — increasingly the normal case, an agent setting a mesh up on a person's behalf — a session restart silently kills the broker, the manager, and every seat mid-work.
Together they compound: the session dies → the mesh dies with it → and the CLI then denies the mesh was ever there, so the person has nothing to restart from except memory of a directory path.
Proposal:
- Persist the mesh record at provision time (same store as
meshes add, marked self-hosted with its root), so a dead stack yields mesh "X" is recorded at <root> but not running — run cotal up there to restart instead of an existence denial.
- Give
cotal up a --daemon mode (setsid/reparent + pid files), or make detaching the default with the current behavior behind --foreground. An agent-invoked up should produce a stack that outlives the agent.
Two coupled behaviors, measured 2026-08-26 on macOS with 0.30.0→0.30.1:
1. An
up-started mesh is only discoverable while its processes live.cotal meshesrows for meshes registered withmeshes addpersist in~/.cotal/meshes/and carry theregisteredtag. A mesh started bycotal upshows a row with no tag, derived from runtime state. When the stack's processes die, the row vanishes: the operator gets✗ no mesh named "X" is running - see cotal meshes, andcotal meshesshows nothing — no record the mesh ever existed, no root path, no restart affordance. To someone who did not start the stack themselves this reads as data loss ("my mesh is not even registered, wtf" — verbatim operator reaction).2.
cotal upruns the whole stack as children of the invoking process, with no daemonize option. Broker, delivery daemon and manager all die with the invoking process tree. When the invoker is an agent session — increasingly the normal case, an agent setting a mesh up on a person's behalf — a session restart silently kills the broker, the manager, and every seat mid-work.Together they compound: the session dies → the mesh dies with it → and the CLI then denies the mesh was ever there, so the person has nothing to restart from except memory of a directory path.
Proposal:
meshes add, marked self-hosted with its root), so a dead stack yieldsmesh "X" is recorded at <root> but not running — run cotal up there to restartinstead of an existence denial.cotal upa--daemonmode (setsid/reparent + pid files), or make detaching the default with the current behavior behind--foreground. An agent-invokedupshould produce a stack that outlives the agent.