test(signals): pin the direct-commit readers by posture over a held frame (#3482) - #3492
Conversation
…rame (#3482) until() and resolve() (CONFIG_DIRECT_COMMIT) created after a confirming frame was staged under an action's optimism: - inside the action after a bare `yield` — the action's own reader; the DIRECT_COMMIT arm delivers under its own hold and the action settles (the documented form, #3491); - inside the action from an `await` continuation with no bare `yield` — a mainline reader over its own hold: born held, replays at the commit its promise holds open, times out (#3482 as filed); - outside the action — a mainline reader over a FOREIGN hold: pending through the hold, served the committed view after the commit, never the unrevealed frame. The third is the pin the suite lacked: the exemption proposed in #3482 and declined in #3490 passed 2,733 tests while making a mainline resolve() serve another action's speculative frame. Verified: with that one-liner applied the second and third fail; on next all three pass. Rules index regenerated (the file cites A29). Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
Coverage Report for CI Build 35082758847Coverage remained the same at 71.46%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Merging this PR will degrade performance by 4.72%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing Footnotes |
Tests-only. Companion to #3491 (docs); follows the closed #3490.
Why
#3482 reported
yield until(...)deadlocking when the confirming frame landed before the call. The proposed fix — exemptingCONFIG_DIRECT_COMMITreaders from born-held inenterStagedRead— passed all 2,733 signals tests, yet it made a mainlineresolve()over an unrelated action's hold resolve with that action's unrevealed frame while the UI still showed the optimistic row. Nothing pinned that posture for the promise-delivery readers. This adds the pins.What is pinned
tests/direct-commit-readers-posture.test.ts— the optimistic-row + live-echo shape from the issue, the server broadcasting before it answers, so the confirming frame is held under the action's optimism. A reader created after that, by posture:yieldDIRECT_COMMITarm delivers under its own hold; action settles; commit revealsres_1:confirmed(the documented form)awaitcontinuation, no bareyieldTimeoutError(#3482 as filed)resolve()→"res_1"anduntil()→trueonly after the commit; never the held frameThe second row pins the consequence the
action()/until()docstrings now describe (#3491). The third is the one that was missing.Verified
On
nextall three pass. With #3490's one-liner applied, the second and third fail — the third is the leak. Full signals suite 2,737 / 2 expected fails unchanged;until,until-entanglement,resolve,resolve-in-action,born-held,rules-indexgreen. Rules index regenerated (the new file cites A29).Reproduction shape by @brenelz.