docs(signals): lean posture landed — contract answers, engine-cost cap 14 → 4 - #3654
Merged
Merged
Conversation
…4 → 4
Closes out the lean-posture proposal in
documentation/plans/responsiveness-findings-plan.md §Cost (landed with
with the gate as shipped — `wantsRerun() = log || folds.length > 0 ||
OBSERVE.records.observed("rerun")`, read at recomputeStart, honoured at
recordRerun — and the four contract questions answered:
- history("rerun") is empty for runs made while nothing wanted a record
and holds every record from the moment something did; why() is a view
of that buffer and shares its gate; subscriptions() reads the graph and
is unaffected. No enable({ reruns: true }) — document, no option.
- OBSERVE.records.subscribe("rerun", …) turns record-building on from the
next run start and off on unsubscribe; log and a registered fold do the
same. The bare attribution.subscribe went with #3644.
- The checks read the frame, not the record: checkEffectCycle,
checkRelayTear, checkHotRuns, checkHotTime, checkWastedRecompute,
checkDepWidth all run before the gate.
- @sentry/solid-2 dropping its rerun subscription is the follow-up in
getsentry/sentry-javascript#24517.
JSDoc on why()/subscriptions() and the diagnostics doc lines say the
same; attribution-lean-gate.test.ts pins WASTED_RECOMPUTE without a
record and why()/subscriptions() on a lean engine.
Tripwire (attribution-engine-cost.test.ts) re-measured 2026-09-24 under
vitest, six runs: folded 1.98–2.14x, listened 1.91–2.11x, lean
1.71–1.90x. The section's 490/55 ns ≈ 9x table was a different
flush-per-write micro-harness; the tripwire's numbers are the baseline
from here. Cap 14 → 4 (~85–100% headroom; trips when the engine costs
roughly double what it does today).
Co-Authored-By: Claude via Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
🦋 Changeset detectedLatest commit: a130c61 The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 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 |
Coverage Report for CI Build 36110683736Coverage remained the same at 73.611%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Merging this PR will not alter performance
Comparing Footnotes
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes out the lean-posture proposal in
documentation/plans/responsiveness-findings-plan.md§Cost — "Lean posture — proposal, needs a decision", landed with #3613 and implemented by #3644. #3644 shipped the gate and the checks off the frame; this PR records the decision and the contract answers in the plan so they are not rediscovered, fills the documentation/test gaps, and does the tripwire ratchet the #3613 cap comment asked for. Docs, JSDoc and tests only.The decision
Document, no option. There is no
enable({ reruns: true }): a consumer that wants re-run records subscribes torerunor imports a fold — the same "subscribing is what turns them on" the timeline records already had — so the engine has one gate rather than two that compose. The gate as shipped:wantsRerun() = log || folds.length > 0 || OBSERVE.records.observed("rerun"), read atrecomputeStart(it decides whether the dep snapshot the record's subscription diff needs is captured; notrecomputeEndas proposed — the snapshot is the first cost) and honoured atrecordRerun.Contract answers
history("rerun")on a lean enginenodeRuns). Documented onAttribution.history,RecordTypes,08-dev-diagnostics.md.attribution-lean-gate.test.tswhy()/subscriptions()why(node)is a view of that buffer and shares its gate (a node whose runs left no record has nonodeId).subscriptions(node)was never a record reader — it walks live_deps, so it answers with or without an audience and with the engine disabled. JSDoc added on both; doc lines added.OBSERVE.records.subscribe("rerun", …)turns records onlog: trueand a registered fold do the same. The bareattribution.subscribe(listener)went with #3644 — no untyped form to gate.checkEffectCycle,checkRelayTear,checkHotRuns,checkHotTime,checkWastedRecompute(frame.start,phase,changed,selfMs, causes),checkDepWidthall run inrecordRerunbefore theprevDeps === nullreturn.@sentry/solid-2as a lean consumerrerunsubscription;InteractionEvent.runs/runMsand theHOT_SCOPE_*/WASTED_RECOMPUTEfindings cover its per-interaction hot list). Performance Tracks stays a full consumer by design.Tripwire: cap 14 → 4
attribution-engine-cost.test.tsre-measured 2026-09-24 on the observe artifacts under vitest (M-series, best-of-5 interleaved), six runs: folded 1.98–2.14×, listened 1.91–2.11×, lean 1.71–1.90×. On the engine after rebasing onto #3650 (three more runs): folded 1.99 / 2.42 / 2.12×, listened 1.93–2.07×, lean 1.74–2.07×. The #3613 engine, re-measured by the same harness beside this one, was ~2.5–2.8×; the section's original 490/55 ns ≈ 9× table came from a different flush-per-write micro-harness and is not comparable, so the tripwire's numbers are the baseline from here.Caveat recorded in the cap comment: the ratio is harness-sensitive. A bare
nodeprocess (no vitest worker transform) measures idle at ~2.8 ms and the folded engine at ~3.1–3.7×, so a faster idle build raises the ratio without the engine changing.Cap 4: ~85–100% headroom over the folded baseline — trips when the engine costs roughly double what it does today per re-run, the same discipline as
observe-idle-cost's 1.25 over 1.03–1.09. The plan's## Costbullet ("cap 14 against a measured ~10") is updated to match.Tests
attribution-lean-gate.test.ts: 8/8 (6 existing +why()/subscriptions()on a lean engine, WASTED_RECOMPUTE without a record).attribution-engine-cost.test.tsat cap 4: 3/3 before the rebase, 3/3 after.@solidjs/signalssuite on the rebased branch: 230 files, 3720 passed / 2 skipped (3698 on the pre-rebase base).observe-idle-cost,attribution-wasted-recompute,attributionsuites green.Public API changes
None — JSDoc, docs and tests only.
Also
The #3644 PR body was updated to cite the plan section and point here for the ratchet.