fix(fleet): harden operator sends for release (#565)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful

This commit was merged in pull request #565.
This commit is contained in:
2026-06-20 20:41:11 +00:00
parent 6dfd78f643
commit b5c1381e45
4 changed files with 236 additions and 11 deletions

View File

@@ -17,6 +17,9 @@ Product-owned defaults:
- `packages/mosaic/framework/tools/tmux/agent-send.sh`
- `packages/mosaic/framework/tools/tmux/send-message.sh`
These files are published through `packages/mosaic/package.json`, whose `files`
allowlist includes `framework` along with `dist`.
Site-owned local roster:
```text
@@ -66,6 +69,14 @@ These commands read the roster and target the configured tmux socket. The
generated systemd agent services use `start-agent-session.sh`; message delivery
uses the tmux send tools with `-L mosaic-factory`.
`mosaic agent send` is operator-origin traffic unless a caller explicitly says
otherwise. The CLI always passes a deterministic source label to
`agent-send.sh` with `-S`, defaulting to `<hostname>:operator`, so it does not
query the target tmux socket and accidentally identify as an active agent pane.
Use `--source-label <label>` or `--source <label>` only when deliberately
impersonating a known handoff lane. The lower-level inter-agent wrapper
`agent-send.sh -S <label>` remains the explicit source override for scripts.
## Verification
Use these checks before expanding the roster:
@@ -83,6 +94,27 @@ Expected results:
- `tmux ls` shows only the default tmux server sessions and is not changed by
fleet start/stop operations.
- `mosaic fleet verify` checks exact session targets on the isolated socket.
- `systemctl --user status ...` may show `active (exited)` for oneshot units;
that means the unit ran, not that an agent pane is live. Treat tmux
`has-session`, `list-panes`, process tree, and logs as the liveness evidence.
## Release Preflight
Run this checklist before cutting or dogfooding a fleet release:
- Real AI dogfood: send at least one task through `mosaic agent send`, then
confirm the agent accepted/responded using pane, process, or log evidence.
- Restart/stop/idempotency: run `mosaic fleet start`, `restart`, `stop`, and a
repeated `start` against the named socket; verify the default tmux server is
unchanged.
- Liveness verification: run `mosaic fleet verify` and confirm roster sessions
with `tmux -L mosaic-factory ls` or exact `has-session` checks.
- Package dry-run: run `npm pack --dry-run --json` from `packages/mosaic` and
confirm `framework/fleet`, `framework/systemd/user`,
`framework/tools/fleet`, and `framework/tools/tmux` assets are included.
- Mosaic update test: install or upgrade from the packed artifact in a temporary
Mosaic home and confirm `mosaic update` or the release upgrade path does not
remove local roster/config files.
## Rollback

View File

@@ -0,0 +1,35 @@
# Fleet release hardening
## Objective
Harden the Mosaic local fleet release path for operator sends, tmux/systemd verification, package contents, and dogfood release documentation.
## Constraints
- Do not edit `docs/TASKS.md`.
- Do not change production deployment refs.
- Keep fleet transport generic and named-socket safe.
- Preserve strict roster validation.
- Add tests first or alongside fixes.
## Plan
1. Add regression tests for deterministic `mosaic agent send` source labels.
2. Strengthen fleet status/verify/package/install-systemd coverage.
3. Implement focused CLI/source-label changes.
4. Update local canary documentation with dogfood preflight.
5. Run formatting, targeted tests, typecheck, lint, and package dry-run evidence.
## Evidence Log
- Started from existing `docs/PRD.md`; durable local fleet canary is in v0.1.0 scope.
- Loaded `mosaic-fleet-operations` skill; key constraints are isolated tmux sockets, no default tmux positive tests, and `active (exited)` is not liveness.
- TDD red: `pnpm --filter @mosaicstack/mosaic test -- src/commands/fleet.spec.ts` initially failed because `node_modules` was absent; after `pnpm install`, the new source-label tests failed on missing `-S`, missing helper, and unknown `--source-label`.
- Green implementation: `mosaic agent send` now passes `-S <hostname>:operator` by default and accepts `--source-label` / `--source` overrides.
- Test coverage added for tmux-based fleet verify liveness, package `files` allowlist containing `framework`, and explicit operator source-label command construction.
- Formatting: `pnpm exec prettier --write packages/mosaic/src/commands/fleet.ts packages/mosaic/src/commands/fleet.spec.ts docs/guides/fleet-local-canary.md docs/scratchpads/2026-06-20-fleet-release-hardening.md`.
- Targeted tests: `pnpm --filter @mosaicstack/mosaic test -- src/commands/fleet.spec.ts src/cli-smoke.spec.ts` passed with 49 tests.
- Typecheck: `pnpm typecheck` passed.
- Lint: `pnpm lint` passed.
- Package dry-run: `npm pack --dry-run --json` from `packages/mosaic` included `framework/fleet`, `framework/systemd/user`, `framework/tools/fleet/start-agent-session.sh`, and `framework/tools/tmux/{agent-send.sh,send-message.sh}`.
- Review: `~/.config/mosaic/tools/codex/codex-code-review.sh --uncommitted` approved the supplied diff with no findings; the review tool noted its read-only sandbox could not inspect files directly.