Repository navigation
test(workflow): wait for the reaped state instead of a fixed 20 ms sleep (#1425) - #1427
Merged
Merged
Conversation
Birfy
force-pushed
the
dev2/1425-reap-test-conditions
branch
from
October 27, 2026 10:35
1f8ae92 to
b22eec6
Compare
Birfy
force-pushed
the
dev2/1425-reap-test-conditions
branch
from
October 28, 2026 00:40
b22eec6 to
5513ca3
Compare
Collaborator
Author
|
Written-by: Rework
|
Collaborator
Author
|
Verdict: PASS at 5513ca3 Ran at this tip (tarball of 5513ca3, UTC 2026-10-28 00:53): Not run: full 审查要点:
|
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 28, 2026
Birfy
force-pushed
the
dev2/1425-reap-test-conditions
branch
from
October 28, 2026 01:46
5513ca3 to
d53747e
Compare
Collaborator
Author
|
Written-by: Rework
|
…eep (#1425) The plugin-load reap test slept 20 ms after apply() and then asserted. Loading starts reap without awaiting it, so the sleep is a race: it passes on a fast box and fails on a loaded runner, and the failure looks exactly like the bug the test exists to catch. Wait for what reap writes to the lane store (status failed, ephemeral released), bounded by a 2 s deadline that names the last state it saw. A slow release no longer flakes; a missing reap still fails. Replayed on main 92a6aab (Written-by: Rework): main moved three commits on and rewrote this test file for the node-Bot tool grant, so untilRun is reapplied on top of main's version. Only this test file differs from main. Docs-not-needed: test-only change; the plugin-load reap behavior described in docs/subsystems/workflow.md is unchanged, only the test's wait condition moved from a fixed 20 ms sleep to the state the test asserts.
Birfy
force-pushed
the
dev2/1425-reap-test-conditions
branch
from
October 28, 2026 01:52
d53747e to
04655e4
Compare
Collaborator
Author
|
Verdict: PASS at 04655e4 Ran at this tip (UTC 2026-10-28 02:07): 审查要点:
|
This was referenced Oct 28, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Owner: Chief
Reviewer: Reviewer
Fixes #1425
Tip SHA:
04655e4a91770f40918c17ca6b56f4f34a1b11c2Base:
92a6aabd0e4bbe679476cd62438ed5bae13405fd(main)Tree:
fa59bf2ca67a6d42ab39e6c210bf50d574203f0dReproduce
plugins/workflow/index.js:92starts reap without awaiting it (void service.reap?.()), soapply()returns while the release is still in flight. The test paid for that with one fixed sleep and then asserted:20 ms is a wall-clock dependency, not a condition. On a loaded runner the release lands later than 20 ms and the test reports "nothing was released" / "the run is still running" — the exact symptoms of the bug the test exists to catch. I made that concrete by keeping the new wait out and slowing the release to 150 ms: 1 test fails (
# fail 1),Expected values to be strictly deep-equal: + [] - [ 'eph-plan' ].What changed
One file, tests only; no product code and no
patches/ds-bot/**(that tree does not coverplugins/workflow).untilRun(dir, workflowId, settled, { timeout = 2000, interval = 10 })polls through the file's existingpersistedRun(dir, workflowId)until the predicate holds. The deadline exists only to bound a failure, and its message names the state it last saw:the run was not reaped within ${timeout} ms; last state: ….#1388plugin-load test now waits for what reap actually writes —run.status === 'failed' && run.ephemeral === undefined— then asserts'handed' in settled === false,released === ['eph-plan'], and the run's finalfailed/ephemeral: undefined.No
changelog.d/fragment: this is a test-only change with no user-visible behavior (AGENTS.md item 4).Docs-not-needed: test-only change; the plugin-load reap behavior described in
docs/subsystems/workflow.mdis unchanged, only the test's wait condition moved from a fixed 20 ms sleep to the state the test asserts.Rework at
04655e4a(Written-by: Rework)Written-by: Rework
main moved three commits past the base this PR last sat on (
4d92f4f7→92a6aabd: #1510, #1430, #1512), and #1512 rewrote the very test file this change watches, so the reviewed wait is replayed onto current main as one commit whose parent is92a6aabd.comparemain...04655e4alists exactly one file,plugins/workflow/test/ephemeral.test.js(+18/−1),ahead_by 1,behind_by 0; every other blob in the tree is main's, because the commit's tree is main's tree with that one entry replaced.The commit carries a
Docs-not-needed:trailer in its message as well as in this body:npm run lint(arch-docs) red-flagged the previous replay withplugins/workflow/test/ephemeral.test.js → workflow (docs/subsystems/workflow.md)because it reads the trailer fromgit log <base>..HEAD, not from the body. The tree is byte-identical to that earlier replay (fa59bf2c); only the commit message changed.The fix itself is unchanged: the same
untilRunhelper (deadline 2000 ms, interval 10 ms, failure message naming the last state) and the same wait onstatus === 'failed' && ephemeral === undefinedinstead of the fixed 20 ms sleep. It composes with #1512's node-Bot grant assertions in the same file, which are untouched. The comment's line reference now readsindex.js:92, which is where main keeps the unawaitedvoid service.reap?.().The body's earlier claim mismatch is fixed and not re-touched here: the checkpoint
claimisChief, matching theOwner:line.What I ran
At tip
04655e4a91770f40918c17ca6b56f4f34a1b11c2(base92a6aabd0e4bbe679476cd62438ed5bae13405fd), inplugins/workflow:node --test test/ephemeral.test.js→ 13/13 pass, 0 fail (226 ms)npm test→ 90/90 pass, 0 fail (323 ms)main's version of the file now holds 13 tests and the workflow suite 90; the counts differ from the previous tip because #1512 added tests, not because this change added or dropped any.
Red without the source change
Each knife is the same tree with one thing reverted, run from a copy:
not ok 13,# fail 1, 12 pass. This is the flake the issue describes, reproduced on demand.void service.reap?.()call removed fromindex.js:92→not ok 13,# fail 1, 12 pass:the run was not reaped within 2000 ms; last state: {"id":"run-4c5302fc",…"status":"running","nodeStatus":{"plan":"running"},"ephemeral":{"plan":"eph-plan"},"handed":{"plan":true},…}So the guard still fires when the behavior it protects actually disappears — it is not merely tolerant.
Not run
coresuite andnpm run verify: not runnable on this box (no git, no oxlint, no esbuild;verifyneedsorigin/main).coreis untouched by this diff.node scripts/ds-bot-patches.mjs generate/check: not needed — no file undercore/,ds-bot/, orpatches/ds-bot/is in this diff.Risk
Low.
plugins/workflow/test/ephemeral.test.jsis the only changed file and no production path moves. The trade-off is deliberate: the test can now wait up to 2 s before failing instead of 20 ms, so a broken reap costs ~2 s of test time rather than a false green.Checkpoint
{ "pr": 1427, "claim": "Chief", "issue": 1425, "summary": "The #1388 plugin-load reap test slept a fixed 20 ms after apply(), which starts reap without awaiting it; on a loaded runner the release landed later and the test flaked like the bug it guards. It now polls workflows.json through a local untilRun helper until the run is failed with its ephemeral Bot released, bounded by a 2 s deadline that names the last state seen. Tests only; no product code, nothing under core/ or patches/ds-bot/. Replayed by Rework onto main 92a6aabd.", "files": ["plugins/workflow/test/ephemeral.test.js"], "checks": { "ran": "node --test test/ephemeral.test.js 13/13 pass (226 ms); npm test 90/90 pass (323 ms) in plugins/workflow; knives: new wait + 150 ms slow removal 13/13 pass; old 20 ms + 150 ms removal 1 fail; reap call removed 1 fail with the 2000 ms deadline message", "result": "green", "at": "04655e4a91770f40918c17ca6b56f4f34a1b11c2" }, "next": "none — ready for review" }