Repository navigation
fix(signals): close the probe's state around a memo isPending pulls (#4429) - #4465
Conversation
…4429) `verdictValue` pulls a dirty memo with the dispatch closed (`setVerdict(null)`, A31: the pulled memo's pass is its own) but left `probing` and `latestActive` set. A `latest()` / `isPending()` the pulled memo made itself re-entered the window with the outer probe's state: - `latest()` of a born-held node took the probe's `joinPass` arm, so the memo's pass joined the hold and its value was held with it; - a flight its `latest()` read set `probeFound`, so the outer `isPending` answered for the memo's reads, not for the memo; - inside `latest(fn)`, the memo's own `isPending` of a held write read as a probe inside a `latest` window and answered final. Each depended on who woke the memo. Save and clear both flags around the pull, as the dispatch already is. `probeFound` needs no save: it is only set while `probing`. Fixes #4429 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
Resolves verdict.ts beside #4438's shadow hook (the window's state is restored before the shadow's decision point) and the generated RULES-INDEX.md (regenerated). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
Narrow the fix to `probing`, the state #4429 names: +9 B brotli / +13 B minified on `+ isPending/latest`, where clearing `latestActive` too cost +25 / +25. `latestActive` leaks the same way (inside `latest(fn)`, a pulled memo's own `isPending` of a held write answers final); that is left for its own issue and decision. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
… pass) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
…fied) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
…-x1ore2-4429 # Conflicts: # scripts/size/scenarios.js
…minified) Frozen floor 38.76 KB -> 38.80 KB, recorded minified 117,227 -> 117,328 B (+13 B this fix; the rest is next's growth since the floor was recorded). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
…-x1ore2-4429 # Conflicts: # scripts/size/floor-caps.json # scripts/size/scenarios.js
🦋 Changeset detectedLatest commit: ff76ebc The changes in this PR will be included in the next version bump. This PR includes changesets to release 15 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Size (brotli, eager entry chunk)
Bundled with Rolldown (what Vite ships), brotli q11, decimal KB. A scenario fails only when it is over its brotli cap and its minified size is more than 20 B over the minified recorded with the cap; over the cap within that allowance is brotli layout noise and passes with a warning. Caps and their recorded minified in |
Coverage Report for CI Build 41079575274Coverage remained the same at 78.1%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Merging this PR will improve performance by 12.63%1 warning
Performance Changes
Tip Curious why performance improved? Comment Comparing Footnotes
|
|
I don't think either CodSpeed flag comes from this PR. The base (
I'm treating both as base-outlier noise. Generated by Claude Code |
The probe now restores `probing` around a pulled pass, so the entry can only hide a regression. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015hPxMkC3jg3Uivh65gvaf2
Before:
verdictValuepulls a dirty memo with the dispatch closed (setVerdict(null); A31 says the pulled memo's pass is its own), but it leftprobingset. Alatest()the pulled memo called itself then re-entered the window with the outer probe's state:latest()of a born-held node took the probe'sjoinPassarm, so the memo's pass joined the hold and its value was held with it.latest()read setprobeFound, so the outerisPendinganswered for the memo's reads instead of for the memo.After: a memo pulled inside
isPending()computes as its own pass. Alatest()it calls doesn't join a hold through the probe, and its reads don't answer the outerisPending.How:
verdictValuesavesprobing, clears it for the pulled pass, and restores it afterwards. ClearinglatestActivetoo would have cost +25 B. That case (insidelatest(fn), a pulled memo's ownisPendingof a held write answers final) is left for its own PR.Size vs next, measured locally (linux): +13 B minified only on bundles that ship
isPending/latest, +9 B brotli on+ isPending/latest. Hello world +0. No cap changes.Tests: new
packages/signals/tests/probe-pulled-pass-4429.test.ts, which fails on next. Signals 6,027 passed. Web 1,560, hydrate 716 and solid 916 passed. Server 1,905 passed; the only failure is the known #3311 one. Solid'scross-package-fieldsfails on next too.Fixes #4429
Generated by Claude Code