Files
stack/docs/scratchpads/1264-unattended-first-start.md
T
2026-08-16 17:37:32 -05:00

5.9 KiB

#1264 — Unattended fleet first start

Tracking

  • Issue: mosaicstack/stack#1264
  • Branch: fix/1264-fleet-unattended-first-start
  • Base: origin/next@476db12b92971634b67fd2057b7577ee5894e449
  • Worktree: /var/home/jason.woltje/agent-work/1264-unattended-first-start
  • Coordinator: Fred; reviewer must be neither Fred nor this implementation seat.
  • docs/TASKS.md is orchestrator-owned and is not modified by this worker.

Objective

A roster-owned fleet seat launched from systemd on a clean host must cross Mosaic's first-run identity gate without a human or TTY, while retaining an exact seat identity from the canonical roster and preserving the interactive wizard for standalone launches.

Intake and boundaries

  • Read Daphne's source report at jarvis-brain commit 6c0b6fc70ae6a179a1b7ff9dedfc54e9adccd19a before implementation.
  • Read Tiny's concurrent PREFLIGHT-STATE.md; do not edit start-agent-session.sh, its PATH builder, runtime preflight, or #1258's Node candidate.
  • Do not touch the canary VM or this host's ~/.config/mosaic.
  • Do not depend on held PR #1213 or introduce the proposed ~/.mosaic composition layer.
  • No real credentials/provider calls. Tests use temporary roots and fake executables only.
  • Report exact commands, exit codes, and retained stderr in docs/reports/qa/2026-08-16-1264-unattended-first-start.md.

Requirements and design assumptions

  • PRD IDs: FCM-REQ-12, AC-FCM-10; FCM-REQ-11 is reserved by concurrent #1256.
  • ASSUMPTION: generated MOSAIC_AGENT_NAME distinguishes fleet launches; the existing runtime composer still validates the exact member against the canonical roster.
  • Prefer the shipped defaults/SOUL.md and defaults/USER.md over threading wizard flags through every launcher. Seed only missing top-level files, never overwrite existing operator content.
  • Generic defaults are a base behavior contract, not the seat identity. The roster-resolved injected block supplies exact agent/session name and class.
  • Fleet missing/unsafe defaults must fail closed without attempting an interactive wizard.
  • Standalone missing identity retains today's wizard behavior.

Plan

  1. Add a no-TTY, systemd-equivalent failing reproducer before production changes; record RED.
  2. Add narrow first-start bootstrap logic at the existing checkSoul() seam only.
  3. Prove generic default bytes, private modes, exact roster identity, no clobber, idempotence/race, invalid-default refusal, and standalone wizard preservation.
  4. Run focused, package, shell/framework, typecheck, lint, format, build, and greenfield fixture gates.
  5. Update user/developer/admin documentation, sitemap, QA report, and documentation checklist.
  6. Obtain independent code review, remediate, commit with explicit goals identity, queue-guard, push, open PR to next, and request a reviewer other than Fred/goals.
  7. After branch is pushed and worktree is clean, remove this worktree as Fred explicitly required.

Budget

  • No user-specified token cap.
  • Working estimate: 25K tokens for source/test/docs/review/PR lifecycle.
  • Reduce scope before expanding launcher surfaces; stop and report if the fix requires #1213 or the contested pane-PATH function.

Progress

  • Issue #1264 identified and read.
  • Daphne's report and Tiny's state read.
  • Fred authorized plain-git worktree placement after the mandated helper failed on this host.
  • PRD amended before coding.
  • RED test captured: focused Vitest 1 failed, command exit 1; real built CLI entered the identity wizard under piped stdin and never reached the fake runtime boundary.
  • Implementation and canonical documentation complete.
  • Applicable local baseline and situational gates complete; aggregate shell has one scoped environment refusal and root DB-backed test remains prohibited/unrun.
  • Independent automated review complete: one padded-name finding fixed; clean code/security re-review. Formal non-goals/non-Fred PR reviewer pending.
  • PR lifecycle complete.
  • Worktree removed.

Test evidence

RED — 2026-08-16

env -u DATABASE_URL pnpm --filter @mosaicstack/mosaic exec vitest run \
  src/commands/launch-first-start.spec.ts

Exit 1; 1 file failed, 1 test failed. The child emitted [mosaic] SOUL.md not found. Running setup wizard..., rendered What would you like to do?, then emitted [mosaic] Setup failed. Run: mosaic wizard. The assertion expected runtime exit 0 and received 1; the fake runtime-boundary capture was not created. Full output is retained at /tmp/1264-red.out for this work session.

GREEN — current delta

  • Original no-TTY subprocess test: 1/1 passed, command exit 0.
  • Final focused set: 6/6 files, 119/119 tests passed.
  • Full Mosaic Vitest: 88/88 files, 1568/1568 tests passed.
  • New helper coverage: 100% statements/functions/lines, 93.33% branches.
  • Root preflight/format/diff checks passed; typecheck 45/45, lint 25/25, build 25/25.
  • Targeted start-agent-session, install migration (21/21), and init-RCE shell tests passed.
  • Aggregate framework shell stopped at the known environment refusal: global Pi is 0.84.2 while Invariant R is measured for 0.84.1. It was not retried or scored as a #1264 failure.
  • Root pnpm test remains UNTESTED because it can execute prohibited PostgreSQL-dependent tests.
  • CI remains UNTESTED until the PR is pushed.

Risks / blockers

  • The shipped defaults are intentionally generic; exact fleet identity must remain visibly roster-derived to avoid making every seat indistinguishable.
  • First-start writes are a concurrent boundary when several systemd seats launch together; creation must be no-clobber and idempotent.
  • The test intentionally drives the real built CLI rather than exporting private launch helpers; this keeps the systemd/no-TTY execution boundary under test.
  • Real Pi authentication and provider task execution remain an environment-level residual and are explicitly untested in this local fixture.