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.
What
Framework unitssystemd/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 ownership authority.
Schema bound: optional additive per-class fallback_cadence 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 (out-of-range still fails loud).
A10 install/wire: wake-install.sh enumerates + links + validates both units into the user systemd search path (idempotent, fail-closed, same link-to-SSOT pattern as the detector unit); write-fallback-cadence writes the per-class cadence as a blank-reset drop-in (exactly one effective OnUnitActiveUSec).
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 (mirrors #913's opportunistic WAKE_VERIFY_USE_SYSTEMCTL). F7 is encoded in the installer, not operator memory.
Red-first
test-wake-install.sh I11 F7: reap refuses without a proven-live fallback (legacy left running — no coverage gap), succeeds once provisioned. I12 stalled detector still gets delivery via the fallback drain. I13 install links+validates the units. I14 per-class cadence blank-reset = exactly one OnUnitActiveUSec (negative control leaks two).
test-wake-detector.sh D9: in-range watch-list carrying fallback_cadence accepted; out-of-range schema_version still fails loud (Gate B intact).
ADDITIVE only; path-ownership stays the single framework-manifest.txt SSOT — new units owned via the existing systemd/** glob (resolver confirmed framework-owned; parity 17 green). No second ownership authority.
Zero touch to install-ordering-guard / lease-broker enforcement wiring (guard spec 19 green).
Gate B: schema range unchanged at [1,1]; detector fails-loud out-of-range.
Gates
shellcheck 0.11 clean; verify-sanitized PASS; systemd-analyze verify rc=0 on both units; full test:framework-shell rc=0 (normal AND openssl-masked, I8 skips cleanly); vitest parity(17)/manifest(34)/install-ordering-guard(19) green; prettier clean; firewall grep=0 on diff; wake manifest.txt bumped 0.6.7 → 0.6.8.
Closes #925; Part of #892.
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.
## What
1. **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 ownership authority.
2. **Schema bound**: optional additive per-class `fallback_cadence` 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 (out-of-range still fails loud).
3. **A10 install/wire**: wake-install.sh enumerates + links + validates both units into the user systemd search path (idempotent, fail-closed, same link-to-SSOT pattern as the detector unit); `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 (mirrors #913's opportunistic `WAKE_VERIFY_USE_SYSTEMCTL`). F7 is encoded in the installer, not operator memory.
## Red-first
- test-wake-install.sh **I11** F7: reap refuses without a proven-live fallback (legacy left running — no coverage gap), succeeds once provisioned. **I12** stalled detector still gets delivery via the fallback drain. **I13** install links+validates the units. **I14** per-class cadence blank-reset = exactly one OnUnitActiveUSec (negative control leaks two).
- test-wake-detector.sh **D9**: in-range watch-list carrying `fallback_cadence` accepted; out-of-range schema_version still fails loud (Gate B intact).
## #869 / Gate A/B
- ADDITIVE only; path-ownership stays the single framework-manifest.txt SSOT — new units owned via the existing `systemd/**` glob (resolver confirmed framework-owned; parity 17 green). No second ownership authority.
- Zero touch to install-ordering-guard / lease-broker enforcement wiring (guard spec 19 green).
- Gate B: schema range unchanged at [1,1]; detector fails-loud out-of-range.
## Gates
shellcheck 0.11 clean; verify-sanitized PASS; systemd-analyze verify rc=0 on both units; full test:framework-shell rc=0 (normal AND openssl-masked, I8 skips cleanly); vitest parity(17)/manifest(34)/install-ordering-guard(19) green; prettier clean; firewall grep=0 on diff; wake manifest.txt bumped 0.6.7 → 0.6.8.
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 <[email protected]>
Claude-Session: https://claude.ai/code/session_0158NZqN2n2ymKFeJAZ4GUCb
#931 CI (node:24-alpine, musl/BusyBox) went RED: the I14 blank-reset assertion
used `grep -qz` (NUL-data), a GNU-only extension BusyBox grep does NOT support
(its option list is -HhnlLoqvsrRiwFE -m -A -B -C -e -f — no -z). BusyBox grep
printed usage + exited non-zero, tripping `|| fail_msg`. Passed locally only
because GNU grep has -z. Toolchain-divergence class (cf. #912, BusyBox sed).
Fix (test-only; product drop-in is correct, verify-single already proves
exactly-one): assert the blank-reset FORM portably — `grep -A1 '^OnUnitActiveSec=$'
| grep -qx 'OnUnitActiveSec=30min'` still requires the empty reset line
IMMEDIATELY followed by the value, and still catches the negative control. Also
simplified a sibling `grep -qi 'EXACTLY ONE\|exactly one'` to `grep -qi 'exactly
one'` (drop the BRE alternation; -i already covers case).
Sweep of all packages/mosaic/framework/tools/wake/test-*.sh for BusyBox-
incompatible constructs (grep -z/-P, sed \xNN/\b/-i, gawk-isms, date -d/%N):
the only #931-introduced defect was this one. Verified in the real Alpine image
(node:24-alpine, BusyBox v1.37.0): all 9 wake harnesses + full test:framework-
shell green under BusyBox with CI=woodpecker (openssl present, I8 HMAC leg runs).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_0158NZqN2n2ymKFeJAZ4GUCb
Product review: independent reviewer ae774fee (opus, ≠ builder mosaic-coder) at 8de52b7b → criteria 1-6 PASS, REPRODUCED (3/4/5 by hand): well-formed timer+service (systemd-analyze verify rc=0, no inlined secret/endpoint); ★ F7 install-validate — reap REFUSES without a live fallback (reproduced: no-fallback→rc=1 legacy-left-running; provisioned→retired; gate-bypass→RED); blank-reset drop-in = exactly one OnUnitActiveUSec (reproduced + negative control); stalled-detector still drains via the fallback (reproduced); Schema Gate B — optional additive fallback_cadence, schema_min/max UNCHANGED [1,1], out-of-range still fail-loud; #869 additive / Gate A — new units owned via the single framework-manifest.txtsystemd/** glob (no 2nd authority), parity 17/17 + install-ordering-guard 19/19 green, install.sh additive-only. Reviewers ONLY blocker was criterion 7 (CI test-gate RED).
Criterion 7 fix + delta-re-review (MS-LEAD, git-verified): the RED was a PR-introduced TEST-portability defect — I14 used grep -qz, unsupported by the Alpine BusyBox grep on the CI image (toolchain-divergence, cf. OB bee9d29b / #912 BusyBox sed). PRODUCT CODE CORRECT (verify-single independently proves exactly-one). Corrective delta 8de52b7b..a41662f0 = ONE commit, ONLY test-wake-install.sh (I14 → grep -A1 ^OnUnitActiveSec=$ | grep -qx OnUnitActiveSec=30min, BusyBox-portable, still asserts the blank-reset ordering + catches the negative control). Criteria 1-6 UNCHANGED → carry. Builder verified in the REAL BusyBox image (node:24-alpine v1.37.0, CI=woodpecker): all 9 wake harnesses + full test:framework-shell GREEN. Sweep: the grep -qz was the only #931-introduced defect (digest-hmac grep -P hits are #912-handled comments); 2 pre-existing GUARDED date GNU-isms in test-wake-store-ack.sh reported (currently pass BusyBox, non-blocking).
6-check — GO
open/mergeable base main ✓ · 2. CI TERMINAL-GREEN @ full-40 a41662f03370349375020aee24e49d9be43c1f0a ✓ · 3. reviewer(ae774fee)≠builder 1-6 + MS-LEAD delta-re-review resolving 7, durable RoR ✓ · 4. reviewed==CI==merge-head all a41662f0 ✓ · 5. body Closes #925 + Part of #892 ✓ · 6. queue-guard at merge. GO for id-11 + squash-merge at FULL-40 a41662f03370349375020aee24e49d9be43c1f0a. Closes#925 (framework fallback-wake, F7 replacement-before-retirement out of the box: timer+service + optional fallback_cadence schema bound + A10 install/link/validate with the reap-refuses-without-live-fallback F7 gate). Non-executor.
# Record of Review — PR #931 (issue #925): framework fallback-wake (F7) — FINAL, CI-GREEN (corrective head)
**VERDICT: APPROVE — GO.** **REVIEWED-HEAD (full-40):** `a41662f03370349375020aee24e49d9be43c1f0a`. **CI: TERMINAL-GREEN** (pipeline 2084, corrective head).
## Review basis (product APPROVE 1-6 + delta-re-review resolving 7)
- **Product review:** independent reviewer `ae774fee` (opus, ≠ builder `mosaic-coder`) at `8de52b7b` → **criteria 1-6 PASS, REPRODUCED** (3/4/5 by hand): well-formed timer+service (`systemd-analyze verify` rc=0, no inlined secret/endpoint); **★ F7 install-validate — reap REFUSES without a live fallback** (reproduced: no-fallback→rc=1 legacy-left-running; provisioned→retired; gate-bypass→RED); blank-reset drop-in = exactly one `OnUnitActiveUSec` (reproduced + negative control); stalled-detector still drains via the fallback (reproduced); Schema Gate B — optional additive `fallback_cadence`, schema_min/max UNCHANGED [1,1], out-of-range still fail-loud; **#869 additive / Gate A** — new units owned via the single `framework-manifest.txt` `systemd/**` glob (no 2nd authority), parity 17/17 + install-ordering-guard 19/19 green, install.sh additive-only. Reviewers ONLY blocker was criterion 7 (CI test-gate RED).
- **Criterion 7 fix + delta-re-review (MS-LEAD, git-verified):** the RED was a PR-introduced TEST-portability defect — I14 used `grep -qz`, unsupported by the Alpine BusyBox grep on the CI image (toolchain-divergence, cf. OB `bee9d29b` / #912 BusyBox sed). PRODUCT CODE CORRECT (verify-single independently proves exactly-one). Corrective delta `8de52b7b..a41662f0` = ONE commit, ONLY `test-wake-install.sh` (I14 → `grep -A1 ^OnUnitActiveSec=$ | grep -qx OnUnitActiveSec=30min`, BusyBox-portable, still asserts the blank-reset ordering + catches the negative control). Criteria 1-6 UNCHANGED → carry. Builder verified in the REAL BusyBox image (node:24-alpine v1.37.0, CI=woodpecker): all 9 wake harnesses + full test:framework-shell GREEN. Sweep: the `grep -qz` was the only #931-introduced defect (digest-hmac `grep -P` hits are #912-handled comments); 2 pre-existing GUARDED `date` GNU-isms in test-wake-store-ack.sh reported (currently pass BusyBox, non-blocking).
## 6-check — GO
1. open/mergeable base main ✓ · 2. **CI TERMINAL-GREEN @ full-40 `a41662f03370349375020aee24e49d9be43c1f0a`** ✓ · 3. reviewer(`ae774fee`)≠builder 1-6 + MS-LEAD delta-re-review resolving 7, durable RoR ✓ · 4. reviewed==CI==merge-head all `a41662f0` ✓ · 5. body `Closes #925` + `Part of #892` ✓ · 6. queue-guard at merge.
**GO for id-11 + squash-merge at FULL-40 `a41662f03370349375020aee24e49d9be43c1f0a`. Closes #925 (framework fallback-wake, F7 replacement-before-retirement out of the box: timer+service + optional `fallback_cadence` schema bound + A10 install/link/validate with the reap-refuses-without-live-fallback F7 gate). Non-executor.**
Ghost
approved these changes 2026-07-26 13:44:49 +00:00
GO — Gate-16 id-11 stamp, pinned to exact FULL head a41662f033.
Basis: verbatim FINAL RoR (comment 19263) — product review ae774fee APPROVE on criteria 1-6 (reproduced: the F7 reap-gate REFUSES retirement without a live-proven fallback, blank-reset drop-in form, stalled-drain fallback, #869-additive, schema Gate-B) carrying through the delta-re-review that resolved criterion 7 (corrective delta = only the I14 BusyBox-portability test fix, verified green in the real node:24-alpine image — the fifth toolchain-divergence instance, caught because the review read real CI per doctrine). Closes#925: F7's replacement-before-retirement now ships out-of-the-box — future hosts get the fallback wake installed, validated, and proven-firing as a machine precondition of legacy reap, not operator memory. Part of #892. Named executor: Mos (id-11), squash pinned.
GO — Gate-16 id-11 stamp, pinned to exact FULL head a41662f03370349375020aee24e49d9be43c1f0a.
Basis: verbatim FINAL RoR (comment 19263) — product review ae774fee APPROVE on criteria 1-6 (reproduced: the F7 reap-gate REFUSES retirement without a live-proven fallback, blank-reset drop-in form, stalled-drain fallback, #869-additive, schema Gate-B) carrying through the delta-re-review that resolved criterion 7 (corrective delta = only the I14 BusyBox-portability test fix, verified green in the real node:24-alpine image — the fifth toolchain-divergence instance, caught because the review read real CI per doctrine). Closes #925: F7's replacement-before-retirement now ships out-of-the-box — future hosts get the fallback wake installed, validated, and proven-firing as a machine precondition of legacy reap, not operator memory. Part of #892. Named executor: Mos (id-11), squash pinned.
Ghost
merged commit 17087efe15 into main2026-07-26 13:44:52 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #925; Part of #892.
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.
What
systemd/user/mosaic-wake-fallback.{timer,service}: a low-frequency SAFETY drain (oneshot service running the canon draindigest.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 existingsystemd/**glob in framework-manifest.txt (Gate A) — no new owned path, no second ownership authority.fallback_cadencein 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 (out-of-range still fails loud).write-fallback-cadencewrites the per-class cadence as a blank-reset drop-in (exactly one effective OnUnitActiveUSec).WAKE_VERIFY_USE_SYSTEMCTL). F7 is encoded in the installer, not operator memory.Red-first
fallback_cadenceaccepted; out-of-range schema_version still fails loud (Gate B intact).#869 / Gate A/B
systemd/**glob (resolver confirmed framework-owned; parity 17 green). No second ownership authority.Gates
shellcheck 0.11 clean; verify-sanitized PASS; systemd-analyze verify rc=0 on both units; full test:framework-shell rc=0 (normal AND openssl-masked, I8 skips cleanly); vitest parity(17)/manifest(34)/install-ordering-guard(19) green; prettier clean; firewall grep=0 on diff; wake manifest.txt bumped 0.6.7 → 0.6.8.
Record of Review — PR #931 (issue #925): framework fallback-wake (F7) — FINAL, CI-GREEN (corrective head)
VERDICT: APPROVE — GO. REVIEWED-HEAD (full-40):
a41662f03370349375020aee24e49d9be43c1f0a. CI: TERMINAL-GREEN (pipeline 2084, corrective head).Review basis (product APPROVE 1-6 + delta-re-review resolving 7)
ae774fee(opus, ≠ buildermosaic-coder) at8de52b7b→ criteria 1-6 PASS, REPRODUCED (3/4/5 by hand): well-formed timer+service (systemd-analyze verifyrc=0, no inlined secret/endpoint); ★ F7 install-validate — reap REFUSES without a live fallback (reproduced: no-fallback→rc=1 legacy-left-running; provisioned→retired; gate-bypass→RED); blank-reset drop-in = exactly oneOnUnitActiveUSec(reproduced + negative control); stalled-detector still drains via the fallback (reproduced); Schema Gate B — optional additivefallback_cadence, schema_min/max UNCHANGED [1,1], out-of-range still fail-loud; #869 additive / Gate A — new units owned via the singleframework-manifest.txtsystemd/**glob (no 2nd authority), parity 17/17 + install-ordering-guard 19/19 green, install.sh additive-only. Reviewers ONLY blocker was criterion 7 (CI test-gate RED).grep -qz, unsupported by the Alpine BusyBox grep on the CI image (toolchain-divergence, cf. OBbee9d29b/ #912 BusyBox sed). PRODUCT CODE CORRECT (verify-single independently proves exactly-one). Corrective delta8de52b7b..a41662f0= ONE commit, ONLYtest-wake-install.sh(I14 →grep -A1 ^OnUnitActiveSec=$ | grep -qx OnUnitActiveSec=30min, BusyBox-portable, still asserts the blank-reset ordering + catches the negative control). Criteria 1-6 UNCHANGED → carry. Builder verified in the REAL BusyBox image (node:24-alpine v1.37.0, CI=woodpecker): all 9 wake harnesses + full test:framework-shell GREEN. Sweep: thegrep -qzwas the only #931-introduced defect (digest-hmacgrep -Phits are #912-handled comments); 2 pre-existing GUARDEDdateGNU-isms in test-wake-store-ack.sh reported (currently pass BusyBox, non-blocking).6-check — GO
a41662f03370349375020aee24e49d9be43c1f0a✓ · 3. reviewer(ae774fee)≠builder 1-6 + MS-LEAD delta-re-review resolving 7, durable RoR ✓ · 4. reviewed==CI==merge-head alla41662f0✓ · 5. bodyCloses #925+Part of #892✓ · 6. queue-guard at merge.GO for id-11 + squash-merge at FULL-40
a41662f03370349375020aee24e49d9be43c1f0a. Closes #925 (framework fallback-wake, F7 replacement-before-retirement out of the box: timer+service + optionalfallback_cadenceschema bound + A10 install/link/validate with the reap-refuses-without-live-fallback F7 gate). Non-executor.GO — Gate-16 id-11 stamp, pinned to exact FULL head
a41662f033.Basis: verbatim FINAL RoR (comment 19263) — product review ae774fee APPROVE on criteria 1-6 (reproduced: the F7 reap-gate REFUSES retirement without a live-proven fallback, blank-reset drop-in form, stalled-drain fallback, #869-additive, schema Gate-B) carrying through the delta-re-review that resolved criterion 7 (corrective delta = only the I14 BusyBox-portability test fix, verified green in the real node:24-alpine image — the fifth toolchain-divergence instance, caught because the review read real CI per doctrine). Closes #925: F7's replacement-before-retirement now ships out-of-the-box — future hosts get the fallback wake installed, validated, and proven-firing as a machine precondition of legacy reap, not operator memory. Part of #892. Named executor: Mos (id-11), squash pinned.