Part of #5930, the flow alarm: nothing approved sits still. Today the steward's probe computes this outside the forge; the forge must own it.
Done:
[ ] src/flow/alarm_no_release.ts exports one function taking the app (or db) and now, answering { fired: boolean, since?: string, says: string }. It fires when main has moved and nothing has gone live for 90 min (read the release record /releases already reads). says is one plain sentence, e.g. "Main moved 2 h ago and nothing has gone live since 0.7.266."
[ ] A test covers fired and not fired: main moved 91 min after the last release fires; 89 min, or no move, does not. It fails without the file.
[ ] Nothing draws it yet; the banner is a separate issue. Keep to this one file and its test, so the four alarms land in parallel without touching each other.
Files: src/flow/alarm_no_release.ts, a test under test/.
Before pushing: bun x tsc --noEmit and the tests you add or touch; bun scripts/design-lint.ts if src/web/ changes. Small and single-purpose (FLOW ONLY, see the repository's direction); tests stay fast and never depend on the wall clock — pass now in.
Part of #5930, the flow alarm: nothing approved sits still. Today the steward's probe computes this outside the forge; the forge must own it.
Done:
now, answering{ fired: boolean, since?: string, says: string }. It fires when main has moved and nothing has gone live for 90 min (read the release record /releases already reads).saysis one plain sentence, e.g. "Main moved 2 h ago and nothing has gone live since 0.7.266."Files: src/flow/alarm_no_release.ts, a test under test/.
Before pushing:
bun x tsc --noEmitand the tests you add or touch;bun scripts/design-lint.tsif src/web/ changes. Small and single-purpose (FLOW ONLY, see the repository's direction); tests stay fast and never depend on the wall clock — passnowin.