Skip to content

chore: merge train 252 — five fixes (v0.5.1632) - #10892

Merged
proggeramlug merged 7 commits into
mainfrom
land-train-252
Sep 21, 2026
Merged

proggeramlug merged 7 commits into
mainfrom
land-train-252

Conversation

@proggeramlug

Copy link
Copy Markdown
Contributor

Lands five PRs as v0.5.1632.

source change
#10866 fix(transform): keep enum references out of cross-module inlining
#10876 fix(compile): retain classes using multiline var bindings
#10867 fix(modules): preserve named Node builtin re-exports
#10874 fix(compile): resolve JSON requires from ESM module paths
#10862 fix(ui-macos): textSetColor no longer a no-op on a Text label

Assembly

Three needed resolution. #10867 and #10874 each add a module declaration to the same regression-test index — additive, both kept, sorted by issue number. #10862 conflicted in Cargo.toml/Cargo.lock/CLAUDE.md because its first commit bumps the version and a later one reverts it; contributor PRs do not bump, so its net diff was applied excluding those files.

collect_modules.rs was at exactly 2000 lines on main — the cap, zero headroom — so #10867/#10874 adding one line between them failed the required gate. Allowlisted with the #1435 block's rationale, and the reason it applies is structural: collect_module_one is a single ~1,890-line walk beneath 15 already-peeled siblings, so the next split is phase surgery on a walk, not a move of independent arms. A file trimmed to exactly the cap is a landmine — it passes for whoever trims it and fails for whoever touches it next.

Re-validated against the current base

The first sweep of this train was invalid and is not the evidence here: concurrent cargo commands were pointed at the same target directory the sweep was reading from, so perry emitted empty output on 44 tests that pass individually. That was my error, not the code's.

It was then re-run twice — once cleanly at v0.5.1630, and again here after rebasing onto v0.5.1631, because that release changed canonical_dir's path resolution and #10867/#10874 are about module resolution. Reusing the earlier result would have been evidence against a base that no longer exists.

import 20/0   require 5/0   module 14/0   export 8/0
enum    3/0   class  83/1   object 40/0

173 passing, zero regressions in every area. The single class failure is test_gap_2159_defineproperty_class_prototype, recorded in gap_snapshot.json as already-failing and PARITY_FAIL in trains 244, 246, 247 and 248 — all of which landed.

Gates

check_file_size, raw_handle_debt, addr_class_inventory, shape_descriptor_census, gc_store_site_inventory, gc_runtime_root_holders, check_test_registration all rc=0; cargo fmt --all -- --check clean; cargo check --workspace --all-targets under -D warnings clean.

#10859 (worker-thread module graph, 17 commits) genuinely conflicts and is deferred to its own pass.

Ralph Küpper added 7 commits September 21, 2026 15:58
Net diff of #10862 excluding its version-bump files: the PR's first commit
bumped [workspace.package] version and a later commit reverted it, so applying
the series conflicted in Cargo.toml/Cargo.lock/CLAUDE.md. Contributor PRs do
not bump the version; the maintainer does at train time.
The file was at exactly 2000 on main, so any PR adding a line fails the gate;
#10874/#10867 add one between them. collect_module_one is a single ~1890-line
walk under 15 already-peeled siblings, so the next split is phase surgery, not
a move of independent arms -- same rationale as the #1435 allowlist block.
@proggeramlug
proggeramlug merged commit 841b605 into main Sep 21, 2026
22 of 23 checks passed
@proggeramlug
proggeramlug deleted the land-train-252 branch September 21, 2026 14:39
@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: fe3e901f-6096-445f-92fd-e5fbfda8e33b

📥 Commits

Reviewing files that changed from the base of the PR and between f88acda and 8c8cd0a.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (27)
  • CLAUDE.md
  • Cargo.toml
  • changelog.d/10417-cross-module-enum-inlining.md
  • changelog.d/10660-cjs-multiline-var-hoist.md
  • changelog.d/10758-esm-static-json-require.md
  • changelog.d/10802-node-builtin-reexports.md
  • changelog.d/10862-textsetcolor-label.md
  • changelog.d/10874-collect-modules-at-cap.md
  • crates/perry-codegen/src/codegen/artifacts.rs
  • crates/perry-codegen/src/codegen/mod.rs
  • crates/perry-hir/src/lower/module_decl.rs
  • crates/perry-hir/tests/node_named_export_hygiene.rs
  • crates/perry-transform/src/inline/cross_module.rs
  • crates/perry-transform/src/inline/mod.rs
  • crates/perry-ui-macos/Cargo.toml
  • crates/perry-ui-macos/src/widgets/padding.rs
  • crates/perry-ui-macos/tests/native_text_color.rs
  • crates/perry/src/commands/compile/cjs_wrap/hoist_classes.rs
  • crates/perry/src/commands/compile/cjs_wrap/tests/hoist_scanner.rs
  • crates/perry/src/commands/compile/collect_modules.rs
  • crates/perry/src/commands/compile/collect_modules/static_require_transform.rs
  • crates/perry/src/commands/compile/run_pipeline.rs
  • crates/perry/tests/source_graph_export_regressions.rs
  • crates/perry/tests/source_graph_export_regressions/issue_10417.rs
  • crates/perry/tests/source_graph_export_regressions/issue_10432.rs
  • crates/perry/tests/source_graph_export_regressions/issue_10758.rs
  • scripts/check_file_size.sh
 ______________________________
