feat(website): Queen HUD says why free bees are idle, round popover no longer crashes - #1030
Conversation
On 2026-09-15 the owner read "BEES 0/4" on #/queen as broken bees. The swarm was healthy_idle: the last round refused with "nothing to choose", 449 of 488 candidate issues had no ## Boundary, 12 were claimed and 27 were accepted but still open. /queen/status already carried all of it; the HUD did not say it. - queenHud.ts: idleReason() reads /queen/status alone (free slots from workers, the tick, the scheduler interval) and idleLine() words it. Free slots plus a refused round: the refusal, and for "nothing to choose" the three largest skip reasons with their wire counts. A tick older than two intervals (the server's TICK_STALENESS_INTERVALS) is called stale instead. A round that dispatched, no free slot, or an unreadable tick gives no line. A missing or malformed skipSummary gives the refusal alone, never a fabricated zero. - Queen.tsx: the BEES tile's sub-line carries the short head; a line under the map's head carries the full sentence and, for "nothing to choose", a link to gHashTag/t27#3587 as an example of an issue bees can take. en and ru copy; other refusals print the wire's own text. - The round popover crashed the page (React #31) on the real wire: each skipSummary entry is {count, issues, more}, and the list rendered the object. It now lists counts read through skipCounts(). - "3 ready" is dispatches.unreviewed: finished dispatch rows with no verdict, not issues ready to take. It reads "finished, no verdict"; the Russian copy says "no verdict", since the longer form was clipped in the 1440 px tile. - qa/queen-idle-reason-contract.mjs (check:queen-idle, wired into website-checks.yml): 51 checks over four real snapshots in qa/fixtures/queen-status and malformed variants. It failed before the change (missing export) and fails on five mutants (stale boundary, zero reasons, counts as text, the old ready word, the old popover). queen-honesty-contract.mjs follows the renamed copy key. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…hen live
Review of the Queen idle line (f64af31b01) found its words claimed more
than /queen/status carries.
- skippedCount counts skip LINES. queend (main.swift, choose) files
"delegatable but ..." and goes on judging the same issue, which in a
round that chose nothing always files " held by " next. The line listed
incompleteSpec as a cause and called skippedCount "issues": a refused
round of 469 issues, 30 of them bounded but incomplete and held, read
"30 incomplete spec" of "499 issues". incompleteSpec is now left out of
the reasons and subtracted from "checked"; more incompleteSpec than
fileConflict lines contradicts the decider and prints the refusal alone.
- skipCounts() returns null when the counts do not sum to skippedCount
(the server's guarantee) and files keys outside the server's closed
category set under "other" instead of making words from their names.
- Counts follow labels ("no ## Boundary: 449", "zanyaty: 1"), so no count
has to agree with a word: "1 issues", "iz 21 zadach" and "1 zanyaty"
were wrong for counts ending in 1 and 2 to 4.
- Another refusal keeps the wire's text in the line and title; the BEES
tile head says "round refused", so its two-line clamp cuts nothing.
- The idle reason is read only when state.kind is "ready". After a failed
fetch the hook keeps the last data, and a kept round aged into "round
stale", blaming the scheduler for a page that could not see the server.
- The BEES tile reads bees, slots and free slots from /queen/status's
workers alone; it mixed dispatches.running and research's capacity with
status's free slots ("0/10" over "4 idle"). The old reading stays when
the status carries no workers.
- The link to t27#3587 is labelled as a format ("an issue written the way
bees can take it") and shows only when some issue lacks a ## Boundary;
#3587 itself was claimed in the snapshot that shows it.
qa/queen-idle-reason-contract.mjs: 71 checks, including a round built
from queend's own sentences filed as the server files them, counts 1, 21
and 3 in both languages, and source checks for the live gate and the
tile. HEAD's reader and page fail 40 of them; eleven single-fix mutants
each fail at least one.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Measured with trusted input on the build served as https://t27.ai with the healthy-idle snapshot as /queen/status: - 390x844: the line was relative over the top of the body's row, so it covered TRI's screen tabs and the first disclosure of the specs, skills and crons views; a tap on TRI's Agent tab did nothing, and one on the specs directive opened the line's link. At 900 px and below (portrait, or taller than 500 px) the line is now a grid row of its own between the head and the body, and the body gives up its height. - 844x390: the head's tools spill below its 40 px band, and the line lay over all of them and the identity chip. On a landscape phone (height 500 px or less) the line is not drawn; the BEES tile's sub-line is hidden at that size too, so it says what it said before the line. - The collapsed rail's left: 84px outranked the phone rules and pushed the line out of a 390 px window after collapsing at 1440; it is desktop only. - Desktop: the line's top was the head's height guessed on 127.0.0.1 (40 px). On t27.ai the head is 42 px, and the line covered its bottom rule. It now starts at 42 px. qa/queen-idle-layout-contract.mjs (check:queen-idle-layout, browser, not in CI like the other Queen browser contracts): the line against the head at 1440x900 and 1280x720 in en and ru; inside a 390 px window after a collapse; between head and body on one screen at 390x844 with TRI's tabs and the specs disclosure topmost and working under trusted taps; no line and every map tool topmost and working at 844x390; no line once /queen/status fails. It fails on the previous build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
feat(website): Queen HUD says why free bees are idle, round popover no longer crashes (#1030) * feat(website): Queen HUD says why free bees are idle On 2026-09-15 the owner read "BEES 0/4" on #/queen as broken bees. The swarm was healthy_idle: the last round refused with "nothing to choose", 449 of 488 candidate issues had no ## Boundary, 12 were claimed and 27 were accepted but still open. /queen/status already carried all of it; the HUD did not say it. - queenHud.ts: idleReason() reads /queen/status alone (free slots from workers, the tick, the scheduler interval) and idleLine() words it. Free slots plus a refused round: the refusal, and for "nothing to choose" the three largest skip reasons with their wire counts. A tick older than two intervals (the server's TICK_STALENESS_INTERVALS) is called stale instead. A round that dispatched, no free slot, or an unreadable tick gives no line. A missing or malformed skipSummary gives the refusal alone, never a fabricated zero. - Queen.tsx: the BEES tile's sub-line carries the short head; a line under the map's head carries the full sentence and, for "nothing to choose", a link to gHashTag/t27#3587 as an example of an issue bees can take. en and ru copy; other refusals print the wire's own text. - The round popover crashed the page (React #31) on the real wire: each skipSummary entry is {count, issues, more}, and the list rendered the object. It now lists counts read through skipCounts(). - "3 ready" is dispatches.unreviewed: finished dispatch rows with no verdict, not issues ready to take. It reads "finished, no verdict"; the Russian copy says "no verdict", since the longer form was clipped in the 1440 px tile. - qa/queen-idle-reason-contract.mjs (check:queen-idle, wired into website-checks.yml): 51 checks over four real snapshots in qa/fixtures/queen-status and malformed variants. It failed before the change (missing export) and fails on five mutants (stale boundary, zero reasons, counts as text, the old ready word, the old popover). queen-honesty-contract.mjs follows the renamed copy key. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(website): the idle line counts issues, not skip lines, and only when live Review of the Queen idle line (f64af31b01) found its words claimed more than /queen/status carries. - skippedCount counts skip LINES. queend (main.swift, choose) files "delegatable but ..." and goes on judging the same issue, which in a round that chose nothing always files " held by " next. The line listed incompleteSpec as a cause and called skippedCount "issues": a refused round of 469 issues, 30 of them bounded but incomplete and held, read "30 incomplete spec" of "499 issues". incompleteSpec is now left out of the reasons and subtracted from "checked"; more incompleteSpec than fileConflict lines contradicts the decider and prints the refusal alone. - skipCounts() returns null when the counts do not sum to skippedCount (the server's guarantee) and files keys outside the server's closed category set under "other" instead of making words from their names. - Counts follow labels ("no ## Boundary: 449", "zanyaty: 1"), so no count has to agree with a word: "1 issues", "iz 21 zadach" and "1 zanyaty" were wrong for counts ending in 1 and 2 to 4. - Another refusal keeps the wire's text in the line and title; the BEES tile head says "round refused", so its two-line clamp cuts nothing. - The idle reason is read only when state.kind is "ready". After a failed fetch the hook keeps the last data, and a kept round aged into "round stale", blaming the scheduler for a page that could not see the server. - The BEES tile reads bees, slots and free slots from /queen/status's workers alone; it mixed dispatches.running and research's capacity with status's free slots ("0/10" over "4 idle"). The old reading stays when the status carries no workers. - The link to t27#3587 is labelled as a format ("an issue written the way bees can take it") and shows only when some issue lacks a ## Boundary; #3587 itself was claimed in the snapshot that shows it. qa/queen-idle-reason-contract.mjs: 71 checks, including a round built from queend's own sentences filed as the server files them, counts 1, 21 and 3 in both languages, and source checks for the live gate and the tile. HEAD's reader and page fail 40 of them; eleven single-fix mutants each fail at least one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(website): the idle line takes no tap from the Queen's controls Measured with trusted input on the build served as https://t27.ai with the healthy-idle snapshot as /queen/status: - 390x844: the line was relative over the top of the body's row, so it covered TRI's screen tabs and the first disclosure of the specs, skills and crons views; a tap on TRI's Agent tab did nothing, and one on the specs directive opened the line's link. At 900 px and below (portrait, or taller than 500 px) the line is now a grid row of its own between the head and the body, and the body gives up its height. - 844x390: the head's tools spill below its 40 px band, and the line lay over all of them and the identity chip. On a landscape phone (height 500 px or less) the line is not drawn; the BEES tile's sub-line is hidden at that size too, so it says what it said before the line. - The collapsed rail's left: 84px outranked the phone rules and pushed the line out of a 390 px window after collapsing at 1440; it is desktop only. - Desktop: the line's top was the head's height guessed on 127.0.0.1 (40 px). On t27.ai the head is 42 px, and the line covered its bottom rule. It now starts at 42 px. qa/queen-idle-layout-contract.mjs (check:queen-idle-layout, browser, not in CI like the other Queen browser contracts): the line against the head at 1440x900 and 1280x720 in en and ru; inside a 390 px window after a collapse; between head and body on one screen at 390x844 with TRI's tabs and the specs disclosure topmost and working under trusted taps; no line and every map tool topmost and working at 844x390; no line once /queen/status fails. It fails on the previous build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
|
Verified live on https://t27.ai after the publisher run ("Publish assets/index-BzlYtmgd.js from trinity fe4d5ed"; merge tree equals the reviewed branch tree, Round popover. The probe is headless Chrome with a trusted CDP click on the round tile. The button is
HUD on the live swarm. The swarm is working, 10 of 10 busy:
Probes on the same bundle, trusted input: TRI tab 21 of 21, Queen tabs 61 of 61. CI note. The red Not verified live: the idle line itself, because the swarm is not idle right now. It is covered by the contract on four real status snapshots and by the layout contract. |
Description
The owner looked at https://t27.ai/#/queen, saw "BEES 0/4" and asked why the bees were broken. They were not broken. The swarm was healthy and idle, and the scheduler had nothing to choose: 449 of 488 candidate issues had no
## Boundarysection. The HUD already fetched that reason from/queen/statusand did not show it.components/queenHud.ts(skipCounts,idleReason,idleLine) work from/queen/statusalone and use the server clock./queen/statusworkers, and its sub-line carries the short reason.dispatches.unreviewedcounts.skipSummarycrashed the whole page with React error ci: bump docker/build-push-action from 5 to 7 #31. Each entry is{count, issues, more}, and it was rendered as a child. The popover now lists counts.Refs #1010
Related Issue
#1010. This is the follow-up to the Queen bees investigation (gHashTag/t27#3624 and the scheduler rules in gHashTag/BrowserOS trios/agent-server).
Changes Made
apps/website/src/components/queenHud.ts:skipCounts,idleReason,idleLine.apps/website/src/pages/Queen.tsx: the BEES tile sub-line, the idle line, the popover counts, the COPY keys in en and ru.apps/website/src/pages/Queen.css: idle line placement on desktop, portrait phone, landscape phone and collapsed rail.apps/website/qa/queen-idle-reason-contract.mjs(71 checks,npm run check:queen-idle, in website-checks) with four real/queen/statussnapshots inqa/fixtures/queen-status/;qa/queen-idle-layout-contract.mjs(26 checks, headless Chrome);qa/queen-honesty-contract.mjsupdated for the new wording.🔥 TOXIC VERDICT
What Works
idleLineexport. After the change it passes 71 checks on four real snapshots, plus malformed, mismatched, stale and gated cases, with counts of 1, 21 and 3 in en and ru.What Doesn't Work / Limits
/queen/statusdoes not expose the configured repository.queen-honesty-contracthas one check that fails identically on the base, andqueen-round-contracthas one timing check that also fails on the base build. Neither is touched here.Overall Assessment: APPROVE. Self-Score: 8/10.
🌳 TECH TREE Options
{ "version": 1, "head_sha": "f741b2f943e53f87756f58da0eec752e65a8f03a", "summary": "The Queen HUD now explains why free bees are idle from /queen/status, relabels the unreviewed count as finished without a verdict, and no longer crashes when the round popover opens with the real skip summary.", "changes": [ "apps/website/src/components/queenHud.ts: skipCounts, idleReason and idleLine read the refusal, skip counts and staleness from /queen/status with the server clock.", "apps/website/src/pages/Queen.tsx: the BEES tile sub-line and an idle line with the reason and an example link, the round popover lists counts instead of rendering objects, and new en and ru copy.", "apps/website/src/pages/Queen.css: idle line placement for desktop, portrait phones, landscape phones and the collapsed rail without covering controls.", "apps/website/qa/queen-idle-reason-contract.mjs, qa/queen-idle-layout-contract.mjs, qa/fixtures/queen-status and qa/queen-honesty-contract.mjs: contracts over real status snapshots and layout." ], "tests": [ { "command": "node --experimental-strip-types qa/queen-idle-reason-contract.mjs before the implementation", "status": "failed", "result": "Control, expected to fail: queenHud.ts provides no idleLine export.", "evidence": "Session scratchpad idle-shots/contract-before.log" }, { "command": "npm run check:queen-idle; node qa/queen-idle-layout-contract.mjs --dist dist", "status": "passed", "result": "71 idle-reason checks over four real status snapshots and edge cases, and 26 layout checks at desktop, phone and landscape sizes, pass on the build rebased onto main.", "evidence": "Local runs in the feat/queen-idle-explained worktree after the rebase" }, { "command": "Headless Chrome render of the base and the branch build with the real healthy-idle status stubbed, clicking the round tile", "status": "passed", "result": "The base build crashes with React error 31 when the round popover opens; the branch build lists the skip counts with no exceptions and shows the idle line unclipped in en and ru.", "evidence": "Session scratchpad idle-shots before and after screenshots" }, { "command": "npm run typecheck:ratchet; eslint on changed files; check:tri; check:tri-identity; check:queen-languages; check:explorer-languages; npx vite build", "status": "passed", "result": "Type errors stay at the baseline and every contract and the production build pass.", "evidence": "Local runs in the feat/queen-idle-explained worktree after the rebase" } ], "limitations": [ "On landscape phones 500 px tall or less the idle sentence is hidden.", "The example link is a fixed format example, because /queen/status does not expose the configured repository.", "The layout contract is not wired into continuous integration." ], "tags": ["Website", "Queen", "Honesty"], "blog": { "title": "Zero bees is not broken bees", "summary": "A HUD that showed 0 of 4 bees made the swarm look broken, and now it says why the bees are idle, using the scheduler's own counts.", "outline": [ "The question: the owner saw 0 of 4 bees on the Queen and asked why they were broken.", "The answer on the wire: a healthy idle swarm whose scheduler found nothing to choose, because 449 of 488 issues lacked a Boundary section.", "The change: the HUD reads the refusal and skip counts and prints them, with an example of an issue bees can take.", "The honesty rules: no reason from stale data, counts that must add up, and labels that never need grammatical agreement.", "The bug found on the way: the round popover crashed the page on the real skip summary." ] } }🤖 Generated with Claude Code