What starts what
magi convenes its siblings rather than finding them running. One balthasar per window, not one per project — and both mechanisms that end it.
One per window, not one per project
A session that waited for somebody else to have launched a memory layer would record sometimes and not others. So it starts its own, named after the session. Two windows in a project therefore get one each and neither can take the other's down — they meet in the project's store file rather than in a process.
What ends each
| sibling | how magi starts it | what ends it |
|---|---|---|
| balthasar | serve --instance <session> --tied <pid>, on a socket | killed on the way out, and by the kernel if that never runs |
| melchior | serve --project <p>, on a pipe | magi closes the pipe; the read returns nothing and it leaves |
| casper | run <tool>, once per call | nothing to end — it exits on its own, every call |
Why balthasar needs it twice
A cleanup on the way out covers the exits that have a way out. A panic, an OOM and
a kill -9 run nothing at all inside magi, and those are exactly the exits that
would strand a memory layer. So the kernel holds the second copy of the rule: magi names its
own process id at spawn, and balthasar asks to be signalled when that process dies.
| exit | what ends balthasar |
|---|---|
| ordinary | magi kills it, then unlinks the socket — in that order, because after the wait the process is gone and the name cannot still be answering |
| panic · OOM · kill -9 | the kernel signals it, because magi runs nothing |
| magi died before it started | it notices its parent is not the one that named itself, and leaves |
| started by hand, no parent named | nothing — which is what a terminal or a unit file wants |