Filed by the domain:spec execution seat (#6017), session_01KB5PFtxuy1x3dcR5gxudx6, 2026-09-14T10:4xZ, from the out_of_scope_findings of the #17928 round (report 5662691490, PR #18175). ⛔ Not claimed, ⛔ not dispatched. Grading is triage's; domain:spec is set from the measured landing point (packages/spec/src/automation/** + packages/services/service-automation/src/builtin/wait-node.ts), ⛔ not guessed from the title.
⚠️ This card exists because the tree claimed it already did. A fixture comment on the #17928 branch asserted this residual had been "Filed separately". It had not — no such card existed. Commit 14cb2a66 corrects the comment rather than leaving it asserting a filing nobody made; this card discharges it for real.
Class (a) — a reproducible defect
#17928 / PR #18175 closes the absent waitEventConfig hole: a wait node with no block is refused at the contract, and a stored one fails the run loudly instead of parking forever with success: true.
⇒ A non-blank but unparseable or zero-valued timerDuration still reproduces the original defect, unchanged.
parseIsoDuration answers undefined for 'not-a-duration', 'P', 'PT0S' and '0' exactly as it did for the absent key. On that path:
- no deadline is computed,
- no job is armed,
- no
waitUntil is persisted,
- and the node still returns
{ success: true, suspend: true }.
⇒ The run reports success and parks forever, which is precisely the shape decision batch #127 item 5 ruled unacceptable — reached through a different door.
The repro is already live in the tree
packages/services/service-automation/src/builtin/wait-node.test.ts → 「cancels nothing for a timer wait that armed no job」, which asserts scheduled is empty on a paused run. ⇒ The behaviour is pinned today as expected; this card is the argument that the pin describes a defect rather than a contract.
⚠️ Source/test reading carried from the #17928 round, ⛔ not re-measured by this seat at filing time. A taker owes the re-measurement first.
Why it was NOT fixed in place by #17928
Stated by that round against the bounded in-place-fix criteria, and this seat agrees:
⇒ criteria 2 and 4 fail ⇒ out of scope, filed rather than folded. ⚠️ Whoever takes this should expect Clause-② to need its own judgement: refusing malformed durations narrows, but if the fix instead declares a new refinement or error code, that is a different answer.
Sibling recorded on the same round, deliberately NOT a second card
The four non-timer eventTypes carry no required resumer key of their own — { eventType: 'signal' } with no signalName parses, and the executor correlates on undefined. Same shape as the row above rather than an independent finding ⇒ this card is its carrier too. (Also recorded in PR #18175's ## Acceptance notes.)
Dedupe words
timerDuration · parseIsoDuration · malformed duration · silent suspend · wait node
⛔ This seat did not run a dedupe search (per 「立卡者不查重,只附查重词」). ⚠️ A duplicate check must include closed cards — #17939 was a closed duplicate of #17928 and carried measurements that mattered.
Refs
#17928 (the absent-block half, ruled) · PR #18175 (its implementation; this residual is in its Acceptance notes) · #17939 (closed duplicate of #17928, carries the original real-run measurement) · #17843 (the measurement request)
Generated by Claude Code
Filed by the
domain:specexecution seat (#6017),session_01KB5PFtxuy1x3dcR5gxudx6, 2026-09-14T10:4xZ, from theout_of_scope_findingsof the #17928 round (report5662691490, PR #18175). ⛔ Not claimed, ⛔ not dispatched. Grading is triage's;domain:specis set from the measured landing point (packages/spec/src/automation/**+packages/services/service-automation/src/builtin/wait-node.ts), ⛔ not guessed from the title.14cb2a66corrects the comment rather than leaving it asserting a filing nobody made; this card discharges it for real.Class (a) — a reproducible defect
#17928 / PR #18175 closes the absent
waitEventConfighole: awaitnode with no block is refused at the contract, and a stored one fails the run loudly instead of parking forever withsuccess: true.⇒ A non-blank but unparseable or zero-valued
timerDurationstill reproduces the original defect, unchanged.parseIsoDurationanswersundefinedfor'not-a-duration','P','PT0S'and'0'exactly as it did for the absent key. On that path:waitUntilis persisted,{ success: true, suspend: true }.⇒ The run reports success and parks forever, which is precisely the shape decision batch #127 item 5 ruled unacceptable — reached through a different door.
The repro is already live in the tree
packages/services/service-automation/src/builtin/wait-node.test.ts→ 「cancels nothing for a timer wait that armed no job」, which assertsscheduledis empty on a paused run. ⇒ The behaviour is pinned today as expected; this card is the argument that the pin describes a defect rather than a contract.Why it was NOT fixed in place by #17928
Stated by that round against the bounded in-place-fix criteria, and this seat agrees:
timerDurationnarrows the accept set beyond what decision batch 🔗 Broken links detected in documentation #127 item 5 covers — that ruling requires the block and the key, ⛔ it does not rule on the key's lexical validity.waitnode with nowaitEventConfigparses clean and suspends forever withsuccess: true— require the block (andtimerDurationfor timers) at the contract, retire the executor's?? 'timer'; declarehttp_request.method/screen.modedefaults per the executor (objectui#9354's objectstack half) #17928's gate families carry.⇒ criteria 2 and 4 fail ⇒ out of scope, filed rather than folded.⚠️ Whoever takes this should expect
Clause-②to need its own judgement: refusing malformed durations narrows, but if the fix instead declares a new refinement or error code, that is a different answer.Sibling recorded on the same round, deliberately NOT a second card
The four non-timer
eventTypes carry no required resumer key of their own —{ eventType: 'signal' }with nosignalNameparses, and the executor correlates onundefined. Same shape as the row above rather than an independent finding ⇒ this card is its carrier too. (Also recorded in PR #18175's## Acceptance notes.)Dedupe words
timerDuration·parseIsoDuration· malformed duration · silent suspend · wait node⛔ This seat did not run a dedupe search (per 「立卡者不查重,只附查重词」).⚠️ A duplicate check must include closed cards — #17939 was a closed duplicate of #17928 and carried measurements that mattered.
Refs
#17928 (the absent-block half, ruled) · PR #18175 (its implementation; this residual is in its Acceptance notes) · #17939 (closed duplicate of #17928, carries the original real-run measurement) · #17843 (the measurement request)
Generated by Claude Code