5.1 KiB
Framework-Layering Constraints for the Fleet Wake / Heartbeat-Efficiency Component
From: MS-LEAD (Matrix comms-evolution / framework-tooling lead)
To: heartbeat/wake-efficiency designers (via docs/scratchpads/heartbeat-planning/)
Date: 2026-07-25 · Purpose: one-page framework-layering input BEFORE design convergence
Grounded in: RFC-001 (MACP/Matrix-native) + RFC-002 (open-source install/config/topology), ~/agent-work/matrix-impl/
0. READ FIRST — the critical overlap (coherence, not duplication)
The wake/heartbeat-efficiency work and the MACP presence/heartbeat model are the SAME problem domain. RFC-001 §4.5 already defines a mosaic.presence heartbeat (fields: status, seq, interval_ms) whose age vs dark_threshold deterministically drives online/away/offline; §5 makes that same heartbeat the input to coordinator-dark escalation. P1 (PR #888) has this built and dev-proven (a hard-killed agent flips to offline within threshold, heartbeat-driven).
Recommendation: do NOT build a second, parallel heartbeat. Aim for one liveness substrate where a single heartbeat (a) drives presence, (b) feeds escalation, and (c) is the input to wake-efficiency scheduling. Wake-efficiency then = "schedule the next wake from liveness + pending-work signals" over the same heartbeat the presence layer already emits. Two competing heartbeats = drift, double the wasted wakes, and two sources of truth for "is this agent alive." Please align the heartbeat event schema + threshold keys with MACP (RFC-001 §4.5) — reuse interval_ms / dark_threshold naming so config and reasoning compose.
1. Framework vs product layering (RFC-002 §3)
- Boundary rule: framework owns the agent/harness contract + anything needed at spin BEFORE product code exists; product owns deployed services/libraries.
- A wake/heartbeat scheduler is agent-runtime-level → FRAMEWORK (
~/.config/mosaic/tools/+ a guide). It must run without/src/<product>present. - If it reads/writes shared fleet liveness, split cleanly: the framework tool operates on a framework-file layer by default, with an optional product-DB override when the product is reachable (see §3).
2. State location
- Framework/per-agent state →
~/.config/mosaic/(the established convention: tokens under~/.config/mosaic/secrets/, tool state under~/.config/mosaic/). Per-agent state that must survive a non-persistent shell goes on-disk here (mirrors thegit config mosaic.gitIdentitypersisted-per-worktree pattern from the identity patches). - Fleet-shared liveness → the product DB (Postgres), when present.
- Do not invent a third store. Framework file-plane + product DB-plane only.
3. Config schema conventions (RFC-002 §5)
- Precedence:
install-time → DB-override → compiled-default, with sane defaults compiled in so a bare install works. - Two config planes (state this explicitly): a framework tool runs before the product DB exists, so it needs a file-based framework config (
~/.config/mosaic/*.json, consistent with~/.claude/hooks-config.json/settings.jsonpatterns) plus the product DB as authoritative override when reachable. - Classify install-immutable vs runtime-tunable. Heartbeat cadence + thresholds (
interval_ms,miss_tolerance,dark_threshold, wake-min/max) are runtime-tunable — and should share keys with MACP's escalation thresholds (RFC-001 §5) so they're not defined twice.
4. Installer patterns (RFC-002 §6) — if it ships as an installable suite
- Guided installer: detect existing state → suggest (never silent-default) → immutable-vs-tunable gate → validate BEFORE declaring success.
- systemd timers are the sharp edge: any drop-in that overrides cadence MUST emit the
OnUnitActiveSec=blank-reset line on every override (this is literally batch item (4) — the ~88-wasted-wakes/day bug from a missing reset registering both timers). A wake-efficiency tool that gets this wrong recreates the exact bug it exists to solve. Treat the blank-reset as a hard invariant + a test.
5. #869 publish-gate + fail-closed discipline
- If the wake tool touches enforcement paths (lease/activation/timers that gate fleet behavior), the #869 publish-gate discipline applies: fail-closed, no silent fallthrough (cf. Patch 2b's fail-loud fix — an absent expected value must error, not silently degrade), and release/activation stays non-autonomous.
6. Coherence with tmux-P0
- Preserve the existing layering: tmux = P0 fast-path, Matrix/durable above it. Wake-efficiency should reduce wasted wakes without starving the presence heartbeat (same signal — §0). The win is fewer, better-timed wakes over one liveness model — not a new scheduling silo.
The prize: one coherent liveness/wake substrate — a single heartbeat that presence, escalation, and wake-efficiency all read — living in the framework layer, config in two planes (file + DB-override), thresholds shared with MACP, systemd blank-reset as a hard invariant. Happy to review the converging design against this and against RFC-001/002 directly.