The full fleet-polish bundle from your Codex symmetry-gap finding. Three fixes completing add/remove boot-survival symmetry.
1. disable-on-remove (the bug — TDD)
mosaic fleet remove stopped + deleted roster/env/heartbeat but never systemctl --user disable [email protected] — so a removed-but-enabled unit could resurrect on reboot pointing at deleted config. Added buildSystemdDisableCommand + a disable step in remove (best-effort, non-fatal, gated on !--keep-files so keeping config keeps the unit).
2. add-enable
mosaic fleet add now enables the new agent's unit for boot-survival (best-effort, independent of --start so a queued agent still survives a reboot).
3. init-R5 guarantee
mosaic fleet init --write now fails hard when a non-minimal profile lacks exactly one orchestrator (was a soft warning) — a corrupted preset can't silently produce a malformed fleet. The sanctioned no-orchestrator minimal preset is still allowed.
Verification
4 new tests: disable-command builder; remove invokes disable (+ still stops); add invokes enable; init general → exactly 1 orchestrator. + 147 existing fleet tests green (151 total). tsc/eslint/prettier clean.
TDD on the disable bug per contract.
Note for the reviewer
disable/enable/init validations are best-effort + non-fatal (warn-and-continue) except init's R5 hard-fail. Ready for the batched release (F3-m3 + fleet-polish + F4).
## Fleet-polish bundle — boot-survival symmetry (closes #611)
The full fleet-polish bundle from your Codex symmetry-gap finding. Three fixes completing add/remove boot-survival symmetry.
### 1. disable-on-remove (the bug — TDD)
`mosaic fleet remove` stopped + deleted roster/env/heartbeat but never `systemctl --user disable [email protected]` — so a removed-but-**enabled** unit could **resurrect on reboot** pointing at deleted config. Added `buildSystemdDisableCommand` + a disable step in `remove` (best-effort, non-fatal, gated on `!--keep-files` so keeping config keeps the unit).
### 2. add-enable
`mosaic fleet add` now enables the new agent's unit for boot-survival (best-effort, **independent of `--start`** so a queued agent still survives a reboot).
### 3. init-R5 guarantee
`mosaic fleet init --write` now **fails hard** when a non-minimal profile lacks exactly one orchestrator (was a soft warning) — a corrupted preset can't silently produce a malformed fleet. The sanctioned no-orchestrator `minimal` preset is still allowed.
### Verification
- **4 new tests**: disable-command builder; `remove` invokes disable (+ still stops); `add` invokes enable; `init general` → exactly 1 orchestrator. + **147 existing fleet tests** green (151 total). tsc/eslint/prettier clean.
- TDD on the disable bug per contract.
### Note for the reviewer
disable/enable/init validations are best-effort + non-fatal (warn-and-continue) except init's R5 hard-fail. Ready for the batched release (F3-m3 + fleet-polish + F4).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Codex symmetry-gap finding. Three fixes completing add/remove boot-survival
symmetry:
1. disable-on-remove (BUG, TDD): fleet remove stopped + deleted roster/env/
heartbeat but never disabled the systemd unit, so a removed-but-enabled
[email protected] could resurrect on reboot pointing at deleted
config. Add buildSystemdDisableCommand + disable in remove (best-effort,
gated on !--keep-files).
2. add-enable: fleet add now enables the new agent's unit for boot-survival
(best-effort, independent of --start).
3. init-R5 guarantee: fleet init --write now fails hard when a non-minimal
profile lacks exactly one orchestrator (was a soft warning); the sanctioned
no-orchestrator 'minimal' preset is still allowed.
Verified: 4 new tests (disable builder; remove-invokes-disable; add-invokes-
enable; init general → exactly 1 orchestrator) + 147 existing fleet tests green
(151 total); tsc/eslint/prettier clean.
Refs #611
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EsgTQzV5YUGk1JtCLP4B83
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fleet-polish bundle — boot-survival symmetry (closes #611)
The full fleet-polish bundle from your Codex symmetry-gap finding. Three fixes completing add/remove boot-survival symmetry.
1. disable-on-remove (the bug — TDD)
mosaic fleet removestopped + deleted roster/env/heartbeat but neversystemctl --user disable [email protected]— so a removed-but-enabled unit could resurrect on reboot pointing at deleted config. AddedbuildSystemdDisableCommand+ a disable step inremove(best-effort, non-fatal, gated on!--keep-filesso keeping config keeps the unit).2. add-enable
mosaic fleet addnow enables the new agent's unit for boot-survival (best-effort, independent of--startso a queued agent still survives a reboot).3. init-R5 guarantee
mosaic fleet init --writenow fails hard when a non-minimal profile lacks exactly one orchestrator (was a soft warning) — a corrupted preset can't silently produce a malformed fleet. The sanctioned no-orchestratorminimalpreset is still allowed.Verification
removeinvokes disable (+ still stops);addinvokes enable;init general→ exactly 1 orchestrator. + 147 existing fleet tests green (151 total). tsc/eslint/prettier clean.Note for the reviewer
disable/enable/init validations are best-effort + non-fatal (warn-and-continue) except init's R5 hard-fail. Ready for the batched release (F3-m3 + fleet-polish + F4).
🤖 Generated with Claude Code