test(code-splitting): assert final-topology SCC wrapping invariant under strict order#10321
Draft
hyfdev wants to merge 3 commits into
Draft
test(code-splitting): assert final-topology SCC wrapping invariant under strict order#10321hyfdev wants to merge 3 commits into
hyfdev wants to merge 3 commits into
Conversation
…nistic and constant-time Two independent fixes to the strict-execution-order cross-chunk link pass: - add_transitive_esm_init_depended_symbols iterated an FxHashMap via values(), whose bucket order follows FxHash layout. FxHash is unseeded but hashes differently on 32-bit vs 64-bit, so that order (which flows into the chunk's depended_symbols FxIndexSet and thence into imported-symbol $1/$2 rename order in deconflict_chunk_symbols) could diverge between native and wasm32/WASI builds. Iterate sorted by the owning StmtInfoIdx to pin one order everywhere. - module_is_in_live_chunk did a linear chunk.modules.contains scan, called for every canonical referenced symbol of every included statement under strict, making the pass quadratic on large chunks. Replace with an O(1) module_to_chunk + liveness check. Sound because add_module_to_chunk sets both together and every module-removal site pairs the removal with clearing module_to_chunk, reassigning it to the destination chunk, or marking the chunk Removed; no site leaves module_to_chunk pointed at a still-live chunk that no longer contains the module, so no removed-module set is needed.
…der strict order The emergent-cycle projector's soundness rests on mirroring the linker's three init registration paths. One consumption disjunct (referenced_symbols_by_entry_point_chunk) has no projection counterpart, so a future projector hole would surface only as a fuzzer-caught `init_* is not a function` runtime crash. Add a debug-only, strict-gated check that re-runs Tarjan over the FINAL imports_from_other_chunks chunk graph and asserts the exact obligation close_cyclic_chunk_members discharges: every module hosted in a nontrivial SCC (>=2 chunks, or a self-loop) that is both order-sensitive AND order-wrap-eligible is order-wrapped in the plan. This turns any future under-projection into a deterministic debug/CI build failure instead of a runtime crash. It is a structural invariant like the existing empty-facade zero-static-indegree assert, not the internal semantic verifier design.md rejects. The obligation is deliberately is_order_sensitive && is_order_wrap_eligible, not raw is_order_wrap_eligible: a side-effect-free, import-free eligible leaf (e.g. `export const x = 1`) is never wrapped by the projector, yet can be co-hosted in a chunk that lands in a cycle because of its siblings' cross-chunk imports, and leaving it unwrapped is correct. Reuses is_order_sensitive and is_order_wrap_eligible (visibility widened to pub(super)) instead of duplicating their conditions. Zero fixtures trip the assert; zero snapshot changes.
hyfdev
force-pushed
the
codex/strict-scc-final-topology-assert
branch
from
July 16, 2026 15:14
ede4fd5 to
bc71bc1
Compare
hyfdev
force-pushed
the
codex/strict-transitive-init-determinism
branch
2 times, most recently
from
July 22, 2026 03:38
d427f05 to
4039bf3
Compare
graphite-app
Bot
force-pushed
the
codex/strict-transitive-init-determinism
branch
from
July 22, 2026 06:58
4039bf3 to
1ed58f4
Compare
Base automatically changed from
codex/strict-transitive-init-determinism
to
main
July 22, 2026 07:04
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.
Summary
Adds the structural assert the review recommended ("One structural assert I'd add"). The emergent-cycle projector's soundness rests on mirroring the linker's three init-registration paths, and one consumption disjunct (
referenced_symbols_by_entry_point_chunkincollect_frozen_reexport_usage) has no projection counterpart. No concrete break was constructed, but under-projection is the crash direction this machinery exists to prevent — a future hole would surface only as a fuzzer-caughtinit_* is not a functionruntime crash.This adds a
#[cfg(debug_assertions)], strict-gated check that, after the final cross-chunk edges are assembled, re-runs petgraphtarjan_sccover the finalimports_from_other_chunkschunk graph and asserts the exact obligation the projector discharges: every module hosted in a nontrivial SCC (≥2 chunks, or a self-loop) that is both order-sensitive and order-wrap-eligible is order-wrapped in the plan. It converts any future projector hole from a fuzzer-only runtime crash into a deterministic debug/CI build failure. It is a structural invariant like the existing empty-facade zero-static-indegree assert — not the internal semantic verifierdesign.mdrightly rejects.The obligation is deliberately
is_order_sensitive && is_order_wrap_eligible, matchingclose_cyclic_chunk_members(order_analysis.rs), not rawis_order_wrap_eligible. A side-effect-free, import-free eligible leaf (e.g.export const x = 1) is never wrapped by the projector, yet can be co-hosted in a chunk that lands in a cycle because of its siblings' cross-chunk imports — leaving it unwrapped is correct, so a raw-eligibility assert would spuriously trip on valid on-demand builds. Reuses the existingis_order_sensitiveandis_order_wrap_eligiblepredicates fromorder_analysis.rs(visibility widened topub(super)) instead of duplicating their conditions.Behavior / snapshot impact
None. Debug-only assert, no runtime/output change. Zero fixtures trip the assert across the full suite, and zero snapshot changes.
Validation
cargo test -p rolldown(debug build, so the assert runs against every fixture) — 1868 passed, 0 assert trips, snapshot-stable. (Same 5 pre-existing environmental failures as the base:cjs_module_lexer_compat×3 /npm_packagesneedcjs-module-lexerinstalled;test262needs the submodule.)cargo fmt --all --check— clean.cargo clippy -p rolldown --all-targets -- -D warnings— clean.Follow-up to #10104; addresses the "One structural assert I'd add" recommendation from the review discussion: #10104 (comment)
Draft, stacked on
codex/strict-transitive-init-determinism.