Framework install machinery for the wake component (EPIC #892 W7, the last build slice). ADDITIVE per #869: adds an `install.sh --component wake` early dispatch that never enters the full-framework sync, never alters framework-manifest ownership behavior, and touches nothing the #869 install-ordering-guard covers (no runtime-asset linking, no lease-enforcement hook wiring). (i) Idempotent component-manifest install + Gate A (wake-install.sh install): the wake manifest.txt is VERSION METADATA ONLY; the component file set is INTERSECTED-AND-VALIDATED against the single SSOT framework-manifest.txt. A candidate the SSOT does not own is REFUSED fail-closed with no partial write. Re-running writes zero files (no diff). (ii) systemd/user/mosaic-wake.service — the long-lived detector daemon (detector.sh run). Per-class SLO lives inside the daemon, not a systemd interval; it is a SERVICE not a timer, so blank-reset does not apply. (iii) blank-reset idiom on the legacy mosaic-heartbeat@<agent>.timer cadence drop-in during the §5 overlap->retire lifecycle (empty OnUnitActiveSec= reset before the new value => exactly one OnUnitActiveUSec), with a reset->verify->retire acceptance path (retire LAST, only on §4-vector pass). (iv) snapshot-guard — a reap/clean-checkout of a deployed unit is REFUSED without a prior snapshot (the deployed-from-uncommitted failure class). (v) fail-closed alarm-target + HMAC-key install-validation (G1/G2a): the operator W6 alarm sink must be configured + reachable and the W3/W7 HMAC key must resolve BY NAME; missing/unreachable => FAIL LOUD. The installer ships/writes NO endpoint value and NO secret, and echoes neither. Red-first harness test-wake-install.sh (6 groups) wired into test:framework-shell; Gate-A parity extended to prove bash+TS both resolve the wake component paths framework-owned. wake component manifest bumped 0.5.0 -> 0.6.0. Part of #892 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0158NZqN2n2ymKFeJAZ4GUCb
Mosaic tmux Fleet PoC
This directory contains the first durable tmux-backed fleet primitives for the Mosaic software-factory model.
The lifecycle model follows the organization-neutral AI Guide playbook
mosaicstack/aiguide:playbooks/tmux-fleet.md (commit 2a0b0b5): a dedicated
holder owns the tmux server/socket; agent units join it and stop only their own
exact-match session.
Layout
mosaic-tmux-holder.service— user-mode holder that owns the named tmux server.mosaic-agent@.service— user-mode template for one reusable agent session.mosaic-interaction-agent@.service— generic Pi operator-interaction template that fails fast when its pinned runtime policy is incomplete or changed.test-fleet-units.sh— validates unit syntax and required relationships.
The agent template calls:
~/.config/mosaic/tools/fleet/start-agent-session.sh <agent-name>
which starts or reuses a tmux session on MOSAIC_TMUX_SOCKET.
Generated environment and local data
The roster-derived projection is written outside the package at:
~/.config/mosaic/fleet/agents/<agent>.env.generated
Systemd does not read either environment file. It starts the launcher with a fixed cleared bootstrap
environment; before it creates, queries, or stops an exact agent tmux session, start-agent-session.sh
strictly parses the generated projection and the optional local data file:
~/.config/mosaic/fleet/agents/<agent>.env.local
The local file may contain only safe machine-specific data (MOSAIC_RUNTIME_BIN, heartbeat paths or
interval, and Claude configuration paths). It cannot override roster-derived keys, carry a command,
or contain secret-like/unknown keys. Both files must be private regular files. Do not hand-edit the
generated projection; update the roster and regenerate it instead. A legacy <agent>.env is
consumed only for regeneration, strict relocation, or private quarantine and is never launch input.
See docs/fleet/reference/generated-env-boundary.md for the full contract.
Manual canary sequence
Use the roster and the supported installer; do not pre-create the agent environment directory or
edit a generated projection. mosaic fleet install validates the roster, installs the units and
helpers, and writes private roster-derived projections before any service is started.
# Create a site-owned canary roster. Inspect an existing roster before using --force.
mosaic fleet init --profile minimal --write
mosaic fleet install
systemctl --user daemon-reload
mosaic fleet start canary-pi
tmux -L mosaic-fleet ls
For an operator-interaction service, first put <agent-name> in the roster with the pinned Pi
runtime, model, reasoning, and operator-interaction tool policy. Re-run mosaic fleet install after
that roster change so it writes <agent-name>.env.generated; ambient MOSAIC_AGENT_* values are not
launch authority. The generic unit instance uses that generated identity, and no service source is
renamed for an instance:
mosaic fleet install
systemctl --user daemon-reload
systemctl --user start mosaic-interaction-agent@<agent-name>.service
~/.config/mosaic/tools/fleet/print-interaction-effective-policy.sh <agent-name>
Do not use tmux kill-server without -L mosaic-fleet; this pattern is meant
to avoid disturbing the user's default tmux server.