3.7 KiB
Brief: one kill switch for the bus, every run, Discord and new launches
Sage, 2026-10-20, for Mos's order mos-0974 (MVP, DECISIONS Q176, Vikunja #414 "Kill switch is available to stop all processing immediately"). Gitea #1689. T1 item 4. Owner Rocko, reviewer Dewey, gate owner Sage. Base: refactor at the brief commit.
Design first. The first deliverable is agents/rocko/work/queue-191/DESIGN.md, which Dewey reviews before
any code. Then the build follows the design, with tests and mutants.
The goal
One human command and one Console button stop all processing at once and keep it stopped until the human clears it:
- The bus takes no new work. Agent verbs that start or continue work refuse with a fixed code while the switch is on. Reads and the human's own verbs, including the clear, still work.
- Every running managed session and task run is stopped (SIGTERM, then SIGKILL after a bounded wait), and each stop is recorded as an event.
- Discord stops (its existing STOP file and
stopverb) and can't restart while the switch is on. - New launches refuse: the launcher, chief hire,
run-task.sh, and any other path that starts an agent. - The switch survives a bus restart and a host reboot (it lives in the data root, not in memory).
- Turning it on and clearing it are human-only verbs, through the bus human proof, and each leaves one event with who and when.
What exists today (GAP-MAP.md G10, measured at 9ae8c73ac)
These are pieces, with no single switch over them. The design inventories every path that starts or continues work and says how each one checks the switch:
launch.revokeandlaunch.restoreinpackages/bus/src/broker.mjs(around :2087), human-only.- The
mosaic launches off|onverbs inpackages/cli/src/cli.mjs(around :456-533) andpackages/cli/src/launcher.mjs(around :769). - The Discord STOP file (
packages/discord/src/cli.mjs:18-27).
What the design must settle
- Where the switch state lives, its format, and how each process reads it (the broker checks on every work verb; the launcher and Discord check before start). The race: a launch already past its check when the switch goes on must still be stopped.
- The CLI verb names (for example
mosaic haltandmosaic resume) and the Console button. The button is a human write, so it goes through the same writer and same-origin checks as other Console writes, and it works under the Q175 SSO session (#412) once phase 2 lands. Until then, test it with fixture servers only. - Per instance. Row 190 adds several instances per host. The switch is per instance, so it stops one instance and never another. The design names how it finds the instance's data root. This row may build on the row 190 candidate (Q177 merge-chaining).
- What a stopped run's record says, so run evidence stays write-once and honest.
Tests
Each part of the goal gets a test: work verbs refuse, a running stand-in session and run are stopped, Discord refuses to start, every launch path refuses, the switch survives a restart, an agent can't set or clear it, and the clear lets work resume. Mutants: drop the check from one launch path, let an agent clear the switch, keep the switch in memory only, skip the SIGKILL after the wait. Each one must fail a test.
Boundaries
- No test touches
~/.mosaic-dev, the live units, a real Discord bot or a slot file. Use the stand-in units, scratch data roots and fixture servers the suites already build. - Rocko has no git credentials. Sage commits the candidate and runs the queue moves Rocko can't.
Gate
Dewey approves DESIGN.md, then the manifest. The cli suite, the bus, discord and webui package suites and
every scripts/test-*.sh are green on Sage's gate, and the mutants are killed.