chore: merge train 233 (v0.5.1612) - #10783
Merged
Merged
Conversation
added 8 commits
September 20, 2026 06:11
`remedy_is_scoped_to_bundled_npm_shims` asserted
`shimmed_package_module("dayjs.businessDaysAdd") == Some("dayjs")`, but
v0.5.1610 removed the `dayjs` native binding (with `qs`, `fastify`,
`date-fns`, `rate-limiter-flexible` and `node-cron`), so the classifier
correctly answers `None`. The production code is right; the test had
outlived its subject and was reddening `main`.
Swapping in another package name would re-arm the same trap for the next
removal (`lru-cache`, `commander`, `pg`, `mysql2`, `decimal.js` are
queued), so the positive cases now derive from `NATIVE_MODULES`: a helper
filters it to the entries that are neither Node builtins nor Perry-owned
surfaces and the test asserts every one resolves and names itself in the
remedy. The sibling end-to-end test carried the same trap on `lodash` and
is derived the same way.
The negative half stays literal — those are categories, not packages, and
each pins a distinct branch of `shimmed_package_module`. Verified the test
still fails in both directions by stubbing the function to return `None`
unconditionally and to return `Some` unconditionally.
Fixes #10685 -- the removal is the fix. Native `instanceof` threw "Right-hand side of 'instanceof' is not callable" and constructor.name was undefined (the handle isn't a real class object); core get/set/eviction logic was otherwise correct, but forEach/dispose silently no-op'd where npm's real implementation visits/invokes. Removes both copies (crates/perry-ext-lru-cache/ and the feature-gated crates/perry-stdlib/src/lru_cache.rs), the dedicated #10293 native-subclass machinery (crates/perry-runtime/src/lru_subclass.rs plus its call sites in perry-codegen), the LRUCache-only arms in every shared HIR/codegen recognition point (LRUCache/Command/Big/Decimal/BigNumber share several match blocks; only LRUCache's line is touched here), and every registry row (well_known_bindings.toml, NATIVE_MODULES, the API manifest, stdlib_features.rs, native_result_ledger, workspace-architecture.json, ci_ext_link_scope.py, Android stubs). Based on PR #10699's branch (fix/10439-native-binding-import-provenance): without that fix, lru-cache at its default import name is unreachable regardless of perry.compilePackages, so this removal is not independently mergeable.
Fixes #10686 -- the removal is the fix. Native program.args was undefined; boolean option defaults serialized as the truthy string "false"; subcommand .action() callbacks never fired; missing-required-argument and unknown-option validation (Node's commander.missingArgument / commander.unknownOption) was entirely absent. Removes both copies (crates/perry-ext-commander/ and the feature-gated crates/perry-stdlib/src/commander.rs, including its registered GC-root scanner), the Command-only arms in every shared HIR/codegen recognition point (LRUCache/Command/Big/Decimal/BigNumber share several match blocks; only Command's line is touched here, including the dedicated is_commander/is_commander_method fluent-chain continuation in static_and_instance.rs), and every registry row (well_known_bindings.toml, NATIVE_MODULES, the API manifest, stdlib_features.rs, native_result_ledger, gc_runtime_root_holders.json, workspace-architecture.json, Android stubs). commander's real npm source subclasses node:events' EventEmitter directly (class Command extends EventEmitter) -- Perry's existing generic EventEmitter-subclass support already handles that once compiled from source, so no dedicated native-subclass machinery was needed here (unlike bundled-commander is referenced only by perry-stdlib's `full` feature umbrella (checked every other umbrella in Cargo.toml); no other umbrella needs retargeting by this or the sibling decimal.js/lru-cache removals. Based on PR #10699's branch (fix/10439-native-binding-import-provenance): without that fix, commander at its default import name is unreachable regardless of perry.compilePackages, so this removal is not independently mergeable.
…) binding removals
Both removals record absolute baselines that main has moved past and that collide with each other (#10739), so none of them may be hand-merged. Each number below was produced by re-running the script that owns the file on THIS tree, not by arithmetic from either PR's recorded figure: workspace-architecture.json members 72 -> 70, externalize 23 -> 21 (python3 scripts/workspace_architecture.py --check --print-summary) scripts/native_result_ledger.py rows 369 -> 356, providers 320 -> 307 (python3 scripts/native_result_ledger.py; 369 -> 367 -> 356 across the two removals) unrooted_local_shape_baseline total 562 -> 555 (python3 scripts/unrooted_local_shape.py --update-baseline) docs/src/api/reference.md 2923/126 -> 2903/124 docs/api/perry.d.ts 2043/124 -> 2041/122 (scripts/regen_api_docs.sh) Cargo.lock regenerated with `cargo metadata --offline` (drops lru, perry-ext-commander, perry-ext-lru-cache and nothing else) Also in this commit: - crates/perry-hir/src/lower_decl/class_decl/from_ast.rs: drop the #10293 `"LRUCache" => ("lru-cache", "LRUCache")` native-parent arm. #10708 removed only the copy in class_decl.rs; from_ast.rs holds the parallel arm its own comment says to keep in lockstep, and codegen's `lower_lru_cache_subclass_init` is gone, so a `class X extends LRUCache` from the real compiled source would have been routed to a path that no longer exists. - crates/perry/well_known_bindings.toml: drop the `date` line orphaned by the commander entry's removal (it made the file fail to parse as TOML). - crates/perry/src/commands/compile/host_config.rs: the #5137 wildcard-skip comment named commander/dayjs/lru-cache and `js_commander_new`, all of which are now deleted; re-point it at ioredis/`js_ioredis_new`. - changelog.d fragments: record each package's acceptance result against the real npm package and the pinned Node oracle.
This was referenced Sep 20, 2026
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (61)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
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.
Merge train 233 — two agent-produced branches plus one repair, released as v0.5.1612.
Contents
refactor(stdlib): remove thelru-cacheandcommandernative bindings — 59 files, +99/−4405test(hir): derive the shimmed-npm-shim test cases from the live registry instead of naming packagesfix(release): drop twoperry-stdlibfeatures train 231 deleted from the next-app providerBoth PRs were CONFLICTING and are combined rather than rebased separately: they move the same absolute counts, so two independently-correct rebases would collide with each other. That collision is #10739.
Two main-side reds, both of them mine, both fixed here
perry-hir'sremedy_is_scoped_to_bundled_npm_shimswas stale. It assertedshimmed_package_module("dayjs.businessDaysAdd") == Some("dayjs"); train 231 removed the dayjs binding, so the lookup correctly returnedNone. Production code right, test wrong — and per-PRcargo-testscopes to the crates a diff affects, so the nextperry-hirPR would have gone red for a reason it did not cause.The fix derives the positive cases from the live registry (
NATIVE_MODULESminus Node builtins minus Perry-owned surfaces) — 47 entries today, where two package names were hardcoded. A binding removal now shrinks that set instead of reddening the test. The negative half stays literal on purpose: those are categories (fs.bogus, anode:spelling,perry/gc.notReal,crypto.subtle.digest, an unshimmed package), no removal can delete them, and they are what fails if the derivation ever drifts loose. Both halves were sabotage-checked — forcingshimmed_package_moduleto always-Noneand to always-Someeach fail the test, the second in its strong form (returning the correct module prefix, so only the literal negatives can catch it).The release provider enabled two features that no longer exist. Train 231 deleted
rate-limitandbundled-dayjsfromcrates/perry-stdlib/Cargo.toml;tests/release/packages/next-app-route/provider/stdlib/Cargo.tomlstill asked for both, so the provider no longer resolved. It is not a workspace member, socargo check --workspace --all-targetsis structurally blind to it and only the full tier's nightly release-package smoke sees it. The cheap standing check iscomm -23between the provider's feature list and perry-stdlib's defined features — worth running on every future removal.The removals: why
commanderstays in despite losing four stderr linesAfter removal, real
commander15.0.0 matches Node byte-for-byte on stdout — option defaults,--no-negation,.opts(),program.args,processedArgs, subcommand.argument()/.action()dispatch, variadics,helpInformation(),--helpthroughconfigureOutput, and all fourCommanderErrorcodes underexitOverride(). But it prints nothing where Node printserror: unknown option '--nope'and three siblings. That is #10711.It is not a regression, and the evidence is on
main, not in a claim.crates/perry-ext-commander/src/lib.rsandcrates/perry-stdlib/src/commander.rsatdd00a00305contain zero matches foreprintln!|stderr|io::stderr— the native binding never wrote that text either. They also contain zero matches forexit_override|configure_output|help_information|processed_args, so the acceptance fixture could not even have run onmain. stderr was empty before and is empty after; every value commander computes now matches Node where previously noCommanderErrorwas thrown at all.Correction to #10711's impact text while we are here: it says
--helprouted through the configuration object also loses its text. It does not —configureOutput({ writeOut })+--helpis byte-identical. Only theoutputError(msg, writeErr)shape is affected, so the blast radius is narrower than the issue states.lru-cache11.5.2 is byte-identical outright, including the four things the native binding got wrong:instanceof,constructor.name,forEach, anddisposefiring on eviction.A conflict resolution that compiled and was wrong
#10708 removed the
"LRUCache" => ("lru-cache","LRUCache")native-parent arm fromclass_decl.rsbut missed the parallel copy infrom_ast.rs, whose own comment says to keep the two in lockstep. Withlower_lru_cache_subclass_initdeleted from codegen,class X extends LRUCachein real compiled source would have routed to a path that no longer exists. There is a_ => Nonecatch-all, so it compiles either way and no gate would have caught it. Removed here.Two more of the same species: taking the removal PR's side on
crates/perry-stdlib/Cargo.toml'sfull = [...]would have resurrectedrate-limit,bundled-dotenvandbundled-dayjs, all deleted by train 231; and dropping the marked region ofwell_known_bindings.tomlorphaned a trailingdate = ..., producing a duplicate key that no compile can see because the file is read at runtime.Counts re-derived on this tree, not carried
workspace_architecture.py --check --print-summarypolicy: OKnative_result_ledger.pyunrooted_local_shape.py --checkOKstring_payload_access_inventory.pybinding_governance.py --checkOKbinding_pins.mjs --checkCargo.lockregenerated withcargo metadata --offline: exactly 32 lines, exactlylru,perry-ext-commander,perry-ext-lru-cache, nothing else.Validation
Assembled on
dd00a00305; both source branches asserted fresh; no attribution trailers. Nine cheap gates,cargo check --workspace --all-targetsunder-D warnings, all five pinned artifacts byte-identical before and after the sweep, and seven unit suites with an empty failing set — the first train where that gate has a baseline of zero.lintcompleted its full 6-of-6 compile tier with nothing outside the known-red public-baseline step.Gap sweep at
PERRY_RUN_TIMEOUT=30, seven areas aimed at what a binding removal can break — heritage, module resolution, and theclass X extendspath thefrom_ast.rsfix touches — every area asserted live, zero unexplained regressions:Two integration suites report
rc=101. Both are cargo refusing a target this train deletes (package ID specification 'perry-ext-lru-cache' did not match any packages, and the deletedissue_10293_lru_cache_subclass.rs), not test failures — the surviving edited suite,issue_10439_native_binding_import_provenance, passes. The landing gate now requires proof of both halves before accepting such a code: the log must show cargo could not find the target andgit diff --name-statusmust show this train deletes it.