< torvalds@linux:~$ git review >
 ------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

proggeramlug pushed a commit that referenced this pull request Sep 22, 2026
The three gap-suite reds on this PR — `test_gap_http2_settings`,
`test_gap_3527_http_ctor_prototype`, `test_gap_gc_net_once_flags_rekey` — are
not compile failures. They are `PERRY_COMPILE_TIMEOUT` expiring. In the CI log
each one is exactly 300.1 s wide:

    02:37:46.96 -> 02:42:47.08   test_gap_3527_http_ctor_prototype   300.12 s
    02:45:24.62 -> 02:50:24.77   test_gap_gc_net_once_flags_rekey    300.15 s
    02:47:57    (shard 2)        test_gap_http2_settings             300.1  s

All three compile and pass by hand on this branch (perrymaster, cold
`target/perry-auto-*`): 3m43s, and byte-parity against the node 26.5.1 oracle.

WHY THE BUDGET IS TOO SMALL

#10757 sized one 300 s budget for every fixture, on the stated belief that
"the fast-mode/PERRY_SKIP_BUILD tiers don't pay [an auto-optimize rebuild] per
test". They do, and the reason is four hundred lines further down the same
file: the #7629 block unsets PERRY_NO_AUTO_OPTIMIZE for every fixture that
routes a module to a `perry-ext-*` wrapper, because no single prebuilt stdlib
can serve the mixed corpus. perry then runs `cargo build` for a
feature-stripped runtime + stdlib + wrapper INSIDE the per-test compile
budget, once per distinct feature set, into a fresh `target/perry-auto-<hash>`.
The gap-suite workflow comment already records that cost as ~200 s per
distinct feature set; with runner variance it measures 270-300 s. So the
rebuild sits ON the line:

    #10930  test_gap_gc_net_once_flags_rekey   287.4 s   PASS  (12.6 s margin)
    #10930  test_gap_http2_settings            300.13 s  COMPILE_FAIL
    #10930  test_gap_3527_http_ctor_prototype  300.13 s  COMPILE_FAIL

That is merge train 254 — v0.5.1634, now on main. The same red, on a rotating
cast, is in every recent run: 11 fixtures on #10918, 5 on #10892, 4 on #10930.
All three merged. A gate whose red is overridden by hand every time is not a
gate, and this one cannot even tell a killed compile from a rejected one.

THE FIX

Split the budget by the property that predicts the cost — this compile may
rebuild the toolchain — and not by test name. `PERRY_EXT_COMPILE_TIMEOUT`
(default 900 s, 3x the observed cost) applies when auto-optimize is on for
that compile AND the fixture routes to an ext wrapper, reusing the existing
`test_routes_to_ext_wrapper` predicate. The ordinary 300 s budget is
untouched, so a genuine hang in a plain compile is still bounded at 300 s, and
the shard's 110-minute cap has room (shards run 17-46 min).

A killed compile now says so — `compile TIMEOUT after <N>s — killed, not
rejected` — in the console line and at the head of the persisted
`*.compile_error.log`. The old `(compile error)` with no message is what made
this take a night to find: the fixture compiled fine by hand, and the cause
was only visible by subtracting two timestamps out of a CI log.

WITNESS

Four arms on perrymaster, `test_gap_http2_settings`, PERRY_SKIP_BUILD=1 (the
CI path), `target/perry-auto-*` and the perry object cache wiped before each
cold arm:

  A  unpatched, cold, PERRY_COMPILE_TIMEOUT=120
     -> FAIL (compile error)                  killed at 2:03
  B  patched,   cold, PERRY_COMPILE_TIMEOUT=120
     -> PASS                                  4:02
  C  patched,   cold, PERRY_COMPILE_TIMEOUT=900 PERRY_EXT_COMPILE_TIMEOUT=60
     -> FAIL (compile TIMEOUT after 60s — killed, not rejected)
  D  patched,   test_gap_symbols (not ext-routed), PERRY_COMPILE_TIMEOUT=1
     -> FAIL (compile TIMEOUT after 1s — killed, not rejected)

