Files
stack/docs/scratchpads/ms-792-fleet-enoent-installer.md
jason.woltje 3f77229e88
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline was successful
fix(#792): fleet roster ENOENT actionable exit + installer heading printf (#818)
2026-07-17 21:36:36 +00:00

3.0 KiB
Raw Blame History

ms-792 — Fleet roster error handling and installer heading

Objective

Make expected missing or malformed fleet roster configuration fail with an actionable message and nonzero exit instead of a raw Node stack trace. Ensure the installer preserves the @mosaicstack/mosaic heading.

Plan

  1. Add failing coverage for missing and malformed roster input.
  2. Centralize roster-file read and parse error translation; add the CLI async error boundary.
  3. Sweep fleet command read paths that bypass the roster loader.
  4. Replace the installer heading output with format-safe rendering and test it.
  5. Run focused and repository quality checks; request independent review.

Progress

  • 2026-07-16: Confirmed issue #792 and branch base 9745bc3f.
  • 2026-07-16: Installed locked workspace dependencies using a worktree-local pnpm store; no .mosaic/ files were changed intentionally.
  • 2026-07-16: Added a shared roster read/parse guard and routed v1 fleet commands plus v1/v2 selection through Commanders actionable nonzero error path. V2 command modules already return structured nonzero JSON errors for their guarded reads.
  • 2026-07-16: Replaced installer heading echo with format-safe printf; added a regression check for the scoped package heading.
  • 2026-07-16: Rebuilt CLI and manually verified fleet ps with no roster prints the initialization hint, exits 1, and has no stack trace.
  • 2026-07-17: Rebased #818 onto origin/main at 9ddc6fbd (#791 PR3). The added fleet regen command had a canonical roster read in its sibling module; it now uses the same missing-roster guard and Commander exit path. Internal NORTH_STAR, preset, and post-write invariant reads remain intentionally unguarded.
  • 2026-07-17: RoR found that semantically invalid v1 documents still escaped as plain Error values. normalizeFleetRosterV1 now preserves each validation message while converting it to FleetRosterConfigurationError, so its command callers use the actionable nonzero Commander path.

Verification

  • pnpm --filter @mosaicstack/mosaic test — PASS (61 files, 1,046 tests; executed outside sandbox because CLI smoke tests spawn Node)
  • pnpm typecheck — PASS
  • pnpm lint — PASS
  • pnpm format:check — PASS
  • pnpm --filter @mosaicstack/mosaic exec vitest run src/commands/fleet.spec.ts src/commands/install-heading.spec.ts — PASS (209 tests)
  • pnpm --filter @mosaicstack/mosaic exec vitest run src/commands/fleet-regen-command.spec.ts — PASS (27 tests, including missing canonical roster)
  • pnpm --filter @mosaicstack/mosaic exec vitest run src/commands/fleet.spec.ts -t "semantically invalid v1 roster" — RED then PASS; verifies duplicate agent names are reported as fleet.roster exit 1 without a stack trace.
  • Instrumented Vitest coverage is unavailable because @vitest/coverage-v8 is not declared in this repository. Each branch added in the roster guard has direct unit coverage.

Risks / blockers

  • Dependency installation is required before executing Vitest, TypeScript, lint, and formatting gates.