From the 2026-09-10 repository review (R02), re-verified on v5.8.2. Ruling 2026-09-15: bound the fetch only; an engine-local emergency loop is deferred to gh-#265 (maintenance mode).
Problem. engine/genwave.liq:127:
safe = request.dynamic(id="safe_lib", prefetch=1, retry_delay=5., { request.create(list.hd(default="", process.read.lines("curl -s http://api:8080/internal/safe-track"))) })
No --connect-timeout, no --max-time. An API that accepts the TCP connection and never answers (DB wedged inside HandleSafeTrackAsync) blocks the safe source's request thread for as long as the kernel allows. The reviewer did not reproduce an audible outage; the dependency is source-confirmed.
Scope.
curl -sf --connect-timeout 2 --max-time 5 (numbers to be agreed); empty/malformed output already falls to request.create("") → mksafe.
- Log a distinct engine line when the safe fetch times out vs returns nothing, so the health surface can tell "API down" from "safe scope empty".
Acceptance.
- A stalled
/internal/safe-track degrades to mksafe within the bounded window and recovers when the API answers again.
- Smoke test (
tools/smoke_test.sh or the on-air gate) covers the stall case.
Non-goal here: a baked emergency asset under safe rotation. That is a /design question filed against gh-#265.
From the 2026-09-10 repository review (R02), re-verified on v5.8.2. Ruling 2026-09-15: bound the fetch only; an engine-local emergency loop is deferred to gh-#265 (maintenance mode).
Problem.
engine/genwave.liq:127:No
--connect-timeout, no--max-time. An API that accepts the TCP connection and never answers (DB wedged insideHandleSafeTrackAsync) blocks the safe source's request thread for as long as the kernel allows. The reviewer did not reproduce an audible outage; the dependency is source-confirmed.Scope.
curl -sf --connect-timeout 2 --max-time 5(numbers to be agreed); empty/malformed output already falls torequest.create("")→ mksafe.Acceptance.
/internal/safe-trackdegrades to mksafe within the bounded window and recovers when the API answers again.tools/smoke_test.shor the on-air gate) covers the stall case.Non-goal here: a baked emergency asset under safe rotation. That is a /design question filed against gh-#265.