Skip to content

docs(signals): rules index, async spec reorganized by topic, superseded text separated from live rules - #3432

Merged
ryansolid merged 7 commits into
nextfrom
docs/rules-index
Sep 14, 2026
Merged

ryansolid merged 7 commits into
nextfrom
docs/rules-index

Conversation

@ryansolid

Copy link
Copy Markdown
Member

Docs, one generator script, one test. No source under packages/*/src is touched, so no changeset.

What

docs/RULES-INDEX.md (generated by scripts/rules-index.mjs) — every rule ID cited from src/ or tests/ with its status, definition site and citation counts: the A/B/C/V ids of the async spec, INV/RUL of the internals docs, the § node-shape/store sections, and the five rules-mining R vocabularies. 305 rules. tests/rules-index.test.ts gates that every ID cited in src/ resolves to a definition (77 ids today; 9 were dangling before this branch).

docs/NODE-SHAPE.md — recovers §11/§12 (node-literal shape, _notifiedAt, companion placement) from the deleted DESIGN-PATCH-CHANNEL.md via git history; §12d/§12e reconstructed from the code comments that cite them. INV-8 gets a RETIRED entry.

docs/SPEC-ASYNC-SEMANTICS.md — the Tier-A table becomes topic sections (Reads and visibility, Verdicts, Transactions and holds, Loading window and seeds, Errors), each rule as ### A<n>. <title> with an explicit Status line, its Pinned by tests, and a Mechanism cross-reference (the node fields / functions the rule requires; every identifier checked against src/). Every proposition, ruling and pin is carried verbatim (asserted by the transform); IDs are never renumbered. Tier B/C, the fixed violations and the re-ruling logs move unchanged under History. 200 KB → 70 KB — the difference was table-cell padding.

Three rules had superseded text posing as live and get a Statement (current) / History (superseded, kept verbatim) split with a retitle:

docs/INTERNALS-ASYNC-STATE.md — dated findings §5a–§5h move verbatim under History with a note on which still govern (§5d/§5e/§5g/§5h live; §5a–§5c historical; §5f superseded).

docs/rules-mining/ — each file names its namespace (CS/OL/OS/PJ/RS) and how source comments cite it; README with the table. A bare R<n> was ambiguous five ways.

Why

Prerequisite for judging a single read-side visibility resolver on the only criterion that shrinks brotli — removing decision sites — which needs, per rule, the fields a read consults. That column now exists. It also stops the two failure modes found in the inventory: dangling § citations in source comments, and amendments appended after the sentence they contradict.

Verification

  • node scripts/rules-index.mjs --check — every src/ citation resolves (77 ids)
  • pnpm vitest run in packages/signals — 167 files / 1784 tests green
  • Transform scripts asserted byte-for-byte preservation of all 27 propositions; the A17/A18 restructures asserted token-multiset equality

One known unresolved test-side citation: A28, defined in #3337 (unmerged).

Made with Cursor

ryansolid and others added 6 commits September 14, 2026 10:05
…e stage-3 node-shape sections

Source comments in @solidjs/signals cite rule IDs from six vocabularies:
A<n> (spec), V<n> (fixed violations), INV-<n> (invariants), RUL-<n> (store
rulings), R<n> (rules-mining — five files that EACH number from R1, so a
bare R<n> is ambiguous five ways) and §<n> (design sections). Six citations
resolved to nothing: §11b, §12, §12b, §12c, §12d, §12e were entries in the
Stage-3 increment log of DESIGN-PATCH-CHANNEL.md — the patch-channel journal
that was carried into the monorepo only from §17 and deleted with the
feature (d601119) — and INV-8 was a retired invariant whose definition
had gone with its mechanism.

- docs/NODE-SHAPE.md: the stage-3 node-shape decisions restored under their
  original numbers — §11b presence bits, §12 cold-field extension, §12b
  zombie pair + plain-commit fast drain, §12c what stays in the core
  literal (recovered from packages/solid-signals/DESIGN-PATCH-CHANNEL.md at
  3a505c7); §12d staged-rewrite fast path and §12e signal-literal diet
  reconstructed from the code comments that cite them, marked as such.
- INTERNALS-ASYNC-STATE.md: INV-8 entry (RETIRED 2026-07-07b) recording
  what the hold-provenance invariant proved before revert targets were
  eliminated, so invariants.ts's citation resolves.
- docs/RULES-INDEX.md (generated): 305 rules across the six vocabularies
  with status (live / ruled / amended / superseded / retired / fixed /
  promoted), definition site, and src/test citation counts; R-ids
  namespaced CS/OL/OS/PJ/RS without renumbering (comments qualify with
  core/opt/proj/snap; a bare R<n> resolves to the citing module's file,
  else core-store); tier ids promoted into A-rules ("(was B1)") resolve to
  the row they became.
- scripts/rules-index.mjs generates it; --check fails on any src/ citation
  without a definition. tests/rules-index.test.ts runs the check.
- SPEC / both INTERNALS headers point at the index. IDs are never renumbered.

Co-authored-by: Cursor <cursoragent@cursor.com>
…History

SPEC-ASYNC-SEMANTICS.md: the Tier-A table (27 rows, 130 KB of cell padding)
becomes topic sections — Reads and visibility, Verdicts, Transactions and
holds, Loading window and seeds, Errors — each rule as "### A<n>. <title>"
with an explicit **Status** line (ruled / ruled, amended in place /
superseded by), its **Pinned by** tests, and a **Mechanism** cross-reference
(the node fields and functions the rule requires — the column a single
visibility resolver would be built from; added by the index, not part of the
ruling). Every proposition, ruling and pin is carried over verbatim (checked
by the transform); A20/A21 stay at their IDs under "Superseded rules";
Tier B/C, the fixed violations and the three re-ruling logs move unchanged
under History. 200 KB → 70 KB, no ID renumbered.

INTERNALS-ASYNC-STATE.md: the dated findings §5a–§5h move verbatim under
"History — dated findings" with a note in their place saying which still
govern (§5d/§5e/§5g/§5h live; §5a–§5c historical; §5f superseded).

scripts/rules-index.mjs reads the new section format; every src/ citation
still resolves (77 ids), tests/rules-index.test.ts green.

Co-authored-by: Cursor <cursoragent@cursor.com>
Each rules-mining file numbers from R1 (58 / 37 / 46 / 36 / 38 rules), so a
bare R-id is ambiguous five ways. Each file now opens with its namespace
(CS / OL / OS / PJ / RS), how source comments cite it (core / lanes / opt /
proj / snap R<n>) and which module's bare citations resolve to it;
rules-mining/README.md carries the table. Matches scripts/rules-index.mjs's
resolution rules. No ID renumbered.

Co-authored-by: Cursor <cursoragent@cursor.com>
…t in src

backfillCompanion → the _pendingValue backfill at companion creation (#3041);
_affectsSentinel → _affectsNodes (on the transaction); createShadowDraft →
the projection-trap status gate (#2988, proj R23). Found by checking every
identifier named in a Mechanism line against src/.

Co-authored-by: Cursor <cursoragent@cursor.com>
…uperseded mechanism

The title "arriving truth holds until commit" restated the 2026-07-07b
mechanical model (hold in _pendingValue, elevate at commit, unobservable
under the mask) — the sentence the 2026-09-09 re-rule (#3331) explicitly
replaced. Live rule: a newer truth from the source removes the optimism from
the graph immediately; only the display keeps the override until the
transaction commits.

The section now leads with **Statement (current)** — lifetime bound to the
own transaction, the #3331 supersession, 09-10 scope and provenance,
consequences, store/node ownership corollaries, pins — and keeps the
07-07b mechanical sentence and the formulation it replaced under
**History (superseded mechanism, kept verbatim)**. Every token of the
original proposition is present (asserted); nothing reworded. Status and
Mechanism lines updated to lead with the supersession machinery.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ead A21 clause

A17's body opened with the 2026-07-06 wording ("THE value for every read —
ambient/untracked and tracked alike"; "do NOT mask the override from any
read path") and appended the 2026-09-09 amendment (#3331) that contradicts
the tracked half: after the node's own source lands, tracked derivations
see the arrived truth and only the display keeps the override. Same
failure as A18's title. The section now leads with Statement (current) —
the #3331 split, then the still-true 07-06 reasoning (the future until we
know otherwise; direct read shows optimistic, effect waits) — and keeps
the two replaced sentences verbatim under History. Retitled from "THE
value for every read" to the display/graph split. Status and Mechanism
updated. Every token preserved (asserted).

A22 cited "the decree that silences it (A21)" as live; A21 is superseded
by A24 and nothing silences a new question. Annotated in place so the
sentence's A9 half reads as the only live part.

Co-authored-by: Cursor <cursoragent@cursor.com>
@changeset-bot

changeset-bot Bot commented Sep 14, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 6ba9bc2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coveralls

coveralls commented Sep 14, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 34878719253

Coverage remained the same at 71.842%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1007
Covered Lines: 772
Line Coverage: 76.66%
Relevant Branches: 790
Covered Branches: 519
Branch Coverage: 65.7%
Branches in Coverage %: Yes
Coverage Strength: 15.02 hits per line

💛 - Coveralls

Second gate in scripts/rules-index.mjs --check (run by
tests/rules-index.test.ts): every A-rule not superseded must be cited by
ID from at least one test file. The spec's "Pinned by" column was prose —
a renamed or deleted pin was caught by nothing. Nine A-rules had pins that
never carried the ID (A3 A4 A5 A6 A8 A10 A11 A12 A27); the describe/it
names of those pins now do. A10 was cited in src/ and by no test, which
the earlier "uncited anywhere" list missed.

A4 (a custom equals is never invoked with undefined prev on first commit)
was only covered implicitly — every comparator in equals-comparator-errors
dereferences prev unguarded and the first commit succeeds. It now has a
direct pin that records the comparator's calls: none on first commit, one
with the committed prev on the next write.

Co-authored-by: Cursor <cursoragent@cursor.com>
@codspeed-hq

codspeed-hq Bot commented Sep 14, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by ×2.4

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 159 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
projection derive: write one NESTED field (reference) 545.8 µs 223.2 µs ×2.4

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing docs/rules-index (6ba9bc2) with next (da6ed76)

Open in CodSpeed

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.

2 participants