A vs B is the same fixture, same cold state, same ordinary budget: the patch
is the only difference. C shows the ext budget is the one governing an
ext-routed fixture. D shows the ordinary budget still bites, so this is not a
blanket raise.

The three fixtures then pass through the harness on this branch:
test_gap_http2_settings, test_gap_3527_http_ctor_prototype and
test_gap_gc_net_once_flags_rekey — 1/1 parity pass each, 0 compile fail.
proggeramlug pushed a commit that referenced this pull request Sep 22, 2026
The previous commit gave a compile that may rebuild the toolchain its own
budget, scoped to fixtures that route a module to a `perry-ext-*` wrapper.
CI then showed there is a second way in — and showed it in one line, which is
the whole point of the label that commit added:

    FAIL  test_gap_6558_webassembly_graceful_fail
          (compile TIMEOUT after 300s — killed, not rejected)

No ext-routed import, auto-optimize off, so it kept the ordinary 300 s budget.
It still builds native artifacts inside the compile:

      wasm-host: building perry-wasm-host from workspace source
      wasm-host (no-auto): rebuilding runtime with wasm-host feature

Cold, that compile measures 395 s here — over the line by a third, and under
the old `(compile error)` wording it would have read as a broken fixture.
It is in #10918's list of the same red for the same reason.

