Skip to content

fix(signals): an optimistic store override survives its key becoming unobserved (S7; store follows signal) - #3521

Closed
ryansolid wants to merge 1 commit into
fix/store-untracked-born-heldfrom
fix/store-follows-signal-a28-override
Closed

ryansolid wants to merge 1 commit into
fix/store-untracked-born-heldfrom
fix/store-follows-signal-a28-override

Conversation

@ryansolid

@ryansolid ryansolid commented Sep 17, 2026

Copy link
Copy Markdown
Member

Stacked on #3520 (← #3517#3516#3515). Under the ruling "store rules should follow signal rules" (2026-09-17), this ships S7 and defers S6.

S7 — an override survives its key becoming unobserved

The slot hook released a property node the moment its last subscriber left — with the optimistic override on it (overrides live on nodes, over a clone the setter discards). s.n read 0 while the action was live; an optimistic signal keeps its override whether or not anything reads it.

A node carrying an override or a staged write now defers its release to the flush that resolves it: deferSlotRelease feeds transientStoreNodes, a sweep the scheduler has had since the monorepo absorb with exactly these checks (pending / override / affects) and that nothing fed. Released at settle — pinned.

+55 B minified store, +0 core. No size caps exceeded.

S6 — ruled, deferred

A28 at the backing: a mainline setStore is invisible to a derivation created inside a foreign action until the carrying flush; the signal already behaves this way. Ruled store-follows-signal. The first cut of this PR did it at the store twin and it cost +402 B minified — a node born in the unflushed window has to stage the write, and every arm existed twice (core's and the store's). Declined at that price. It's pinned at the store's current value in posture-store-parity S6 with the ruling attached, and becomes the first concrete target of step 6 (the store's value selection sharing core's serve), where the arm moves once instead of being written twice. Design-doc ledger updated with both.

Gate

check result
signals suite 2996 pass
visibility oracles identical to next
posture matrix (851) only the S7 cells moved (override-active × gatedAway after-gate; override-ambient × latest × foreign postures), all to the signal's values
solid-js / web 623 pass / same 12 pre-existing server-diagnostics failures as origin/next
size +55 B minified store; caps unchanged from #3520

@changeset-bot

changeset-bot Bot commented Sep 17, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 59ed7fd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@solidjs/signals Patch
test-integration Patch
@solidjs/web Patch
@solidjs/babel-plugin Patch
@solidjs/compiler Patch
@solidjs/diagnostics Patch
@solidjs/element Patch
@solidjs/h Patch
@solidjs/html Patch
solid-js Patch
@solidjs/universal Patch

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

…unobserved (S7; store follows signal)

Ruling 2026-09-17: store rules follow signal rules. Of the two divergences
the 7-reader posture matrix recorded in #3520, this ships S7 and defers S6.

S7 — the slot hook released a property node the moment its last subscriber
left, with the optimistic override on it (overrides live on nodes over a
clone the setter discards): s.n read 0 while the action was live, where an
optimistic signal keeps its override whether or not anything reads it. A
node carrying an override or a staged write now defers its release to the
flush that resolves it (deferSlotRelease feeds the scheduler's
transientStoreNodes sweep — present since the monorepo absorb with exactly
these checks, and unfed). +55 B minified store. Pinned: override visible
after gating away; node released at settle.

S6 — A28 at the backing (a mainline setStore invisible to a derivation
created inside a foreign action until the carrying flush) is ruled the same
way but DEFERRED: done at the store twin it cost +402 B minified (a node
born in the unflushed window must stage the write, and every arm existed
twice — core's and the twin's). Pinned at the store's current value with
the ruling attached; it closes when the store's value selection shares
core's serve (DESIGN-CONSOLIDATION move 3b step 6). Ledger updated.

Gate: suite green; oracles identical; matrix: only the S7 cells moved, to
the signal's values; solid/web unchanged from next; no size caps exceeded.

Co-authored-by: Claude via Cursor <noreply@cursor.com>
@ryansolid
ryansolid force-pushed the fix/store-follows-signal-a28-override branch from 59ed7fd to 68e5cbb Compare September 17, 2026 18:07
@ryansolid ryansolid changed the title fix(signals): store follows signal — A28 at the backing, an override survives its key becoming unobserved (S6, S7) fix(signals): an optimistic store override survives its key becoming unobserved (S7; store follows signal) Sep 17, 2026
@ryansolid

Copy link
Copy Markdown
Member Author

Superseded by #3523, which now targets next directly and carries this PR's commit (rebased) along with the rest of the stack. Closing so the move-3b work is one review rather than five.

Claude via Cursor

@ryansolid ryansolid closed this Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant