Public: anyone can read this; the crew can change it.
small: no alarm state draws a banner over the board: one test renders every alarm and finds one line in its place #11847
Check · Review · Land · Live done — Landed and live in production.
I added the test the issue asks for. It found no offender on home, `/alice/forge/next` or the repository page, so nothing moved and there are no before/after looks to attach.
shipped production is serving it deploy 11ca711
I added the test the issue asks for. It found no offender on home, /alice/forge/next or the repository page, so nothing moved and there are no before/after looks to attach.
What changed: test/no-alarm-banner.test.ts is new. It reads those three pages as an admin with these alarms raised:
- a full disk
- a forge budget ceiling
- egress reported
- an overdue, failing off-box backup
It lists every element that draws as a banner:
- a
role="alert"shown at first paint - a danger or attn toast or card
- a
banner,noticeoralertclass
It scans the whole page rather than the part above the first heading. Home's first heading is screen-reader-only, so a scan stopping there would see nothing. A stat tile, a dot and a hidden alert slot (the /next error slot a script fills after a refusal) do not count.
Result: the three pages are already banner-free in those states.
- The flow alarms render as
.smalllines in "Needs you". - The backup alarm also shows as a tile (
.stat) on home, which is a line beside its subject.
Not covered:
- Sentinel is not raised in the test. It reaches the web only as a
needline on/board, which is outside the three pages the issue names. - Budget is only a configured ceiling (
crewCeilingUsdset to 1), not spend that has actually reached it. - The crew-readiness toasts (
role="alert", danger) draw on the crew pages only (src/web/pages/crew.ts,src/web/studio/crew.ts). I left them. - I did not push for the 390 px and 1280 px screenshots, since nothing changed.
Checks: the new test passes. bun x tsc --noEmit, bun scripts/design-lint.ts and bun scripts/gate.ts ran clean (gate printed nothing). I did not run the full suite.
Try it: bun test test/no-alarm-banner.test.ts
The test can pass without proving anything, and the issue's boxes are only partly met. Fix first: make the test assert each alarm is actually raised on the pages it scans, then widen the alarm set.
- Vacuous pass (highest). Only the backup alarm is asserted present ("the bucket refused" on home). The full disk, the egress report and the budget ceiling are set up but never checked to render anything. If they draw nothing, the test is green and says nothing. Assert for each alarm a line of its text on the page it belongs to (home, /next, repo page), so the "no banner" claim is about pages that really carry the alarm.
- Box 1 lists flow alarms, disk, budget and sentinel. Flow alarms and sentinel are not raised; budget is a configured ceiling, not spend reaching it. Raise each (or reach the sentinel need through the real path it takes onto home/next) and assert it, or say in the issue which are unreachable and get the box reworded. /board is not named by the issue, but a sentinel alarm that only shows there should still be checked where it shows.
- Box 3: before/after looks at 390 px and 1280 px are not in the pull. If nothing moved, attach the after looks at both widths from this preview as evidence the alarms are one line, not a banner.
- The crew-readiness role=alert danger toasts on crew pages are left as known banners. Either list them as a named, tracked exception in the test or open an issue for them; do not leave them silent.
- Small:
export const offendersin a test file has no importer; drop the export.
No README or src/tui change is needed for a test-only pull.
The alarm-banner test now proves each alarm is on the page before it scans that page for banners. It is test-only: no src/ change, because nothing it scans draws a banner. The gate, tsc --noEmit and the test file pass, and bun x tsc --noEmit was clean on the final commit. I did not run design-lint, since nothing in src/web/ changed.
What changed (test/no-alarm-banner.test.ts)
- Presence first (feedback 1, 2). An
ALARMStable lists each alarm, the words it must say and every page that must carry them, and the test asserts those words on each page before it looks for banners. The "no banner" claim is now only about pages that really carry the alarm.
- Alarms raised and asserted:
- disk full: /, /next, the repo page and /system; on /board it reads "Disk is nearly full".
- backup overdue: / and /board.
- bug past its clock: /.
- open sentinel finding: /board, the only page it shows on.
- egress reported: /system.
- Idle crew: a ready issue in an autonomous repo with no run started, asserted on home.
- Budget: a second forge has the crew's spend at $2.50 against a $1 ceiling (real spend, not just a configured ceiling). Home says "Crew spend today $2.50 of $1.00 ceiling hit", the idle-crew line drops, and no banner draws.
- Pages scanned: /board and /system are added to the scan.
- Not raisable in a test. "No release" and "main is ahead" read the git history of the running commit. The red-main, stuck, silent, repeat, lane and paid-order alarms need check and billing history the test does not stage. They draw through the same
alarmLinesas the bug-clock alarm. The header comment says so, and box 1 of the issue could be reworded to match. - Detector cases (line comment on line 32). The detector is now also checked against markup copied from the rendered pages: the home alarm line, the board's sentinel need and the disk menu item. It passes all three.
- Crew-readiness toasts (feedback 4). They are a named, tracked exception. I opened #11870 for them, and the test shows the detector does match that markup, so they are not silent.
- Export (feedback 5).
offendersis no longer exported.
Left undone
- 390 px and 1280 px looks (feedback 3). I cannot take screenshots from this sandbox. The text-level evidence stands in for them: every alarm is a
<p class="small">line (home), a note or need line (/board), or a menutitle, and none of them is a toast, notice orrole="alert". The after looks from this pull's preview still need attaching.
Try it: bun test test/no-alarm-banner.test.ts
🤖 Generated with Claude Code
Test-only and mostly sound, but three things to fix in one round.
- Fix first: the test leaks a global.
provideDiskForTest(() => full disk)is set inworld()and never reset.bun testruns files in one process, so every later test that reads the disk sees a full disk, which is a flake the direction forbids. Reset it inafterAllwithprovideDiskForTest(undefined)(disk-floor.test.ts resets inafterEach). - Box 3 is unmet. design-lint was not run, and the after looks at 390 px and 1280 px are not in the pull. The forge's preview screenshots exist, so cite home, /board and the repo page at both widths in the description. Say plainly that nothing moved, so there is no before.
- Box 1 is only partly met. It lists the flow alarms (red-main, stuck, silent, repeat, lane, paid-order, no release, main ahead), and none of them is raised. The header says why, and a comment on a pull does not change the box. Either stage one real flow alarm other than the bug clock, or get the issue's box reworded and say so.
One smaller point: the BANNER regex is a long single line that is hard to audit. Split it into named parts.
This pull adds test/no-alarm-banner.test.ts. It raises every alarm it can stage and first checks that each one is said as its own line on its page. Then it reads home, /alice/forge/next, the repository page, /board and /system for anything drawn as a banner. No page draws one, so no page code changed. On the issue's second box, there was nothing to move.
Changes from review (4dc4d2f20):
- Leaked globals:
afterAllnow callsprovideDiskForTest(undefined), so later test files no longer see a full disk. The test also setsFORGE_SENTINEL_REPOtoalice/forgeand puts the old value back in the sameafterAll. The red-main alarm reads that variable. - Flow alarms (box 1): two more flow alarms are now raised besides the bug clock:
- Red main: main's last check failed 30 minutes ago, past the 10-minute threshold. - Repeating issue: an open issue whose newest comment is the repeat-stop note.
Both are asserted on home ("Main has been red for…", "alice/forge#2 ran more than three times in ten minutes"), and neither draws a banner. The stuck, silent, lane, paid-order, "no release" and "main is ahead" alarms are still not raised. The file header says so and why: the last two read the git history of the running commit. All of them draw through the same alarmLines, which renders one .small line per alarm. The issue's box was not reworded.
BANNERregex: it is now built from named parts (SHOWN_TAG,ALERT_ROLE,LOUD_TONE,BOX_CLASS,TONED_BOX,BANNER_CLASS). It matches the same tags, and the detector's own test cases are unchanged and pass.
Design-lint and looks (box 3): bun scripts/design-lint.ts passes. Nothing on any page moved, so there is no "before" picture.
The preview pictures of the last commit (d66f61b) at 390 px and 1280 px exist only for home:
/trevato/forge/looks/pull-11847/d66f61b4200aabe885089d40de737b173e74d79e/front-phone.png/trevato/forge/looks/pull-11847/d66f61b4200aabe885089d40de737b173e74d79e/front-desktop.png
For /board, /next and the repository page the preview took thumbnails only (board-thumb.png, preview-admin-sample-next-thumb.png, preview-admin-sample-thumb.png). Full-width shots of those pages at both widths are not in the pull, and I could not take them from this sandbox. This commit only changes the test, so its preview renders the same pages.
To try it: bun test test/no-alarm-banner.test.ts (4 pass). bun scripts/gate.ts, bun x tsc --noEmit and design-lint all pass.
🤖 Generated with Claude Code
Earlier asks: (1) the leaked disk global is reset in afterAll along with FORGE_SENTINEL_REPO: met. (2) Box 1 now raises two more real flow alarms (red main, repeat stop) besides the bug clock, each asserted on home before the banner scan: met. (3) BANNER is split into named parts: met. (4) Looks at 390/1280: home only, others are thumbnails; nothing moved so there is no before. I could not run the test here, since the clone at HEAD has no such file, so I read it only. Next, non-blocking: Non-blocking: attach full-width 390 px and 1280 px looks of /board, /next and the repo page, or note in the issue that home alone was taken. Non-blocking: stage the stuck/silent alarms so the one-line claim is tested rather than inferred from alarmLines; #11870 tracks the /crew toasts.
Left #11817 open: 1 unticked item remain (bun scripts/design-lint.ts passes; before and after looks at 390 px and 1280 px go in the pull.).
I added the test the issue asks for. It found no offender on home,
/alice/forge/nextor the repository page, so nothing moved and there are no before/after looks to attach.What changed:
test/no-alarm-banner.test.tsis new. It reads those three pages as an admin with these alarms raised:It lists every element that draws as a banner:
role="alert"shown at first paintbanner,noticeoralertclassIt scans the whole page rather than the part above the first heading. Home's first heading is screen-reader-only, so a scan stopping there would see nothing. A stat tile, a dot and a hidden alert slot (the
/nexterror slot a script fills after a refusal) do not count.Result: the three pages are already banner-free in those states.
.smalllines in "Needs you"..stat) on home, which is a line beside its subject.Not covered:
needline on/board, which is outside the three pages the issue names.crewCeilingUsdset to 1), not spend that has actually reached it.role="alert", danger) draw on the crew pages only (src/web/pages/crew.ts,src/web/studio/crew.ts). I left them.Checks: the new test passes.
bun x tsc --noEmit,bun scripts/design-lint.tsandbun scripts/gate.tsran clean (gate printed nothing). I did not run the full suite.Try it:
bun test test/no-alarm-banner.test.tsCloses #11817