fix(wake): #925 framework-ship canon fallback-wake (systemd timer + schema bound + A10 install/validate) — F7 out of the box
Some checks failed
ci/woodpecker/pr/ci Pipeline failed
Some checks failed
ci/woodpecker/pr/ci Pipeline failed
Framework-ship the canon-side FALLBACK WAKE (F7 replacement-before-retirement) so hosts get it out of the box instead of hand-wiring it per host. ADDITIVE; honors #869 / Gate A/B discipline. 1. New framework units systemd/user/mosaic-wake-fallback.{timer,service}: a low-frequency SAFETY drain (oneshot service running the canon drain `digest.sh render --from-store`) fired by a per-class cadence timer, INDEPENDENT of the event-driven detector, so a stalled detector/daemon can never silently starve delivery. Owned via the existing `systemd/**` glob in framework-manifest.txt (Gate A) — no new owned path, no second authority. 2. Optional additive per-class `fallback_cadence` bound in wake-watch-list.schema.json (config, not code). Backward-compatible within schema_version 1, so [schema_min, schema_max] stays [1,1] and the detector's Gate B range check is unchanged. 3. A10 wake-install.sh enumerates + links + validates the two units into the user systemd search path (idempotent, fail-closed); write-fallback-cadence writes the per-class cadence as a blank-reset drop-in (exactly one effective OnUnitActiveUSec). 4. F7 install-validate: the §5 legacy reap now REFUSES unless the canon fallback wake is proven live (installed + schedulable floor always; enabled + proven-firing when a live user manager is probeable, mirroring #913). Red-first: test-wake-install.sh I11 (F7 reap-refuses-without-live-fallback), I12 (stalled detector still drains), I13 (install links+validates units), I14 (per-class cadence blank-reset = exactly one); test-wake-detector.sh D9 (optional fallback_cadence in-range accepted; out-of-range still fails loud). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0158NZqN2n2ymKFeJAZ4GUCb
This commit is contained in:
@@ -398,6 +398,53 @@ EOF
|
||||
"$STORE" consume --upto 6 >/dev/null 2>&1 || fail_msg "D8: CONSUMED 6 must succeed over the contiguous prefix after the delta"
|
||||
) && ok
|
||||
|
||||
echo "== D9: schema (#925) — optional per-class fallback_cadence is BACKWARD-COMPAT (in-range accepted; out-of-range still FAILS LOUD, Gate B intact) =="
|
||||
(
|
||||
WAKE_STATE_HOME="$(fresh_state d9)"
|
||||
export WAKE_STATE_HOME
|
||||
unset WAKE_AGENT
|
||||
stub="$TMP_ROOT/d9stub"
|
||||
mkdir -p "$stub"
|
||||
make_stub "$stub"
|
||||
export WAKE_DETECTOR_SOURCE_CMD="$stub/adapter.sh"
|
||||
printf 'SHA-D9\n' >"$stub/repo_r1"
|
||||
printf '## LANE-X\nx\n' >"$stub/board_file_b1"
|
||||
# A watch-list that EXERCISES the new optional additive field: a per-class
|
||||
# `fallback_cadence` under an slos tier, at schema_version 1. Because the field is
|
||||
# OPTIONAL + additive, an existing schema_version-1 watch-list stays valid and the
|
||||
# detector's Gate B range [schema_min, schema_max] is UNCHANGED — the new field
|
||||
# must NOT push the watch-list out of range.
|
||||
wl="$TMP_ROOT/d9.json"
|
||||
write_fc_watchlist() {
|
||||
local file="$1" ver="$2"
|
||||
cat >"$file" <<EOF
|
||||
{
|
||||
"schema_version": $ver,
|
||||
"slos": {
|
||||
"actionable-tier": { "class": "actionable", "fallback_bound": "30m", "fallback_cadence": "1h" }
|
||||
},
|
||||
"repos": [{ "id": "r1", "remote": "example/repo", "class": "digest" }],
|
||||
"board_files": [{ "id": "b1", "path": "BOARD.md", "anchor": "## LANE-X" }],
|
||||
"watches": [
|
||||
{ "lane": "lane-x", "sources": [
|
||||
{ "kind": "repo", "id": "r1" },
|
||||
{ "kind": "board_file", "id": "b1" }
|
||||
] }
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
# (a) in-range (schema_version 1) WITH fallback_cadence -> ACCEPTED.
|
||||
write_fc_watchlist "$wl" 1
|
||||
export WAKE_WATCH_LIST="$wl"
|
||||
"$DET" poll-once >/dev/null 2>&1 || fail_msg "D9: an in-range watch-list carrying the optional fallback_cadence must be ACCEPTED (additive/backward-compatible)"
|
||||
# (b) out-of-range (schema_version 999) WITH the SAME field -> STILL FAILS LOUD.
|
||||
write_fc_watchlist "$wl" 999
|
||||
err="$("$DET" poll-once 2>&1)"; rc=$?
|
||||
[ "$rc" -ne 0 ] || fail_msg "D9: the new field must NOT weaken Gate B — an out-of-range schema_version must still FAIL LOUD (rc=$rc)"
|
||||
echo "$err" | grep -qi 'range' || fail_msg "D9: the out-of-range failure must still state it is out of the supported range [$err]"
|
||||
) && ok
|
||||
|
||||
echo
|
||||
if [ -s "$FAILFILE" ]; then
|
||||
echo "wake detector harness: FAILED ($(grep -c . "$FAILFILE") assertion(s))" >&2
|
||||
|
||||
Reference in New Issue
Block a user