Commit Graph
37 Commits
Author SHA1 Message Date
fargo e68650a8e7 test(#1297): make broker-dependent tests host-independent (CI root + no live broker)
Pipeline 2561 failed 5 tests that pass on a dev host, two环境 classes:

1. Un-seamed success-path start/apply tests answered the HOST's broker
   state: this dev machine has a live lease-broker socket at the default
   XDG path, so the real probe (correctly, since #1297 F3) returned true
   locally; CI has no broker, so the new start re-check refused
   broker-absent. Fixed by injecting a deterministic present-broker seam
   in exactly the tests whose property is ordering/targeting (reconciler
   start-ordering, two apply-running tests, and the CLI command spec's
   shared helper). Refusal and real-probe tests keep explicit false
   seams / explicit socket paths.

2. The placeUnitFile unlink-failure spec relies on EACCES from a 0500
   directory; CI steps run as root (apk add succeeds unprivileged-free)
   and CAP_DAC_OVERRIDE makes unlink succeed, so the abort path cannot
   be triggered there. Now it.skip under uid 0 with the reason stated;
   exercised on every non-root dev host.

The remaining unseamed apply tests use the stopped-agent path (no broker
interaction) and passed CI unchanged — verified against the 2561 log,
not assumed.
2026-08-20 18:53:50 -05:00
fargo bdc23da04e fix(#1297 review): real socket probe, honest placement abort, observable broker state
rev-security-03 REQUEST_CHANGES (review note on the brain), all four
findings verified by measurement before fixing:

F1 BLOCKER — brokerSocketPresent used access(path, S_IFSOCK).
S_IFSOCK (0xC000) is a file-type constant, not an access() mode (0-7):
on node 24.18.0 the call throws ERR_OUT_OF_RANGE, so the probe could
NEVER return true and the swallow-catch made every un-seamed call report
the broker absent — on this host (roster v1) 'mosaic fleet start' would
have refused broker-absent forever. Now stat().isSocket(), matching the
bash side's [ -S ]. New spec exercises the REAL probe against a REAL
unix socket (true), a regular file (false), and an absent path (false) —
no seam, so no seam can hide this again.

F2 — placeUnitFile's single catch conflated destination-absent with
unlink-FAILED; on unlink failure it copied through the still-live
symlink (copy-through overwrite measured by the reviewer). Now: ENOENT
is the only swallowed lstat outcome; unlink failure aborts with a named
UnitPlacementError BEFORE any copy. New spec proves the residue target's
bytes survive an unlink failure and the destination link is untouched.

F3 — observeBroker defaulted unit/socket to false when seams unset, and
production injects none: plan/status/doctor reported a healthy broker as
absent. Seams still take precedence; with no seam the real stat()
probes run. The v2 start path (and apply-with-running) now re-check the
socket after enable+start with a NAMED lifecycle-precondition-failed
refusal — previously only the v1 path had that protection, and the
refusal was masked into the generic recoverable result. Acceptance
fixtures gain hermetic brokerSocketEnv paths (the old fixture asserted
the lying default).

F4 (note) — unlink race stays inside the user-owned dir; no action.

Local gates on this tree: vitest 1566/1566, typecheck, lint, prettier
3.8.1, verify-sanitized all pass. CI 2468's sanitization failure did not
reproduce locally on the identical tree; watching the fresh pipeline.
2026-08-20 18:53:43 -05:00
fargo c2db6728b4 fix(fleet): activate the lease broker at install/start, place units through symlinks safely, refuse doomed launches (#1292)
Wall 6: no documented path ever enabled or started the shipped
mosaic-lease-broker.service — every gated runtime died ~4s in at lease
registration while fleet start reported rc0, and a broker not in the
reconciler plan could not be reported as drifted.

Activation lands in the control plane, not the launcher:

- fleet install places ALL FOUR units through placeUnitFile — a placement
  helper that unlinks any by-path-enable symlink at the destination
  BEFORE copying (Node copyFile follows the link and overwrites the SEED
  template; measured on a throwaway systemd user instance 2026-08-17,
  with both cp and fs.copyFile), removes a stale wants-symlink pointing
  outside the active dir (readlink — readFile returns the target's
  content, not the link path), then copies and daemon-reloads. The same
  measurement showed systemctl enable <name> does NOT rewrite an existing
  by-path wants-symlink — reconciliation must be explicit. Idempotent:
  second install on by-path residue converges to the identical state.
  Until now the copy block named three units and omitted the broker, and
  the residue set / copy set were disjoint only by accident (fomo-lin
  survived copy-through because its one symlink was the one unit not
  copied); adding the broker made them intersect on first run. See the
  SET-INDEPENDENCE note on the helper before adding a fifth unit.
- enableFleetUnits enables the broker first, alongside the holder.
- fleet start / reconciler start the broker BEFORE any holder/agent
  lifecycle effect, then RE-CHECK the socket (not unit state) and exit
  nonzero with a named code if it did not appear. Re-probed on every
  invocation — a RemainAfterExit=yes dead-looking-active unit can never
  make retry look like repair (the sticky-retry check).
- The reconciler plan carries broker {unitInstalled, socketPresent} as a
  first-class member; the socket is the signal (enabled-but-dead units
  report socketPresent=false).
- start-agent-session.sh preflights the broker socket BEFORE any tmux
  effect (moved ahead of the ownership probe): absent -> exit 75
  (EX_TEMPFAIL), named refusal with socket path and remedy, no doomed
  pane. The agent@ unit is Type=oneshot with no Restart=, so the message
  survives instead of looping. The preflight detects and refuses; it
  never starts the broker.
- mosaic doctor's lease check names one convention-neutral remedy:
  'mosaic fleet install (it reconciles either enable convention)' —
  written from the measurement; teaching a manual systemctl line could
  leave a host with competing wants-symlinks.

Tests: fleet-place-unit.spec.ts (8: clean-host negative control,
by-path residue -> seed bytes AND mtime unchanged [the finding-2 check],
wants-residue cleared, idempotence single + double-install convergence);
fleet.spec.ts broker-first enable ordering, refused start emits no
holder/agent calls, second-start re-probe; reconciler broker plan member
(enabled-but-dead shape) + broker-before-agent ordering in both command
and apply paths; test-agent-session-broker-preflight.sh (CI-fit: fake
tmux, real unix socket at a short /tmp path — AF_UNIX caps at 108 bytes,
hermetic env; absent -> exit 75 + no tmux session, live socket passes,
explicit env wins, --stop not fenced). 1563/1563 vitest, lint, root
build 25/25, root typecheck 45/45.

Sabotage controls: placement unlink removed -> exactly the seed-integrity
test reddens (1/8); socket re-check disabled -> exactly the two preflight
specs redden; shell preflight removed -> the bash suite reddens (6 FAIL
assertions, rc=1). All restored byte-identically (sha256-verified), all
green again.

Test 6 (greenfield 1124, seat alive 2min + second fleet start) runs on
sandbox after daphne's baseline, coordinated with fred.

Note: the preflight uses exit 75 measured against the unit's Restart=
policy (oneshot, none) — no restart loop.
2026-08-20 18:53:43 -05:00
be-coder-06andMos 4fa2768962 fix(fleet): propagate roster git identity (#1073)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: be-coder-06 <[email protected]>
2026-08-07 07:07:45 +00:00
jason.woltje 3f77229e88 fix(#792): fleet roster ENOENT actionable exit + installer heading printf (#818)
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful
2026-07-17 21:36:36 +00:00
jason.woltje 9ddc6fbda8 feat(fleet): mosaic fleet regen — regenerate roster-derived projections (PR3 of #791) (#813)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-07-17 03:17:55 +00:00
jason.woltje 9745bc3f29 feat(fleet): add reviewed v1-to-v2 migration preview (#788)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-07-16 13:11:16 +00:00
jason.woltje adad486b6f fix(fleet): enforce exact comms authority (#787)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-07-16 00:32:23 +00:00
jason.woltje 499090508e feat(fleet): reconcile local roster state (#785)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-07-15 15:03:31 +00:00
jason.woltje bc5e73629e feat(fleet): add generation-guarded agent CRUD (#773)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-07-15 12:03:05 +00:00
jason.woltje 191efaefeb feat(fleet): enforce generated environment boundary (#772)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-07-15 08:40:32 +00:00
jason.woltje 405984af5a De-hardcode orchestrator and interaction agent names (#748)
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful
2026-07-13 18:59:27 +00:00
jason.woltje 67135d3822 fix(fleet): guard mosaic fleet restart against tight-loop re-entry race (#680)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-06-25 01:44:48 +00:00
jason.woltje d7eaa19380 feat(fleet): provision roster from system-type profile (H3) (#665)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-06-24 19:48:54 +00:00
jason.woltje 0d17a29ebe feat(fleet): export MOSAIC_AGENT_CLASS into agent env (A3a) (#663)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-06-24 17:19:59 +00:00
jason.woltje 84d2757817 feat(fleet): update-surviving persona customization (H4) (#661)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-06-24 16:21:01 +00:00
jason.woltje a738ac1410 feat(fleet): system-type profiles (H2) (#660)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-06-24 16:02:25 +00:00
jason.woltje f852250419 feat(fleet): native Mosaic backlog on @mosaicstack/db (atomic claim + TTL) (#657)
ci/woodpecker/push/ci-image Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was canceled
2026-06-24 14:55:10 +00:00
jason.woltje 937077f6be fix(fleet): report idle agents as available, reserve stuck for genuine blocks (#653)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-06-24 13:58:22 +00:00
jason.woltje 70661e3fab fix(fleet): derive pane idle from window activity fallback (#651)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-06-24 06:37:45 +00:00
jason.woltje d887555852 feat(fleet): classify agent readiness in fleet ps (#649)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
2026-06-24 05:55:47 +00:00
jason.woltje 4e84f8e850 feat(fleet): comms-block emitter + FLEET-LAUNCH runbook (#633) (#638)
ci/woodpecker/push/ci Pipeline was canceled
ci/woodpecker/push/publish Pipeline was canceled
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-06-22 22:23:50 +00:00
jason.woltje d539d61e0e refactor(fleet): rename tmux socket mosaic-factory → mosaic-fleet (#630)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-06-22 21:08:43 +00:00
jason.woltje 7342415a32 fix(fleet): consume model_hint + fix socket-default trap (stand-up fixes) (#627)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-06-22 19:18:01 +00:00
jason.woltje 2bf66136e4 feat(fleet): enhancer role + two-agent floor (orchestrator + enhancer) (#615)
ci/woodpecker/push/publish Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-06-22 13:15:59 +00:00
jason.woltje d46ac40890 fix(fleet): boot-survival symmetry — disable-on-remove + add-enable + init-R5 (#612)
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-06-22 08:12:58 +00:00
jason.woltje 59c755067e feat(fleet): F3-m2 — native Pi heartbeat + model surface + mosaic_mission_status tool (#602)
ci/woodpecker/push/ci Pipeline is pending
ci/woodpecker/push/publish Pipeline is pending
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-06-22 01:43:18 +00:00
jason.woltje 6ffb27787e fix(fleet): complete HB reader/writer consistency + sidecar hardening (#599)
ci/woodpecker/push/ci Pipeline was canceled
ci/woodpecker/push/publish Pipeline was canceled
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-06-22 01:22:35 +00:00
jason.woltje 67df06f1c4 feat(fleet): orchestrator-mutable fleet — fleet add/remove (F5/R9) (#596)
ci/woodpecker/push/ci Pipeline is pending
ci/woodpecker/push/publish Pipeline is pending
2026-06-21 23:26:21 +00:00
jason.woltje 60a309d5a4 fix(fleet): heartbeat consistency — MOSAIC_HOME path + configurable interval (#595)
ci/woodpecker/push/ci Pipeline is pending
ci/woodpecker/push/publish Pipeline is pending
Co-authored-by: Jason Woltje <[email protected]>
Co-committed-by: Jason Woltje <[email protected]>
2026-06-21 23:25:53 +00:00
jason.woltje ca19d57bba feat(fleet): config-type presets + AI-free init wizard (F1) (#591)
ci/woodpecker/push/ci Pipeline is pending
ci/woodpecker/push/publish Pipeline is pending
2026-06-21 23:07:41 +00:00
jason.woltje 5bef2c35eb feat(fleet): fleet ps surfaces unmanaged socket sessions (#586)
ci/woodpecker/push/ci Pipeline was canceled
ci/woodpecker/push/publish Pipeline was canceled
2026-06-21 22:37:34 +00:00
jason.woltje afcbbb302f feat(fleet): auto-enable units on install + drift recognizes wrapped runtimes (#583)
ci/woodpecker/push/ci Pipeline failed
ci/woodpecker/push/publish Pipeline was successful
2026-06-21 20:02:19 +00:00
jason.woltje af2eede7a9 feat(fleet): Phase-2 observability — fleet ps + watch + send verify (#579)
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful
2026-06-21 04:23:51 +00:00
jason.woltje 7498fcb20d fix(fleet): preserve agent env overrides on install (#567)
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful
2026-06-20 21:50:46 +00:00
jason.woltje b5c1381e45 fix(fleet): harden operator sends for release (#565)
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful
2026-06-20 20:41:11 +00:00
jason.woltje 6dfd78f643 feat(fleet): add local canary CLI (#563)
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful
2026-06-20 17:49:01 +00:00