Skip to content

Carry a duration into the next unit instead of printing 60s, 60m and 1h60m - #763

Merged
Birfy merged 2 commits into
mainfrom
fix/761-format-ms-carry
Oct 22, 2026
Merged

Birfy merged 2 commits into
mainfrom
fix/761-format-ms-carry

Conversation

@Birfy

@Birfy Birfy commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Written-by: Dev

Fixes #761.

Tip SHA: 3394f6c

Reproduce

formatMs in plugins/timeline/src/digest.js chose its unit from the raw milliseconds and then rounded inside that unit, so a value just under a boundary printed a count its own unit cannot hold:

formatMs(59_600)    -> "60s"
formatMs(3_599_999) -> "60m"
formatMs(7_190_000) -> "1h60m"

The run report prints it (- longest wait: <from> → <to>, <formatMs>), so a person pasting the report into a standup reads "1h60m". Reviewer found it while judging #735; the rounding predates that PR.

What changed

  • plugins/timeline/src/digest.js: formatMs rounds once and carries — seconds while the rounded seconds are below a minute, otherwise whole minutes, otherwise h plus two-digit minutes. No other function, endpoint or panel code changed.
  • plugins/timeline/test/digest.test.js: one case with the three failing values, the neighbouring boundaries (59_400 → 59s, 59_999 → 1m, 60_000 → 1m, 3_540_000 → 59m, 86_400_000 → 24h00m) and 3_600_000 → 1h00m added to the existing glance case.
  • docs/subsystems/timeline.md: the digest.js row now says a duration carries (1m, 2h00m, never 60s/1h60m). The first tip failed arch-docs on exactly this (owned file changed without its subsystem doc), so it is in this tip.
  • changelog.d/761-format-ms-carry.fixed.md: the fragment.

What I ran

From a full checkout at main 0105eb25 with this branch's files, DSH_HARNESS=/opt/flybot:

$ cd plugins/timeline && TZ=UTC DSH_HARNESS=/opt/flybot node --import ./test/resolve.mjs --test --test-concurrency=2 "test/*.test.js"
# tests 125
# pass 125
# fail 0
$ TZ=UTC DSH_HARNESS=/opt/flybot node --import ./test/resolve.mjs --test test/digest.test.js
# tests 9
# pass 9
# fail 0
$ node .github/scripts/changelog.mjs check
changelog: 33 fragment(s) in changelog.d/ are well formed

The 116 pre-existing plugin cases stay green; the report's own 12m/1h05m assertions are unchanged.

Red without the source change

Restore main's formatMs (unit chosen from the raw value, rounded inside it) in plugins/timeline/src/digest.js:

$ TZ=UTC DSH_HARNESS=/opt/flybot node --import ./test/resolve.mjs --test test/digest.test.js
# tests 9
# pass 8
# fail 1
not ok 2 - #761: a duration rounds once and carries, instead of printing 60s, 60m or 1h60m

The case names each value it printed (60s, 1h00m expected but 60m printed, 2h00m expected but 1h60m printed). Restoring the new body returns 9/9 and the whole plugin 125/125.

Not run

  • Root npm run verify and the core suite: this box has no core/ sources, so only the plugin suite ran here; the core suite is unaffected by this change and is left to CI.
  • npm run lint / arch-docs themselves: no full checkout with git here; docs/subsystems/timeline.md changes in the same PR, which is what arch-docs asks for, and CI ran it for real on the previous tip where it failed until this doc went in.
  • A live panel: this is report text only; the panel copy path is covered by the existing panel.test.js cases.

Risk

T2 by the repository's own rules (plugins/timeline/**), so it needs a PASS at the tip. One pure function, one test, one fragment; the change is additive in behaviour except at the boundaries the issue names, and no configuration or endpoint changes.

…1h60m

`formatMs` chose its unit from the raw milliseconds and rounded inside that unit, so a value
just under a boundary printed a count its own unit cannot hold: 59.6 s -> `60s`, 59m59.999s ->
`60m`, 1h59m50s -> `1h60m`. The run report prints this as a wait, so it reached a person.

Round once and carry: seconds below a minute, then whole minutes, then `h` plus two-digit
minutes. Boundary cases pin it.

Fixes #761
@Birfy Birfy added the agent-pr Pull request opened by an agent label Oct 22, 2026
@Birfy Birfy self-assigned this Oct 22, 2026
`arch-docs` asks for the subsystem doc when an owned file changes; the digest row now says a
duration carries into the next unit, so the text never prints `60s`, `60m` or `1h60m`.

Fixes #761
@Birfy

Birfy commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

Verdict: PASS at 3394f6c
Written-by: Reviewer2

Ran (head 3394f6c tarball over main 0105eb2; Node 22.23.3; DSH_HARNESS=/opt/flybot, TZ=UTC):

  • cd plugins/timeline && node --import ./test/resolve.mjs --test test/digest.test.js → 9/9 at the tip
  • reverted plugins/timeline/src/digest.js to its main (0105eb2) copy → 8/9, the only red is #761: a duration rounds once and carries, instead of printing 60s, 60m or 1h60m; restored → 9/9
  • cd plugins/timeline && node --import ./test/resolve.mjs --test --test-concurrency=2 "test/*.test.js" → 125/125

What I checked:

  • CI at 3394f6c: 9/9 completed and green (tests-ok, package, plugins (tree|social|timeline), ubuntu Node 24, merge-gate, reviewed tip, risk tier); mergeable: clean; no hold; no other conclusion at this tip
  • formatMs now rounds once and carries: seconds while the rounded seconds are below a minute, otherwise whole minutes, otherwise h plus two-digit minutes — 59_600 → 1m, 3_599_999 → 1h00m, 7_190_000 → 2h00m
  • the case also pins the neighbouring boundaries (59_400 → 59s, 59_999 → 1m, 60_000 → 1m, 3_540_000 → 59m, 86_400_000 → 24h00m) and 3_600_000 → 1h00m; nothing outside formatMs changed
  • docs/subsystems/timeline.md and changelog.d/761-format-ms-carry.fixed.md describe the carry; Fixes #761

Not run: the merge_group run (green at the pull request head only)

Non-blocking: none found.

@github-actions github-actions Bot added the pass label Oct 22, 2026
@Birfy
Birfy added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 1d6b79e Oct 22, 2026
9 checks passed
@Birfy
Birfy deleted the fix/761-format-ms-carry branch October 22, 2026 11:59
@Birfy Birfy removed the agent-pr Pull request opened by an agent label Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

formatMs carries past its unit: 60s, 60m, 1h60m in the run report

1 participant