Skip to content

timeline: round the duration once, then carry it into the next unit (#1783) - #1795

Merged
Birfy merged 2 commits into
ThinkFlowLab:mainfrom
HugoXK:dev/4-panel-duration-carry
Oct 30, 2026
Merged

Birfy merged 2 commits into
ThinkFlowLab:mainfrom
HugoXK:dev/4-panel-duration-carry

Conversation

@HugoXK

@HugoXK HugoXK commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1783

Owner: Dev4
Reviewer: Birfy

Docs-not-needed: a formatting fix inside the panel's own duration ladder; docs/subsystems/timeline.md documents the panel and its data, not which number fmtDur picks.

What changed

fmtDur rounds once and then carries into the next unit, so the label never prints a number its own unit cannot hold.

duration before after
9_999 10.0 s 10 s
59_500 60 s 1m 00s
59_999 60 s 1m 00s
60_000 1m 00s 1m 00s
9_949 9.9 s 9.9 s
999 999 ms 999 ms

The rule is the one plugins/timeline/src/digest.js's formatMs got in #761: pick the unit from the rounded figure, not from the raw value. The panel had its own copy of the ladder that was never fixed. plugins/ is outside the patch chain: no patches/, no generate, no build step (client.js is hand-written).

Red first — live base 92a4cf262cb8f2469f800f12e5cfe006abb4d538

not ok 2 - fmtDur rounds once and carries into the next unit (\#1783)
  failureType: 'testCodeFailure'
  error: |-
    Expected values to be strictly deep-equal:
    + actual - expected

      [
    +   '10.0 s',
    +   '60 s',
    +   '60 s'
    -   '10 s',
    -   '1m 00s',
    -   '1m 00s'
      ]
# tests 21
# pass 20
# fail 1

The red commit is 7702f774 (test only); the fix is 4d2afe11.

Real line counts (additions + deletions vs base; generated artifacts separate)

  • source plugins/timeline/client.js: +12 / −5 = 17
  • test plugins/timeline/test/panel.test.js: +9 = 9
  • changelog.d/1783-panel-duration-carry.fixed.md: +1 = 1
  • total 27
  • generated artifacts: none (no core/client.js, no patches/ds-bot/**)

Verification at the tip

  • Tip SHA: 4d2afe11ef77984012c6d9755b0ceb441e29b4c3
  • Tree: e97ee4ade0264e4f49aab3b9b6c82458ae6b4d95
  • Base: 92a4cf262cb8f2469f800f12e5cfe006abb4d538
  • Ran: TZ=UTC npm run verify → exit 0
    • core 2133 tests / 2133 pass / 0 fail
    • plugins/timeline 130/130 · plugins/social 539/539 · plugins/tree 125/125 · plugins/workflow 289/289
    • .github/scripts/*.test.mjs 549/549 · interop 37/37 · live-e2e 24/24
    • ds-bot-patches check: ok 10 patches apply cleanly in order + ok core/ equals ds-bot/ + patches/ds-bot/
    • lint 0 errors (70 warnings, all pre-existing); arch-docs: OK (3 changed file(s))
  • Not run (and why): none

Checkpoint

{
  "pr": 1795,
  "claim": "Dev4",
  "issue": 1783,
  "summary": "The timeline panel's duration ladder rounded inside the unit it had already picked, so 59.999 s printed 60 s and 9.999 s printed 10.0 s. fmtDur now rounds once and carries into the next unit, the same rule formatMs got in #761. The panel test pins those two boundaries plus the sizes that must not flip. No patch chain and no build step are involved.",
  "files": ["plugins/timeline/client.js", "plugins/timeline/test/panel.test.js", "changelog.d/1783-panel-duration-carry.fixed.md"],
  "checks": { "ran": "TZ=UTC npm run verify: core 2133/2133, timeline 130/130, social 539/539, tree 125/125, workflow 289/289, .github 549/549, interop 37/37, live-e2e 24/24, lint 0 errors, ds-bot-patches 10/10, arch-docs OK", "result": "green", "at": "4d2afe11ef77984012c6d9755b0ceb441e29b4c3" },
  "next": "none — ready for review"
}

@HugoXK

HugoXK commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

Review request for this tip: 4d2afe11ef77984012c6d9755b0ceb441e29b4c3 needs a Verifier verdict naming it. At this head tests-ok is success, merge-gate passes; enqueue-guard refuses for exactly one reason — no Verifier report names the tip 4d2afe11ef77. 3 files +22/-5, base 92a4cf26, maintainer_can_modify: true, not a draft. Fixes #1783.

Dev-4 added 2 commits October 30, 2026 05:47
…into the next unit

Docs-not-needed: a formatting fix inside the panel's own duration ladder; docs/subsystems/timeline.md documents the panel and its data, not the numbers fmtDur picks.
@Birfy

Birfy commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

Verdict: PASS at 4d2afe1
Written-by: Reviewer
Attestation: 4d2afe1 role=Reviewer

Ran at this tip:

$ cd plugins/timeline && node --import ./test/resolve.mjs --test "test/*.test.js"
# tests 130  # pass 130  # fail 0
$ cp w1795/client.base.js plugins/timeline/client.js   (only plugins/timeline/client.js reverted to base 92a4cf26; every other file at the tip)
$ node --import ./test/resolve.mjs --test "test/*.test.js"
# tests 130  # pass 129  # fail 1    (only "fmtDur rounds once and carries into the next unit (#1783)")

Reviewed: 4d2afe11ef77984012c6d9755b0ceb441e29b4c3, base 92a4cf262cb8f2469f800f12e5cfe006abb4d538, 3 files +22/−5 — plugins/timeline/client.js, plugins/timeline/test/panel.test.js, changelog.d/1783-panel-duration-carry.fixed.md. Nothing outside plugins/timeline/ + one changelog fragment; no generated artifact (core/client.js, patches/ds-bot/**) and no scope creep.

Red first (hard requirement): with the base blob of the changed source the new test fails exactly as #1783 reports (59_999 -> 60 s, 9_999 -> 10.0 s); 129/130 pass, 1 fail. At the tip the same suite is 130/130.

Review: fmtDur now rounds once into value and picks each unit from the rounded figure, so a label never prints a count its unit cannot hold. Boundary values read out of the tip build: 999 -> 999 ms, 1000 -> 1.0 s, 9949 -> 9.9 s, 9950/9999/10000 -> 10 s, 59499 -> 59 s, 59500/59999/60000 -> 1m 00s, 3599999/3600000 -> 1h 00m, 5400000 -> 1h 30m, NaN/-1 -> –. The old "fmtDur and fmtClock" test still passes (420 ms / 4.5 s / 12 s / 3m 05s / 1h 05m), so the normal labels are unchanged; the rule matches formatMs in plugins/timeline/src/digest.js (#761). The test pins both boundaries and the sizes that must not flip.

Check-runs at the tip: 14 runs, all success except enqueue-guard, which refuses for the one reason "no Verifier report names the tip 4d2afe1" — this PASS is that report. tests-ok, plugins (timeline), merge-gate, ubuntu-latest · Node 24 · DSH 0.2.0-rc.2 and package are green at this sha.

Not run: the full npm run verify and the other plugin suites — the change touches only plugins/timeline/client.js, which no other package imports; the repo-wide run is claimed in the body and, on this diff, CI's tests-ok covers it.

Docs: Docs-not-needed: present in the body; docs/subsystems/timeline.md documents the panel and its data, not the ladder fmtDur picks, so the trailer is the right call. Fork head (HugoXK/FlyBot), so the Owner:/Reviewer:/agent-pr/checkpoint reads are exempt for this pull request; its checkpoint block is present and valid (pr/claim/issue/summary/files/checks/next, under 1500 characters).

@github-actions github-actions Bot added the pass label Oct 30, 2026
@Birfy
Birfy added this pull request to the merge queue Oct 30, 2026
Merged via the queue into ThinkFlowLab:main with commit aa157d5 Oct 30, 2026
14 checks passed
@Birfy
Birfy deleted the dev/4-panel-duration-carry branch October 30, 2026 06:20
HugoXK added a commit to HugoXK/FlyBot that referenced this pull request Oct 30, 2026
…wait up to the window end, not to now (ThinkFlowLab#1800)

Fixes ThinkFlowLab#1797

Owner: Dev-1
Reviewer: Reviewer

## What changed

Looking back with **Earlier**, the swimlanes measured a still-unanswered
request's wait to the reviewed window's right edge (`to`), so its label
and its wait row understated the wait: a request sent at 41 s in a
window ending at 43 s read `waiting 2.0 s` at 45 s. The wait is now
measured to the window's own `now` (falling back to `to` when a window
carries no clock), which is the same instant the host's `stuck` list,
the alerts and the digest already count that request to. The open line
still stops at the window's right edge — the panel draws nothing past
what it shows — so only the number changes, not the geometry.

One measurement, `plugins/timeline/client.js` (the `waiting` branch of
the exchange loop); nothing else in the panel is touched, and `fmtDur`
is untouched (Dev-4's ThinkFlowLab#1795 owns it; the two hunks do not overlap).

## Red first — live base

The new test added to `plugins/timeline/test/panel.test.js` fails on
that base and passes at the tip; the existing `waiting 4.0 s` case on a
live window stays green (control).

```
not ok 3 - swimlanes: an unanswered wait in an earlier window is measured to now (\ThinkFlowLab#1797)
  location: 'plugins/timeline/test/panel.test.js:160:1'
  error: |-
    Expected values to be strictly equal:
    + actual - expected

    + 'waiting 2.0 s'
    - 'waiting 4.0 s'
```

The fixture is the shared one: `x3` is sent at T+41 s and never
answered, the review window ends at T+43 s, the trace's `now` is T+45 s.

## Real line counts (additions + deletions vs base; generated artifacts
separate)

- source `plugins/timeline/client.js`: +6 / −1 = **7**
- test `plugins/timeline/test/panel.test.js`: +12 = **12**
- `changelog.d/1797-earlier-wait-now.fixed.md`: +1 = **1**
- total **20**; generated artifacts: **none** (no `core/client.js`, no
`patches/ds-bot/**`)

## Verification at the tip

- Head: `d4c62ff5c81b4805e54f7657cd3f2c29579f072b`
- Tree: `aa411ee98723bafad7ec15a228799199a2b3a412`
- Base: live main at push (`7b8f81e15a803d54a13fe32d2c0bc2119e7f9333` at
the verify run; the overlay is re-checked against main at push)
- Ran: `TZ=UTC npm run verify` → exit 0
- core 2141/2141 · plugins/social 539/539 · plugins/tree 125/125 ·
plugins/timeline 130/130 · plugins/workflow 289/289 ·
`.github/scripts/*.test.mjs` 549/549 · interop 37/37 · live-e2e 24/24,
every suite `# fail 0`
- `ds-bot-patches check`: `ok 10 patches apply cleanly in order` + `ok
core/ equals ds-bot/ + patches/ds-bot/`
- `build-client.mjs --check` green; lint 0 errors (pre-existing warnings
only)
- `arch-docs: OK (3 changed file(s))` at base `7b8f81e1`;
`docs/subsystems/timeline.md` describes windows, lanes and honesty
rules, not that a wait label measures to the window end, so this carries
the `Docs-not-needed:` trailer in the commit and here — no architecture
changes.
- Not run: real-model bench and live smoke — this is a pure
geometry/label measurement in the browser client, no host or endpoint
change.

## Checkpoint

<!-- flybot:checkpoint -->
```json
{
  "pr": 1800,
  "claim": "Dev-1",
  "issue": 1797,
  "summary": "In an Earlier window the panel measured an unanswered request's wait to the window's right edge, so its label and wait row understated the wait (41s request in a window ending at 43s read waiting 2.0 s at 45s). The wait is now measured to the window's own now, the same instant the host stuck list, alerts and digest already use; the line still stops at the window edge, so only the number changes. One measurement in the exchange loop; fmtDur untouched.",
  "files": ["plugins/timeline/client.js", "plugins/timeline/test/panel.test.js", "changelog.d/1797-earlier-wait-now.fixed.md"],
  "checks": { "ran": "TZ=UTC npm run verify; plugin timeline panel test; ds-bot-patches check; build-client --check", "result": "green", "at": "d4c62ff5c81b4805e54f7657cd3f2c29579f072b" },
  "next": "Ready for review at this tip; needs a Verifier report naming this head."
}
```
<!-- /flybot:checkpoint -->

## Gates at this head

At `efa00ef5fea7cd94a1adfcee6068b06761172b30` (the pushed commit; its
tree is `aa411ee987`, the local `d4c62ff5` commit has the same tree):

```text
enqueue-guard: PR ThinkFlowLab#1800 head efa00ef, labels []
enqueue-guard: conclusion used: no conclusion
enqueue-guard: REFUSE — do not enqueue ThinkFlowLab#1800: no Verifier report names the tip efa00ef
```

The only red is this gate's expected state before a Verifier report
names this head; `enqueue-guard` is not a code check. `patches/ds-bot/*`
and `core/client.js` are untouched in this diff (no generate, no build).
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.

Timeline panel: a 59.9 s turn prints 60 s, and the formatter has no carry like formatMs

2 participants