# Fleet Generated Environment Boundary **Card:** FCM-M2-001 · **Issue:** #758 · **Status:** unreleased/card-local The local fleet roster is the desired-state authority. A launch reads a deterministic, roster-derived generated projection and an optional strictly data-only local file; neither file is a second roster or a command configuration surface. ## Paths and ownership For agent `` under `/fleet/agents/`: | Path | Owner | Purpose | | ----------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | | `.env.generated` | Mosaic projection writer | Complete deterministic launch data rendered from the authoritative roster. | | `.env.local` | Operator | Optional, constrained local machine data. It cannot shadow generated keys. | | `.env` | Legacy input only | Read once during projection generation, then regenerated/relocated or privately quarantined. It is never a launch authority. | | `.env.quarantine` | Mosaic quarantine | Mode-`0600` private record of forbidden legacy input; it is never read by the launcher. | The systemd templates do not load either environment file. They invoke Bash with a fixed, cleared bootstrap environment; the launcher reads and validates `.env.generated` and `.env.local` itself before it queries, creates, or stops an exact tmux session. It does not `source`, `eval`, or execute an environment-supplied command. Exact stop derives its socket from the same validated generated projection, not from systemd or ambient environment data. All projection, local, and quarantine files must be regular files with no group or world permissions. The agent environment directory must also be a real, non-symlink private directory; it is validated before either environment file is read or tmux is queried. Unsafe paths, symlinks, or permissions fail closed. Diagnostics identify only a rule code, key name, and SHA-256 content hash; they never print values, credential material, or command text. ## Allowed data `.env.generated` is complete and ordered exactly as follows: ```dotenv MOSAIC_AGENT_NAME= MOSAIC_AGENT_CLASS= MOSAIC_AGENT_RUNTIME= MOSAIC_AGENT_MODEL= MOSAIC_AGENT_REASONING= MOSAIC_AGENT_TOOL_POLICY= MOSAIC_AGENT_WORKDIR= MOSAIC_TMUX_SOCKET= ``` The generated launch contract supports only `claude`, `codex`, `opencode`, and `pi`. `fleet add` uses that same runtime authority and rejects any other runtime before it writes the roster or changes projection, local, or quarantine files. The legacy dogfood stub on its separate `mosaic-factory` socket remains an observability canary; it has no generated-launch adapter and cannot be added through this projection path. `.env.local` may contain only these non-secret data keys: - `MOSAIC_RUNTIME_BIN` - `MOSAIC_HEARTBEAT_RUN_DIR` - `MOSAIC_HEARTBEAT_INTERVAL` - `MOSAIC_CLAUDE_JSON` - `CLAUDE_CONFIG_DIR` Local paths must be safe absolute paths and the interval must be a positive integer. Comments, quoted/export syntax, duplicate keys, unknown keys, generated-key shadowing, sensitive key names, and `MOSAIC_AGENT_COMMAND` are rejected. The launcher derives the only executable command from the validated runtime, model, and reasoning data; no arbitrary command compatibility path exists. When a Pi runtime writes a fresh `.hb.native` marker, its native heartbeat remains authoritative; the shell sidecar resumes its `status=ok` fallback only after that marker is stale or absent. ## Legacy disposition During projection generation, legacy roster-derived keys are regenerated from the roster. A valid allowed local value is relocated to `.env.local`; forbidden, malformed, duplicate, sensitive, and unknown legacy entries cause the legacy file to be moved to `.env.quarantine` and are represented by sanitized diagnostics. This is deterministic and idempotent after the legacy file has been consumed. ## USC interface packet This card does not add a USC site file, write a USC roster, or run a site canary. The following is the consolidated downstream interface packet. Status is deliberately separated from checkout presence: no product release version has been evidenced for this interface set. | Interface | Canonical public path and version | Tracker/release status | Downstream limit | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | | M1 structural compiler | `parseRosterV2` in `packages/mosaic/src/fleet/roster-v2.ts`; schema `docs/fleet/reference/roster-v2.schema.json`; roster `version: 2` | FCM-M1-001 is recorded done, merged as #764 (`aa5b43b`); no released product version is asserted here. | Parse YAML/JSON and canonicalize a supplied v2 site roster without writes. | | M1 semantic resolver | `validateRosterV2Semantics` in `packages/mosaic/src/fleet/roster-v2.ts`; baseline `framework/fleet/roles/` plus `roles.local/` | FCM-M1-002 remains `in-progress` in `docs/TASKS.md`; unreleased. | Reuse the shared resolver only; no parallel role resolver or lifecycle action. | | M1 disposition evidence | `packages/mosaic/src/fleet/example-profile-dispositions.ts`; `docs/fleet/migration/example-profile-disposition.md`; retained fixture `version: 1` | FCM-M1-003 remains `not-started` in `docs/TASKS.md`; unreleased even though these checkout artifacts are inspectable. | Inspect fixture/profile/service disposition evidence only; it is not migration authorization. | | M2 generated boundary | `packages/mosaic/src/fleet/generated-env-boundary.ts`; generated projection contract in this document | FCM-M2-001 card-local and uncommitted; unreleased. | Render/write a roster-derived projection; local input is never authority. | The canonical source remains `/fleet/roster.yaml` for the current local fleet path. Generated environment data is a rebuildable projection, not an operator-editable source of membership, runtime policy, or lifecycle state. **Corrected downstream gates:** M2 supplies only parse/validation/projection evidence and does not permit a USC site canary, reconciliation, or lifecycle mutation. M3 must first define and validate the canonical local reconcile/lifecycle path. M4 then supplies preview/migration and its separate canary/rollback gates; only after those M3 and M4 gates may a site migration or canary be considered. This card authorizes none of those actions.