Repository navigation
Description
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: dbd48f9ebef447a886d841c374b52317
Branch: dev/2-room-rail-active-cards
Base: c2d70bd
At: 2026-11-01T16:38:46Z
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: FlyBot Lead
What happens today
On a room board (boardWith({ kind: 'group', roomId })) the rail of a Bot that has active cards drops every active card, so it prints the archive page alone. useBoardTasks fills own only through setGroupTasks for a Bot board — in room scope it stays [] — and the counting loop at core/src/client/kanban.js:400 (at b99e6c98) is
[...own, ...(archive ?? []).slice(0, ARCHIVE_SHOWN)]so the room's own task list (the groupTasks the caller already holds) never reaches the sum. A card drawn in the Bot's column is in the count only if it also happens to be on the archive page.
Measured with a read-only probe (core/dev/probe-roomrail/run.mjs, Product) on live main = b99e6c98: a room whose Writer draws 4 cards (3 active + 1 done) reads 1/1 where the drawn rows say 1/4; a room whose member has only active cards reads empty where it should read 0/1.
This survives #2048 / #2058 (Read a room board's drawn done rows as a lower bound): that change took the archive page from "a total" to "a lower bound of the drawn done rows", but the active rows still never enter the sum at all.
Reproduction
Read-only, no fixture writes:
core/dev/probe-roomrail/run.mjsagainstb99e6c98— Writer with 3 active + 1 done cards: rail1/1, drawn rows 4; Chief with only active cards: rail'', drawn rows 1.- In
core/test/kanban.test.js, a room board built with an archive page of one done card for Botaand two for Bots, plus one active task for each, is expected to readrailMeta('a') === '1/2'andrailMeta('s') === '2/3'; atb99e6c98both read'1/1'. A room whose member has only active cards must read0/1instead of''.
Red first at b99e6c98, TZ=UTC node --test core/test/kanban.test.js: 14 tests / 12 pass / 2 fail, three identical runs; the two failures are exactly the assertions above (expected '1/2', actual '1/1' and expected '1/4', actual '1/1').
Expected behaviour
On a room board a Bot's rail counts the cards that room actually holds for it — its active cards plus its archive page — not the archive page alone. Worked shape:
- a room where the Bot is drawn with 3 active cards and 1 done card reads
1/4, not1/1; - a room where the Bot has only active cards reads
0/N, not empty; - a Bot board (
kind: 'bot') keeps its present answer byte-for-byte.
Boundary: the full-page lower-bound rule is not this issue. When a room page is full and a Bot's share was truncated, #2045 / #2047 own that 0/3-style answer; a change that also rewrites the full-page case is out of scope, and the existing full-page assertions are not this fix's business.
Scope
core/src/client/kanban.js—useBoardTasksexposes the room's own list (groupTasks) alongsideown, andKanbanDialogpasses it into the rail sum at:400. No new endpoint, no new field in the task record, no host change.core/test/kanban.test.js— one new case pinning the room rail, and the two#2058short-page assertions rewritten (they pinned'1/1'/'2/2', i.e. the very behaviour this issue fixes); the rewritten lines carry a comment sayingP-364rewrote them.docs/subsystems/core-client.md— one clause on the kanban line: in room scope the rail is the room's active cards plus its archive page.core/client.js— thenpm run buildartifact.patches/ds-bot/mirrors (0008-client-bundle.patch,files/src/client/kanban.js,files/test/kanban.test.js) — regenerated bygenerate, never hand-edited.- a one-line
changelog.d/fragment named after this issue. - Not in scope: the full-page lower bound (
#2045/#2047),P-366(a Done card can be dragged butmove()returns silently — same file, a separate change), andP-365(no completion time on Done cards).
Duplicate check
Searched rail in titles, rail kanban, room board rail, "group page", groupTasks, plus the 40 newest issues on ThinkFlowLab/FlyBot against live main = b99e6c98: the only related items are #2045 (Task board prints the 20-card archive page as the Done total, closed by #2047) and #2048 (A room board's rail prints a Bot's drawn done rows as its total, closed by #2058). Both are about the archive page being printed as a total; neither covers "the room's own active cards never enter the sum". No open issue and no open PR covers this.
Evidence measured before this issue was opened (local detached worktree off b99e6c98, nothing pushed, no branch, no PR)
- Red first — base source with only the new/rewritten tests in place: 14 / 12 / 2, three identical runs, the two failures named above.
- After the fix: same file 14 / 14 / 0.
- Mutation — the
:400loop put back to[...own, ...(archive ?? []).slice(0, ARCHIVE_SHOWN)], whole file run, then restored: 14 / 12 / 2, the same two assertions red. TZ=UTC ARCH_DOCS_BASE=b99e6c98 npm run verifyat local commitc2dc1297(clean tree) → exit 0: core 2506/2506 (base 2505 + the one new case), social 541, tree 127, timeline 135, workflow 336,.github/scripts563, interop 37, live-e2e 24; lint 73 warnings / 0 errors;arch-docs: OK (7 changed file(s))againstb99e6c98;ds-bot-patches generateis a no-op after regeneration.
The pull request states the counts for its own tip; the changelog fragment adds one file to that list (8 files, arch-docs 8).
Activity
HugoXK commentedon Nov 1, 2026
Claim record (the body above is the same record; this comment is the durable copy).
dbd48f9ebef447a886d841c374b52317Dev-2dev/2-room-rail-active-cardsc2d70bd1b8398d8e5bc3297a015c417d898d8992(livemain; the issue was opened offb99e6c98and the base moved when#2062merged at 16:39:59Z — the body'sBase:line now carries the same sha)Fixes #2063.Do not pick up without a
pickup-okcomment.HugoXK commentedon Nov 1, 2026
Release
Written-by: FlyBot Lead
Released: dbd48f9ebef447a886d841c374b52317
Reason: merged as c5630a1 (#2064)
At: 2026-11-01T17:09:34Z