Skip to content

Read a sub-minute wait in seconds on the Project board - #1897

Merged
Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/2-waited-under-a-minute
Oct 31, 2026
Merged

Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/2-waited-under-a-minute

Conversation

@HugoXK

@HugoXK HugoXK commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Fixes #1896

Owner: Dev
Written-by: Dev-2
Reviewer: Reviewer
Claim-Id: d4afd33d4dfa486f9882ed19d0abaea2
Base: 148554c
Verified commit: 72b2d9d926ef3a687590fbdd6699b95b6c9c47b2 (tree c1d5c525703ce5cf6289eea65e87706ffc77974a);
the pushed head 463907e9cc14d9565f2d59c79ed08dcab571d3a1 was rebuilt from that same tree by the push
path, so the two commits carry identical content
Tree: c1d5c525703ce5cf6289eea65e87706ffc77974a
Diff: 8 files, +85/−5 — the label (core/src/client/project-board.js), the regenerated bundle
(core/client.js), the test, the two patches/ds-bot/ mirrors the generator owns for those files
(0008-client-bundle.patch and files/src/client/project-board.js, files/test/project-board-view.test.js),
the core-client subsystem page and one changelog.d/ fragment

What was wrong

waitedLabel floored to whole minutes, so any span under a minute read 0m. The label is not only a
card's wait line (Waiting group) — the three duration metrics (prMergeMedianMs, issueCloseMedianMs,
taskDoneMedianMs) go through the same function, so a 35-second median merge printed 0m, which a
reader takes for "instant or unknown" rather than "35 seconds". elapsedLabel next door
(core/src/client/activity-row.js) already floors with Math.max(1, …) and never says 0m, so the
board and the activity row disagreed about the same span.

What changed

  • waitedLabel carries seconds under a minute: 40_000 → 40s, 59_999 → 59s, 0 → 0s, and a span
    over zero never floors to 0s (1 → 1s), the same way elapsedLabel never says 0m. At and above
    a minute the units are unchanged (1m, 3h, 50d).
  • Unknown stays unknown: a missing, negative or non-finite span still returns null, so the card
    renders nothing and a duration the host could not read still renders the dash — the "unknown is
    never zero" rule is untouched.
  • The card wait line and the three metrics keep calling that one function; no host change, the values
    stay in milliseconds.
  • core/client.js was rebuilt from core/src/client/ and the patches/ds-bot/ mirrors regenerated, so
    check/canonical stay green. docs/subsystems/core-client.md records the unit rule and a
    changelog.d/ fragment names the visible change.

Red first

The test, on 148554c1 with only core/test/project-board-view.test.js changed:

$ node --test test/project-board-view.test.js
not ok 11 - \#1896: a sub-minute wait and a sub-minute median read in seconds, never 0
  error: |-
    Expected values to be strictly equal:

    '0m' !== '40s'
  location: 'core/test/project-board-view.test.js:271:10'
# tests 22
# pass 21
# fail 1

The test also pins the two neighbouring cases (59_999 → 59s, 0 → 0s) and the three metrics, so a
partial fix that only touched the card line would still fail.

Verification at the tip

Ran: at 72b2d9d926ef3a687590fbdd6699b95b6c9c47b2 on the committed tree, git status --porcelain
empty before and after:

  • TZ=UTC ARCH_DOCS_BASE=148554c19941d77407df6e1916de8d6d393e359f npm run verify — exit 0: core
    2290/2290, social 541/541, tree 127/127, timeline 135/135, workflow 336/336, .github/scripts
    563/563, interop 37/37, live-e2e 24/24; oxlint 0 errors (core 73 warnings, plugin lints
    36/9/2/16 and 1/0 warnings); arch-docs: OK (8 changed file(s)); build-client --check clean.
  • node scripts/ds-bot-patches.mjs check — three lines ok (pin tree 5834c00, 10 patches apply in
    order, core/ equals ds-bot/ + patches).
  • node scripts/ds-bot-patches.mjs canonical — ok patches/ds-bot/ is what generate writes (generate is a no-op).
  • node .github/scripts/changelog.mjs check — 5 fragments well formed; check-mojibake --check — 0
    occurrences of U+FFFD.

Not run: the smoke bench (no index.js or src/host/ change) and the CI package job's pack
check, typecheck and actionlint, which run in CI.

{
  "pr": 1897,
  "claim": "Dev",
  "issue": 1896,
  "summary": "waitedLabel floored to whole minutes, so a card that waited 40 seconds read 0m — and the three duration metrics use the same label, so a 35-second median merge printed 0m, which reads as instant or unknown. The label now carries seconds under a minute, never flooring a span over zero to 0s, while missing and negative spans still return null and an unread duration stays the dash. elapsedLabel next door already avoided 0m, so the two labels agree. The card line and the three metrics keep calling the one function; no host change.",
  "files": [
    "core/src/client/project-board.js",
    "core/client.js",
    "core/test/project-board-view.test.js",
    "patches/ds-bot/0008-client-bundle.patch",
    "patches/ds-bot/files/src/client/project-board.js",
    "patches/ds-bot/files/test/project-board-view.test.js",
    "docs/subsystems/core-client.md",
    "changelog.d/1896-waited-label-seconds.fixed.md"
  ],
  "checks": { "ran": "TZ=UTC ARCH_DOCS_BASE=148554c1 npm run verify; node scripts/ds-bot-patches.mjs check; node scripts/ds-bot-patches.mjs canonical; node core/scripts/build-client.mjs --check", "result": "green", "at": "72b2d9d926ef3a687590fbdd6699b95b6c9c47b2" },
  "next": "none — ready for review"
}

A card that waited 40 seconds read `0m` on the board's Waiting group and
on all three duration metrics (PR merge time, issue close time, task
completion), so a 35-second median merge looked like "instant or unknown".
`waitedLabel` now carries seconds under a minute and never floors a span
over zero to `0s`; missing and negative spans still return nothing, and an
unread duration stays the dash. `elapsedLabel` next door already avoided
`0m` this way, so the two labels now agree.

Fixes ThinkFlowLab#1896
@HugoXK

HugoXK commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Verdict requested for this tip: 463907e (tree c1d5c525703ce5cf6289eea65e87706ffc77974a, base 148554c)

@Birfy review request — #1896 (waitedLabel read 0m under a minute). The PR body carries the red-first run, the full verify counts at this tip and the checkpoint block.

What to look at:

  • core/src/client/project-board.js: waitedLabel now returns seconds under a minute (40s, 59s, 0s, and 1s rather than 0s for a span over zero); null for missing/negative/non-finite is unchanged, and the card wait line plus the three duration metrics keep calling the same function.
  • core/test/project-board-view.test.js: the sub-minute case next to the existing 3h/5m assertions, including the three metrics and the card line; it was red on 148554c1 ('0m' !== '40s').
  • core/client.js rebuilt from core/src/client/, the generator's patches/ds-bot/ mirrors regenerated — check and canonical both green at this tip.

Owner: Dev
Written-by: Dev-2
Reviewer: Reviewer

@Birfy
Birfy added this pull request to the merge queue Oct 31, 2026
Merged via the queue into ThinkFlowLab:main with commit 4885595 Oct 31, 2026
13 checks passed
@Birfy
Birfy deleted the dev/2-waited-under-a-minute branch October 31, 2026 06:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

project board: a card that waited under a minute reads 0m

2 participants