3.3 KiB
Fleet First-Start Identity Boundary
Status: Implemented by issue #1264. Requirements:
FCM-REQ-12,AC-FCM-10.
Problem
launchRuntime() called checkSoul() before runtime execution. A missing top-level SOUL.md
caused checkSoul() to spawn a child mosaic wizard with inherited stdio. Under a systemd-created
fleet pane with no TTY, that child blocked or failed before the runtime boundary even though generic
defaults/SOUL.md and defaults/USER.md already shipped in the same MOSAIC_HOME.
Chosen boundary
The fix remains at checkSoul() and does not add flags to yolo, fleet commands, systemd units, or
start-agent-session.sh:
- A nonblank
MOSAIC_AGENT_NAMEselects the fleet path. resolveFleetIdentity()must resolve that exact member through the existing roster/helper boundary before any identity seed.- Safe bounded snapshots are read from only the missing contracts under
defaults/. - Each snapshot is written to a random owner-private temporary file in
MOSAIC_HOME. linkSync()publishes the complete file without overwriting an existing path.EEXISTmeans a concurrent seat or operator won; the existing path is preserved and revalidated.- Temporary files are removed, and both installed contracts are re-opened through the no-symlink secure-file reader before launch continues.
composeContract()independently re-resolves the roster and injects exact member identity and communications data.
A standalone launch with no MOSAIC_AGENT_NAME retains the interactive wizard.
Identity and authority
The copied defaults deliberately say “Mosaic agent”; they are a generic behavioral base. They are not the source of a fleet seat's identity. The canonical roster controls:
- exact agent/session name;
- canonical role/class and persona;
- peer rows and point of contact;
- tmux socket and helper target; and
- communications generation.
An unknown ambient name fails before any file is seeded. This avoids replacing the interactive wall with a fleet of indistinguishable or ambiently invented identities.
Concurrency and filesystem properties
- Sources and final destinations are bounded regular files beneath
MOSAIC_HOME; symlinks are not followed. - New files have mode
0600. - Hard-link publication is same-filesystem, atomic, and no-clobber.
- A temporary path is removed only when this process successfully created it.
- All required source snapshots are validated before the first destination is published, preventing a missing second default from leaving a partial seed.
- Existing operator files are never chmodded or rewritten.
Verification
src/commands/launch-first-start.spec.ts uses the production-kind boundary: the real built CLI in a
no-TTY subprocess, not a direct wizard test. A fake lease launcher records whether execution reached
the runtime boundary and captures the composed prompt. Positive and negative cases prove the check
can both proceed and refuse.
Real Pi authentication and provider task execution remain environment tests, not claims of this fixture.
Non-goals
- Runtime installation or pane-PATH resolution (#1256/#1258).
- The held
~/.mosaiclaunch-composition layer in PR #1213. - Personalizing the operator's standalone identity without a wizard.
- Changing fleet systemd or shell launcher code.