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
32 lines
1.7 KiB
Desktop File
32 lines
1.7 KiB
Desktop File
[Unit]
|
|
# Mosaic wake DETECTOR daemon (A1/W7 of the wake canon, EPIC #892). A LONG-LIVED
|
|
# single-instance detector: tools/wake/detector.sh run. This is a SERVICE, not a
|
|
# timer — the per-class SLO lives INSIDE the daemon's run-loop (WAKE_DETECTOR_INTERVAL
|
|
# poll cadence + the per-cycle off-host beacon emit), never as a systemd
|
|
# OnUnitActiveSec interval. The blank-reset cadence idiom therefore does NOT apply
|
|
# to this unit; it applies only to the legacy mosaic-heartbeat@ timer during retire.
|
|
Description=Mosaic wake detector daemon (framework tools/wake/detector.sh run)
|
|
After=default.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
# Strip loader / noninteractive-shell controls before ExecStart, matching the
|
|
# lease-broker and tmux fleet units in this same directory (defense-in-depth
|
|
# against an injected BASH_ENV/ENV/LD_PRELOAD in the user manager environment).
|
|
UnsetEnvironment=LD_PRELOAD BASH_ENV ENV
|
|
# Operator-owned runtime configuration. This EnvironmentFile carries only the
|
|
# WAKE_* NAMES and the pluggable adapter COMMANDS (the off-host beacon/alarm sink
|
|
# and the HMAC key NAME) — NEVER the HMAC key material and NEVER the alarm
|
|
# endpoint value. Both are resolved BY NAME at runtime via load_credentials, so
|
|
# no secret and no endpoint is ever written into this unit. The installer's
|
|
# fail-closed install-validate (wake-install.sh validate-targets) is what proves
|
|
# the required names are configured + reachable BEFORE this unit is enabled; the
|
|
# '-' prefix keeps a missing file from masking that dedicated validation.
|
|
EnvironmentFile=-%h/.config/mosaic/wake/detector.env
|
|
ExecStart=/bin/bash --noprofile --norc %h/.config/mosaic/tools/wake/detector.sh run
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=default.target
|