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: 73966f19d3154326ad0829769e997181
Branch: dev/1-board-done-time
Base: c2de64d
At: 2026-11-01T17:01:14Z
What happens today
A Bot's Tasks board draws every card with the same footer (core/src/client/kanban.js:256-261): the owner (bt-board-who) and the progress bar plus 100% (bt-board-progress). Nothing else. The Done column is filled from actions.tasks({ botId, archive: true, limit: ARCHIVE_SHOWN }) (kanban.js:174-188), whose host records do carry the time (core/src/host/tasks.js:342 — view() spreads the whole record, updatedAt and actors included), and the column header already counts them; but the card never renders any of it.
Measured on c2de64d6 with the real modules: a done card renders as #done-1NormalDoneFinished two hours agoWriter100%, the footer as Writer100%, and no node carries a timestamp. kanban.js does not import relativeShort at all (only at-menu.js:181, inbox.js:539, sidebar.js:238 do), so nothing throws and nothing is wrong — the time is simply absent. The same task in the Inbox Done list shows 2 h (inbox.js:545 → whenText), so one finished task reads differently in two surfaces.
Expected
Only in the Done column, append one node at the end of the card footer: a span.bt-board-when whose text is relativeShort(settledAt), styled like the rest of the footer. Nothing changes in the other columns, the rail counts, the archive limit or the ordering.
- Time: the first terminal record's
atinactors(accepted/cancelled/failed— the three states that land a card in Done,shared/task-board.js:19). Not the last one and notupdatedAt: editing a settled task pushes a further same-status record withby: 'updated'(tasks.js:1456) and refreshesupdatedAt(tasks.js:267-270), so the last record andupdatedAtboth move after completion, while the first terminal record is the transition itself (TRANSITIONS,tasks.js:30-39, has no exit from a terminal state). - Fallback: first terminal
at→updatedAt→ draw nothing. Guard withNumber.isFinite(t) && t > 0:relativeShort(undefined)rendersInvalid DateandrelativeShort(0)rendersJan 1. - Formatting and localisation reuse
relativeShort(core/src/client/text.js:64-71) and its existing strings —just now/5 min/2 h/3 d, an absolute date past 30 days. No new i18n key, no new formatter, notitletooltip.
Scope
core/src/client/kanban.js (BoardCard footer, one conditional node, one KANBAN_CSS line, the text.js import), core/test/kanban.test.js, the rebuilt core/client.js and patches/ds-bot/ artefacts (0008-client-bundle.patch, files/src/client/kanban.js, files/test/kanban.test.js), changelog.d/<issue>-board-done-time.added.md, and one sentence on the kanban.js row of docs/subsystems/core-client.md. text.js, board-card.js, inbox.js and the host are untouched.
Out of scope: other columns, the Inbox whenText and Project board waitedLabel, the rail counts (kanban.js:396-409), draggable (:270), the archive limit and its 20 newest wording.
Tests
core/test/kanban.test.js, with the existing boardWith(scope, own, archive) helper:
- A settled card whose
actorsare[{working, -10min}, {accepted, -125min}, {accepted, -1min, by:'updated'}]andupdatedAt: -1minrenders2 h— pins both "use the terminal record" and "use the first one" (the last record orupdatedAtwould read1 min). - The same card in In progress has no
bt-board-whennode. - A card with no
actorsfalls back toupdatedAt. - A card with neither renders no node and no
Invalid Datetext. - A room board (
{kind: 'group'}) Done card renders it too.
Mutation check: taking the last terminal record, or updatedAt, must turn case 1 red; dropping the finiteness guard must turn case 4 red.
Tier T1 (only core/src/client/**), size XS.
Duplicate check
On live main c2de64d6, relativeShort has zero hits in src/client/kanban.js, and bt-board-when has zero hits in src and test. Issue search for done card time / board card timestamp / finished time board / kanban done when returns 0, and relativeShort in bodies returns 0. The nearest existing issues are #2031 (Project board blocked row age), #1884 (completion median), #1289/#2047 (Done counts) and #1746 (Inbox and board row mapping) — none is this. No open or closed duplicate.
Activity
HugoXK commentedon Nov 1, 2026
Claim
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 73966f19d3154326ad0829769e997181
Branch: dev/1-board-done-time
Base at posting: c2de64d
Posted so this issue carries a claim comment and not only the block in its body: the helper that created it writes the block into the body but posts no comment, and a claim comment is the record other readers see. The base above is this moment's base, not a promise about where the branch will be cut — whoever starts posts a heartbeat naming the base it actually used. This account has only
pullon this repository, so it can write neither labels nor assignees; the claim comment is the lock.Do not pick up without a
pickup-okcomment.Show when a task finished on a Done board card
HugoXK commentedon Nov 2, 2026
Release
Written-by: FlyBot Lead
Released: 73966f19d3154326ad0829769e997181
Reason: stood down
At: 2026-11-02T00:34:00Z