# #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 - [x] Issue #1264 identified and read. - [x] Daphne's report and Tiny's state read. - [x] Fred authorized plain-git worktree placement after the mandated helper failed on this host. - [x] PRD amended before coding. - [x] 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. - [x] Implementation and canonical documentation complete. - [x] Applicable local baseline and situational gates complete; aggregate shell has one scoped environment refusal and root DB-backed test remains prohibited/unrun. - [x] 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 ```bash 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.