- Manager.openWith now fires OnSessionStart before sess.start(); if the
child exits before the hook ran, OnSessionStop would otherwise race
ahead and unmark an env root that was never marked, then OnSessionStart
would mark it forever. Added a regression test that uses a pre-closed
waitDone to force immediate exit; with a 20ms delay inside the start
hook it deterministically fails on the old ordering.
- terminalProxy.writePump now calls audit.RecordClose immediately on
terminal.exit, not just from run()'s defer. CloseTerminalSession is
idempotent (WHERE ended_at IS NULL) so the browser_disconnect fallback
becomes a no-op when fired later; without this, a client that keeps
the WS open after exit would leave ended_at NULL and `multica issue
runs` would render exited terminals as active.
- cli.APIClient.GetJSON / GetJSONWithHeaders now return *HTTPError
(matching PostJSON), so callers can errors.As to distinguish 404 from
other failures. runIssueRuns only swallows 404 (old server, no
terminal-sessions endpoint); 500 / auth / network failures now print
a warning to stderr instead of silently downgrading to "no terminal
rows".
Co-authored-by: multica-agent <github@multica.ai>