3.1 KiB
Fleet Unattended First-Start Operations
Status: Current after issue #1264 lands. This runbook covers only Mosaic's first-run identity gate; it does not install runtimes or credentials.
Operational contract
A systemd fleet unit launches under a sanitized environment with no TTY. The generated environment
sets MOSAIC_AGENT_NAME; Mosaic resolves that exact value against the canonical installed roster
before writing identity files.
If top-level identity contracts are missing, Mosaic atomically seeds them from the shipped generic sources:
| Destination | Source | New-file mode |
|---|---|---|
$MOSAIC_HOME/SOUL.md |
$MOSAIC_HOME/defaults/SOUL.md |
0600 |
$MOSAIC_HOME/USER.md |
$MOSAIC_HOME/defaults/USER.md |
0600 |
Creation is no-clobber and safe under concurrent seat starts. Existing regular files remain byte-for-byte and mode-for-mode unchanged. The runtime composer then injects the exact roster name and class; the generic source files grant no seat authority.
Failure handling
The fleet path never falls back to an interactive wizard. It exits nonzero before runtime execution when:
MOSAIC_AGENT_NAMEis not an exact roster member;- an ambient
MOSAIC_AGENT_CLASSdisagrees with that member's canonical class; - a missing destination has no safe regular default source;
- a source or existing destination is a symlink (including dangling), directory, unavailable, or over the bounded size;
- the fleet communications helper/roster cannot be validated; or
USER.mdcannot be securely re-read at the point where its content is composed.
Diagnostics begin with:
[mosaic] ERROR: unattended fleet identity initialization failed: ...
Repair the exact named source, destination, roster, or helper and retry only that roster member. Do
not delete or replace an existing personalized SOUL.md/USER.md merely to clear the check.
Verification without a live seat
The source gate is:
pnpm --filter @mosaicstack/mosaic... build && \
pnpm --filter @mosaicstack/mosaic exec vitest run \
src/commands/launch-first-start.spec.ts
The build leg is load-bearing: dist/ is ignored, so a direct Vitest invocation could otherwise run
absent or stale CLI output. The gate runs the exact-source built CLI in subprocesses with piped stdin,
temporary homes, a canonical fixture roster, fake runtime/broker executables, and no provider call. It
covers no-TTY launch, exact identity,
private modes, no-clobber, missing/symlink defaults, unknown members, class mismatch,
standalone wizard preservation, and concurrent first start.
Do not use this fixture as proof that a real provider credential is present or that a package has been deployed. Those require separate environment-specific evidence.