You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AI-assisted follow-up to the review feedback on #3473, tracking what remains after merge and subsequent fixes.
Rechecked on next at 59c4192, including #3479 and #3488. Four independently reproduced regressions remain:
Torn effect input: an effect receives [1, 0, 1] before [1, 1, 1] (original comment A).
Stale visible derivation: Count publishes 1 while Copy displays 0 and its request is still pending (original comment C).
Lost visibility update: coalesced visibility writes leave content visible after every request has resolved. This is a different sequence from the now-fixed original comment B.
Delayed release: an ordinary write continues waiting on an unobserved request after removing its last reader and reading latest. This eventually completes; it is an unnecessary wait, not permanently lost state.
The repros below cover those four behaviors. Grouping them here carries forward the PR feedback; it does not assume one root cause. The same-value update-grouping change is listed separately as a contract question.
Representative playground: a stale derivation becomes visible
Paste this TSX into s.olid.uk using the current next build. Wait for all three values to show 0, then click Run. After one second, Direct disappears and Count shows 1 while Copy shows 0. Copy catches up about a second later. Count and its visible derivation should publish consistently.
This is original comment A. The signal and its synchronous identity memo disagree in a real effect callback: [1, 0, 1], then [1, 1, 1]. The pre-PR next control (3ae9e921) only delivers [1, 1, 1].
Final hide is lost after coalesced visibility writes
Wait for Data=0, click Run, then wait for all work to finish. Data remains 0 instead of becoming hidden. The pre-PR control eventually hides it. The independently controlled core version also confirms every request has resolved while the effect still displays 0.
The plain panel getter preserves the failing effect dependency graph. Inlining the conditional into JSX introduces a compiler-generated memo and masks this case. Adding a separate displayed reader of show also masks it.
Removing the last reader does not release the write
Count remains 0 after the only Details reader is removed and latest(details) is read. It only becomes 1 when the unused replacement request resolves. The same reduced code on pre-PR next (3ae9e921) releases Count to 1 without waiting for that request.
There are no actions in this repro. The pending work is no longer displayed or tracked by a reader; the subsequent latest call is untracked. This is the remaining latest-related release difference mentioned briefly in the original comment.
Separate contract question: repeating an already-held write
This behavior also changed in #3473 and remains changed:
// A and B initially display 0; an observed async memo derives from B.setB(1);awaittick();// B=1 is held by the pending async memo.setA(1);setB(1);// Repeat the already-held value in the same task as A's write.awaittick();
Pre-PR next holds A with B. Current next publishes A separately while B remains held. This is a verified grouping difference, but not classified here as a correctness bug: if repeating the same pending value is intended to be a no-op for grouping, that would explain it. Including it so the original feedback is accounted for rather than silently dropped.
Cases that are now fixed
Original comment B's exact sequence—unobserved Count update, show, hide alongside request resolution, then show again—now publishes the final show correctly. That does not fix the coalesced-toggle sequence above.
The ordinary show-then-hide release repro, without the extra latest/rewrite sequence, now releases the unobserved work.
All four behaviors independently reproduce outside the fuzzer on 59c4192a, in development and production with __TEST__=false.
The two TSX repros were compiled and executed in jsdom; this is not a claim of interactive browser verification. The two standalone core snippets were rerun as fresh processes on current next and the pre-PR next control.
Restoring only setSignal's previous outside-flush adoption of an existing transition removes the torn tuple and the coalesced visibility failure. The stale-derivation and latest-related release cases still fail with that diagnostic change. This is causal evidence, not a proposed fix; the new adoption condition also serves the intended mainline isolation semantics.
The original campaign retained additional candidates, including mount/control mismatches. These four examples are the independently reproduced behavior groups, not a claim that every retained candidate has the same cause or is covered by one fix. The fuzzer in test(signals): add experimental semantic fuzzer #3446 can be used to check the wider consequences while iterating.
AI-assisted follow-up to the review feedback on #3473, tracking what remains after merge and subsequent fixes.
Rechecked on next at 59c4192, including #3479 and #3488. Four independently reproduced regressions remain:
[1, 0, 1]before[1, 1, 1](original comment A).1while Copy displays0and its request is still pending (original comment C).latest. This eventually completes; it is an unnecessary wait, not permanently lost state.The repros below cover those four behaviors. Grouping them here carries forward the PR feedback; it does not assume one root cause. The same-value update-grouping change is listed separately as a contract question.
Representative playground: a stale derivation becomes visible
Paste this TSX into s.olid.uk using the current next build. Wait for all three values to show
0, then click Run. After one second, Direct disappears and Count shows 1 while Copy shows 0. Copy catches up about a second later. Count and its visible derivation should publish consistently.Torn tuple delivered to an effect
This is original comment A. The signal and its synchronous identity memo disagree in a real effect callback:
[1, 0, 1], then[1, 1, 1]. The pre-PR next control (3ae9e921) only delivers[1, 1, 1].Standalone core reproduction (TypeScript; top-level await)
Final hide is lost after coalesced visibility writes
Wait for Data=0, click Run, then wait for all work to finish. Data remains 0 instead of becoming hidden. The pre-PR control eventually hides it. The independently controlled core version also confirms every request has resolved while the effect still displays 0.
The plain
panelgetter preserves the failing effect dependency graph. Inlining the conditional into JSX introduces a compiler-generated memo and masks this case. Adding a separate displayed reader ofshowalso masks it.Playground reproduction (TSX)
Removing the last reader does not release the write
Count remains
0after the only Details reader is removed andlatest(details)is read. It only becomes1when the unused replacement request resolves. The same reduced code on pre-PR next (3ae9e921) releases Count to1without waiting for that request.There are no actions in this repro. The pending work is no longer displayed or tracked by a reader; the subsequent
latestcall is untracked. This is the remaining latest-related release difference mentioned briefly in the original comment.Standalone core reproduction (TypeScript; top-level await)
Separate contract question: repeating an already-held write
This behavior also changed in #3473 and remains changed:
Pre-PR next holds A with B. Current next publishes A separately while B remains held. This is a verified grouping difference, but not classified here as a correctness bug: if repeating the same pending value is intended to be a no-op for grouping, that would explain it. Including it so the original feedback is accounted for rather than silently dropped.
Cases that are now fixed
1:0action-end regression reported on fix(signals): five hold-consistency fixes — re-park sweep, first observer, lane outside view, zombie readers, unchanged-pass trims #3479 is also fixed; it is not being re-reported here.Verification and diagnostic context
59c4192a, in development and production with__TEST__=false.setSignal's previous outside-flush adoption of an existing transition removes the torn tuple and the coalesced visibility failure. The stale-derivation and latest-related release cases still fail with that diagnostic change. This is causal evidence, not a proposed fix; the new adoption condition also serves the intended mainline isolation semantics.