So the predicate gets the second property, symmetric with the first and still
a property of the test rather than its name. Across the four runs sampled
(#10859, #10918, #10892, #10930) the two together cover the entire observed
population: 13 of 14 distinct fixtures route to an ext wrapper, and the 14th
is this one. `PERRY_EXT_COMPILE_TIMEOUT` is renamed
`PERRY_TOOLCHAIN_COMPILE_TIMEOUT` — it was never only about ext wrappers, and
it has not shipped under the old name.

WITNESS — three more arms, same harness, on `test_gap_6558_webassembly_graceful_fail`
unless stated:

  E  PERRY_COMPILE_TIMEOUT=1  PERRY_TOOLCHAIN_COMPILE_TIMEOUT=900
     -> PASS                         the ordinary budget is not in force
  F  PERRY_COMPILE_TIMEOUT=900 PERRY_TOOLCHAIN_COMPILE_TIMEOUT=1
     -> FAIL (compile TIMEOUT after 1s — killed, not rejected)
                                     the toolchain budget is
  G  test_gap_symbols (neither ext-routed nor wasm), PERRY_COMPILE_TIMEOUT=1
     -> FAIL (compile TIMEOUT after 1s)
                                     the ordinary budget still bites

E and F are the same fixture and the same harness with the two budgets
swapped, so they isolate which one governs; G is the control that this is not
a blanket raise.

Run 35692315543 on the previous commit: gap shards 1, 2, 3, 4 and 5 green —
including 2 and 3, which carried all three of this PR's original reds — and 6
red on this one fixture alone.
proggeramlug pushed a commit that referenced this pull request Sep 22, 2026
The three gap-suite reds on this PR — `test_gap_http2_settings`,
`test_gap_3527_http_ctor_prototype`, `test_gap_gc_net_once_flags_rekey` — are
not compile failures. They are `PERRY_COMPILE_TIMEOUT` expiring. In the CI log
each one is exactly 300.1 s wide:

    02:37:46.96 -> 02:42:47.08   test_gap_3527_http_ctor_prototype   300.12 s
    02:45:24.62 -> 02:50:24.77   test_gap_gc_net_once_flags_rekey    300.15 s
    02:47:57    (shard 2)        test_gap_http2_settings             300.1  s

All three compile and pass by hand on this branch (perrymaster, cold
`target/perry-auto-*`): 3m43s, and byte-parity against the node 26.5.1 oracle.

WHY THE BUDGET IS TOO SMALL

#10757 sized one 300 s budget for every fixture, on the stated belief that
"the fast-mode/PERRY_SKIP_BUILD tiers don't pay [an auto-optimize rebuild] per
test". They do, and the reason is four hundred lines further down the same
file: the #7629 block unsets PERRY_NO_AUTO_OPTIMIZE for every fixture that
routes a module to a `perry-ext-*` wrapper, because no single prebuilt stdlib
can serve the mixed corpus. perry then runs `cargo build` for a
feature-stripped runtime + stdlib + wrapper INSIDE the per-test compile
budget, once per distinct feature set, into a fresh `target/perry-auto-<hash>`.
The gap-suite workflow comment already records that cost as ~200 s per
distinct feature set; with runner variance it measures 270-300 s. So the
rebuild sits ON the line:

    #10930  test_gap_gc_net_once_flags_rekey   287.4 s   PASS  (12.6 s margin)
    #10930  test_gap_http2_settings            300.13 s  COMPILE_FAIL
    #10930  test_gap_3527_http_ctor_prototype  300.13 s  COMPILE_FAIL

That is merge train 254 — v0.5.1634, now on main. The same red, on a rotating
cast, is in every recent run: 11 fixtures on #10918, 5 on #10892, 4 on #10930.
All three merged. A gate whose red is overridden by hand every time is not a
gate, and this one cannot even tell a killed compile from a rejected one.

THE FIX

Split the budget by the property that predicts the cost — this compile may
rebuild the toolchain — and not by test name. `PERRY_EXT_COMPILE_TIMEOUT`
(default 900 s, 3x the observed cost) applies when auto-optimize is on for
that compile AND the fixture routes to an ext wrapper, reusing the existing
`test_routes_to_ext_wrapper` predicate. The ordinary 300 s budget is
untouched, so a genuine hang in a plain compile is still bounded at 300 s, and
the shard's 110-minute cap has room (shards run 17-46 min).

A killed compile now says so — `compile TIMEOUT after <N>s — killed, not
rejected` — in the console line and at the head of the persisted
`*.compile_error.log`. The old `(compile error)` with no message is what made
this take a night to find: the fixture compiled fine by hand, and the cause
was only visible by subtracting two timestamps out of a CI log.

WITNESS

Four arms on perrymaster, `test_gap_http2_settings`, PERRY_SKIP_BUILD=1 (the
CI path), `target/perry-auto-*` and the perry object cache wiped before each
cold arm:

  A  unpatched, cold, PERRY_COMPILE_TIMEOUT=120
     -> FAIL (compile error)                  killed at 2:03
  B  patched,   cold, PERRY_COMPILE_TIMEOUT=120
     -> PASS                                  4:02
  C  patched,   cold, PERRY_COMPILE_TIMEOUT=900 PERRY_EXT_COMPILE_TIMEOUT=60
     -> FAIL (compile TIMEOUT after 60s — killed, not rejected)
  D  patched,   test_gap_symbols (not ext-routed), PERRY_COMPILE_TIMEOUT=1
     -> FAIL (compile TIMEOUT after 1s — killed, not rejected)

A vs B is the same fixture, same cold state, same ordinary budget: the patch
is the only difference. C shows the ext budget is the one governing an
ext-routed fixture. D shows the ordinary budget still bites, so this is not a
blanket raise.

The three fixtures then pass through the harness on this branch:
test_gap_http2_settings, test_gap_3527_http_ctor_prototype and
test_gap_gc_net_once_flags_rekey — 1/1 parity pass each, 0 compile fail.
proggeramlug pushed a commit that referenced this pull request Sep 22, 2026
The previous commit gave a compile that may rebuild the toolchain its own
budget, scoped to fixtures that route a module to a `perry-ext-*` wrapper.
CI then showed there is a second way in — and showed it in one line, which is
the whole point of the label that commit added:

    FAIL  test_gap_6558_webassembly_graceful_fail
          (compile TIMEOUT after 300s — killed, not rejected)

No ext-routed import, auto-optimize off, so it kept the ordinary 300 s budget.
It still builds native artifacts inside the compile:

      wasm-host: building perry-wasm-host from workspace source
      wasm-host (no-auto): rebuilding runtime with wasm-host feature

Cold, that compile measures 395 s here — over the line by a third, and under
the old `(compile error)` wording it would have read as a broken fixture.
It is in #10918's list of the same red for the same reason.

So the predicate gets the second property, symmetric with the first and still
a property of the test rather than its name. Across the four runs sampled
(#10859, #10918, #10892, #10930) the two together cover the entire observed
population: 13 of 14 distinct fixtures route to an ext wrapper, and the 14th
is this one. `PERRY_EXT_COMPILE_TIMEOUT` is renamed
`PERRY_TOOLCHAIN_COMPILE_TIMEOUT` — it was never only about ext wrappers, and
it has not shipped under the old name.

WITNESS — three more arms, same harness, on `test_gap_6558_webassembly_graceful_fail`
unless stated:

  E  PERRY_COMPILE_TIMEOUT=1  PERRY_TOOLCHAIN_COMPILE_TIMEOUT=900
     -> PASS                         the ordinary budget is not in force
  F  PERRY_COMPILE_TIMEOUT=900 PERRY_TOOLCHAIN_COMPILE_TIMEOUT=1
     -> FAIL (compile TIMEOUT after 1s — killed, not rejected)
                                     the toolchain budget is
  G  test_gap_symbols (neither ext-routed nor wasm), PERRY_COMPILE_TIMEOUT=1
     -> FAIL (compile TIMEOUT after 1s)
                                     the ordinary budget still bites

E and F are the same fixture and the same harness with the two budgets
swapped, so they isolate which one governs; G is the control that this is not
a blanket raise.

Run 35692315543 on the previous commit: gap shards 1, 2, 3, 4 and 5 green —
including 2 and 3, which carried all three of this PR's original reds — and 6
red on this one fixture alone.
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