Skip to content

test(heartbeat): drop the 3s waitForStarted bounds in the resume-cap case (BLO-20885) - #1380

Merged
allyblockcast[bot] merged 1 commit into
masterfrom
cto/blo-20885-resume-cap-wait-bounds
Aug 16, 2026
Merged

test(heartbeat): drop the 3s waitForStarted bounds in the resume-cap case (BLO-20885)#1380
allyblockcast[bot] merged 1 commit into
masterfrom
cto/blo-20885-resume-cap-wait-bounds

Conversation

@allyblockcast

@allyblockcast allyblockcast Bot commented Aug 15, 2026

Copy link
Copy Markdown

Thinking Path

  • Paperclip is the open source app people use to manage AI agents for work
  • Queued-run dispatch decides which backlogged run an agent picks up next; heartbeat-queued-backlog-convergence.test.ts is the acceptance evidence for that behaviour (BLO-20396)
  • BLO-20885 exists because a flaky assertion in this file is worse than an ordinary flake — it teaches reviewers to discount the exact signal the dispatch work depends on
  • test(heartbeat): make the queued-backlog convergence suite deterministic (BLO-20885) #1011 de-flaked the sibling-starvation case, but the ticket's remaining criterion is that the whole file survives 20 consecutive runs
  • Running that soak surfaced a different, still-live flake: the resume-cap case fails under runner load
  • This pull request removes the load-sensitive deadline that causes it
  • The benefit is that the file's green is trustworthy, which is the entire point of BLO-20885

Linked Issues or Issue Description

What Changed

  • Dropped the two hard-coded 3_000 ms waitForStarted bounds in resumes forward after a claim instead of restarting the scan at the head, so both waits take the helper's 60 s default.
  • Added a comment recording the measurement and why a generous bound is not a weakening.

No production code changed; no other test touched.

Verification

The failure this fixes. 20 independent vitest run invocations of the full file at master 3cbf0b6f, 19 passed / 1 failed:

iter=13 rc=0 dur=266s | Tests  11 passed (11)
iter=14 rc=1 dur=237s | Tests  1 failed | 10 passed (11)
iter=15 rc=0 dur=216s | Tests  11 passed (11)
FAIL … > resumes forward after a claim instead of restarting the scan at the head
AssertionError: expected 1 to be 2 // Object.is equality
 ❯ heartbeat-queued-backlog-convergence.test.ts:1233:54
    1233| expect(await adapter.waitForStarted(2, 3_000)).toBe(2);

Iterations had slowed from a ~131 s baseline to ~270 s under load (load average 11 on 32 cores) — the deadline was measuring the runner, not the dispatcher. These were the only hard-coded waitForStarted timeouts in the file.

Post-fix, full file: Test Files 1 passed (1) / Tests 11 passed (11), 160.86 s.

Negative control — the change is not vacuous. Forced resumeState = null in heartbeat.ts:20715 so every pass restarts the scan at the head, then re-ran the case:

AssertionError: expected 1 to be greater than or equal to 10
 ❯ heartbeat-queued-backlog-convergence.test.ts:1250:31
    1250| expect(claimedPosition).toBeGreaterThanOrEqual(windowRows);

It still fails — and now on the property assertion rather than on a timeout, which is strictly better diagnostics. Note waitForStarted(2) succeeded under the control, confirming the count-wait was never the discriminating assertion. Control reverted (git checkout --); the diff is the test file only.

Risks

Low. waitForStarted polls every 25 ms and returns the moment the count is reached, so the happy path is unchanged and the suite does not get slower. The only behavioural change is that a genuinely broken cursor now takes up to 60 s to fail instead of 3 s — acceptable in a file whose runtime is already 130–270 s, and the negative control shows it fails on the meaningful assertion when it does.

Model Used

  • Claude Opus 4.5 (claude-opus-4-5), 1M context, extended thinking, with tool use and code execution.

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work
  • I have searched GitHub for duplicate or related PRs and linked them above
  • I have either (a) linked existing issues OR (b) described the issue in-PR
  • I have run tests locally and they pass
  • I have added or updated tests where applicable (test-only change)
  • If this change affects the UI, I have included before/after screenshots (n/a)
  • I have updated relevant documentation to reflect my changes (in-file comment)
  • I have considered and documented any risks above
  • All Paperclip CI gates are green — pending first run
  • Greptile is 5/5 with no open P2s, recommendations, or follow-ups
  • I will address all Greptile and reviewer comments before requesting merge

…case (BLO-20885)

The resume-cap test carried the only hard-coded `waitForStarted` timeouts in
the file; every other wait uses the 60s default or the `diagnosticRemainingMs`
budget. A 3s deadline asserts how fast the runner is rather than what the
dispatcher does, which is the load sensitivity BLO-22418 set out to remove —
shrinking the fixture cut the seed+scan cost but left the deadline in place.

Measured on a 20-run soak of the full file at master 3cbf0b6: 19 passed,
iteration 14 failed with `expected 1 to be 2` at the second wait, on a runner
where iterations had slowed from ~131s to ~270s under load.

The bound is not load-bearing. `waitForStarted` polls every 25ms and returns as
soon as the count is reached, so the happy path is unchanged; removing the
deadline only stops a slow runner from failing the case. Negative control:
forcing `resumeState = null` so every pass restarts at the head still fails the
test, now on the property assertion itself — `expected 1 to be greater than or
equal to 10` at `claimedPosition >= windowRows` — rather than on a timeout.

Co-Authored-By: Claude <noreply@anthropic.com>
@allyblockcast

allyblockcast Bot commented Aug 15, 2026

Copy link
Copy Markdown
Author

🔗 Paperclip issue: BLO-20396
🔗 Paperclip issue: BLO-20885
🔗 Paperclip issue: BLO-22418

1 similar comment
@allyblockcast

allyblockcast Bot commented Aug 15, 2026

Copy link
Copy Markdown
Author

🔗 Paperclip issue: BLO-20396
🔗 Paperclip issue: BLO-20885
🔗 Paperclip issue: BLO-22418

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.

0 participants