refactor(stdlib): remove decimal.js/big.js/bignumber.js native binding - #10704
proggeramlug wants to merge 3 commits into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks 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 |
…wering native_fluent_chain_still_dispatches_through_native_methods asserted the pre-fix, spelling-based, no-import native dispatch that this PR's own detect_native_instance_expr change deliberately eliminates. With no import at all, `new Decimal(1)` (or Command/LRUCache/Big/BigNumber) now correctly falls through to an unresolved-global reference -- matching Node's ReferenceError on a genuinely undefined global -- instead of silently reaching the native handle by name. The test predates this change and was never updated for it, so it went red on this same commit without this PR's diff touching that file: only the sweep's `cargo test --workspace` would have caught it, hours later and attributed to a time window rather than this PR. Removed with the rationale recorded inline, matching the identical resolution three PRs stacked on this branch (#10704, #10708, #10712) each carried independently -- landing it here so none of them has to repeat it. crates/perry-hir/tests/fluent_chain_lowering.rs now runs 2/2; the crate's full test suite (`cargo test -p perry-hir --tests`) is green.
…wering native_fluent_chain_still_dispatches_through_native_methods asserted the pre-fix, spelling-based, no-import native dispatch that this PR's own detect_native_instance_expr change deliberately eliminates. With no import at all, `new Decimal(1)` (or Command/LRUCache/Big/BigNumber) now correctly falls through to an unresolved-global reference -- matching Node's ReferenceError on a genuinely undefined global -- instead of silently reaching the native handle by name. The test predates this change and was never updated for it, so it went red on this same commit without this PR's diff touching that file: only the sweep's `cargo test --workspace` would have caught it, hours later and attributed to a time window rather than this PR. Removed with the rationale recorded inline, matching the identical resolution three PRs stacked on this branch (#10704, #10708, #10712) each carried independently -- landing it here so none of them has to repeat it. crates/perry-hir/tests/fluent_chain_lowering.rs now runs 2/2; the crate's full test suite (`cargo test -p perry-hir --tests`) is green.
|
Flagging a counting problem this PR shares with its two siblings, because it will fail a required gate rather than show up in review. All three of #10704, #10708 and #10712 record the identical transition It is already moot in any case: the chain has moved on. Main is now at 79 members / externalize 30 / keep 44 after the validator and dotenv removals, with uuid in flight. These are absolute recorded baselines, not deltas. So at rebase time, for each of the three: recompute from the resolved tree and have Two related notes:
Finally, for whoever runs the acceptance check: #10735 is live on main — |
|
Correction to my comment above: I gave main's baseline as 79 members / externalize 30 / keep 44. That is wrong — 79/30 is the figure after the uuid removal, not main's. Main ( The attribution was wrong too: I said "after validator and dotenv". Only #10690 (validator) has landed; #10691 (dotenv) is still open, and a jsonwebtoken removal landed instead. This does not change the advice, and the advice is the point: recompute from the resolved tree at rebase time and have |
2fb7d73 to
700cb8e
Compare
|
Base pointer retargeted to The content rebase onto Recomputed triple is 77/28/44 against main's 78/29/44, reproduced independently by Left as draft deliberately: it went first as a pathfinder for #10708 and #10712, which are structurally identical and both still carry the stale base pointer. The full recipe is now on each of them. |
Fixes #10684 -- the removal is the fix. Native division returned "1" for both 1/3 and 10/4, and new Decimal("123456789123456789").times("987654321987654321") aborted the process (Multiplication overflowed in rust_decimal -- a fixed 96-bit type backing an arbitrary-precision library). instanceof and constructor.name were also broken, the same way as lru-cache's. Removes both copies (crates/perry-ext-decimal/ and the feature-gated crates/perry-stdlib/src/decimal.rs), the dedicated HIR/codegen recognition for Big/Decimal/BigNumber (they share one binding/crate with decimal.js), and every registry row (well_known_bindings.toml, NATIVE_MODULES, the API manifest, stdlib_features.rs, native_result_ledger, workspace-architecture.json, Android stubs). big.js/bignumber.js go with it -- same crate, same defects. Based on PR #10699's branch (fix/10439-native-binding-import-provenance): without that fix, decimal.js/big.js/bignumber.js at their default import name are unreachable regardless of perry.compilePackages, so this removal is not independently mergeable. # Conflicts: # Cargo.lock # Cargo.toml # crates/perry-api-manifest/src/entries.rs # crates/perry-api-manifest/src/entries/part_4.rs # crates/perry-codegen/src/lower_call/builtin.rs # crates/perry-codegen/src/runtime_decls/stdlib_ffi.rs # crates/perry-hir/src/destructuring/var_decl/native_fetch.rs # crates/perry-hir/src/destructuring/var_decl/native_new.rs # crates/perry-hir/src/js_transform/imports.rs # crates/perry-hir/src/lower/expr_call/static_and_instance.rs # crates/perry-hir/src/lower/module_decl.rs # crates/perry-hir/src/lower_patterns.rs # crates/perry-stdlib/Cargo.toml # crates/perry-stdlib/src/lib.rs # crates/perry-ui-android/src/stdlib_stubs.rs # crates/perry/src/commands/compile/collect_modules/feature_detect.rs # crates/perry/src/commands/stdlib_features.rs # crates/perry/well_known_bindings.toml # docs/api/perry.d.ts # docs/examples/stdlib/other/snippets.ts # docs/src/api/reference.md # docs/src/native-libraries/governance.md # docs/src/stdlib/other.md # docs/src/stdlib/overview.md # scripts/native_result_ledger.py # scripts/unrooted_local_shape_baseline.json # workspace-architecture.json
…nding removal)
… orphaned decimal.js parity fixture Removes the stray perry-ext-decimal crate entry that survived the rebase's auto-merge in workspace-architecture.json, resyncs Cargo.lock, and recomputes native_result_ledger EXPECTED_ROWS/PROVIDERS (344 rows, 295 providers), the unrooted-local-shape baseline, the generated binding-governance table, and docs/api/perry.d.ts + docs/src/api/reference.md from a fresh perry-dev build. crates/perry-hir/src/lower_patterns.rs: detect_native_instance_expr's new-expression arm went dead. Its match on class_name used to have five live arms (Big/Decimal/BigNumber from this PR, LRUCache/Command from the already- landed #10708/#10712) -- with all five gone the fallback-only match triggered rustc's unreachable_code lint under -D warnings. Simplified the arm to what it now always evaluates to (None after the local-class shadow check), and rewrote the function doc comment to explain why the stub is kept rather than deleted. This is a sequencing interaction the brief calls out explicitly: this file wasn't touched by mysql2/pg/cron's diffs, but decimal.js landing after commander/lru-cache emptied a match neither PR could see on its own. test-files/test_parity_decimal.ts + its test-parity/known_failures.json entry: the original PR left this fixture behind (unlike #10795, which deleted its own moment/cron/backoff test files as part of the same removal). The fixture is now double-dead: decimal.js has no Perry-specific behavior left to validate, and the file was already skip-listed as a broken oracle (node itself can't resolve decimal.js post-npm-ci, #8271) before this PR.
700cb8e to
286a3b4
Compare
Summary
Fixes #10684 — the removal is the fix.
Removes the native
decimal.jsbinding (andbig.js/bignumber.js, which share the exact samecrate, runtime symbols, and defects) so
import Decimal from "decimal.js"(noperry.compilePackagesentry) resolves to the real npm package, compiled from source, per theowner's decision to stop shipping hand-written Rust reimplementations of npm packages.
This PR is based on
fix/10439-native-binding-import-provenance(#10699), notmain. Without#10699's fix,
new Decimal(...)chained directly onto a method call is intercepted by class-namespelling regardless of
perry.compilePackages, so decimal.js's real source is unreachable at itsdocumented import name. This PR is not independently mergeable — it must land after #10699.
The defects this closes (#10684)
new Decimal(1).dividedBy(3)returned"1"(real:"0.3333…").new Decimal(10).dividedBy(4)returned"1"(real:"2.5").new Decimal("123456789123456789").times("987654321987654321")panics with
Multiplication overflowedinrust_decimal— SIGABRT. Root cause is structural: thebinding backs an arbitrary-precision JS library with
rust_decimal's fixed 96-bit decimaltype, so sufficiently large operands necessarily overflow.
instanceof/constructor.namebroken — the handle isn't a real class object (same class ofbug as lru-cache's).
Scope note: big.js / bignumber.js go with it
decimal.js,big.js, andbignumber.jsall route through the sameperry-ext-decimalcrate,the same
js_decimal_*runtime symbols, and the same HIR recognition (detect_native_instance_exprand its siblings treat
Big/Decimal/BigNumberas one group). They can't be split — removingdecimal.js's binding necessarily removes big.js/bignumber.js's too. Same backing type, same
structural overflow defect.
LRUCache/Commandrecognition in the same shared functions isuntouched; those are #10685/#10686.
What was found and removed (both copies, per #10678)
crates/perry-ext-decimal/(crate deleted; governance-tracked,well_known_bindings.toml's[bindings."decimal.js"]+[bindings."bignumber.js"])crates/perry-stdlib/src/decimal.rs(506 lines, feature-gatedbundled-decimal, exporting theexact same
js_decimal_*symbols) + the feature itself and itsrust_decimaldependencyBig/Decimal/BigNumber(leavingLRUCache/Commandalone) acrosslower_patterns.rs(detect_native_instance_expr),native_new.rs,native_fetch.rs,module_decl.rs,static_and_instance.rs(the math-lib fluent-chain continuation), andjs_transform/imports.rs'sNATIVE_CODEGEN_CLASSES"Decimal"construction arm + collision guard incrates/perry-codegen/src/lower_call/builtin.rsdecimal.jsNativeModSigrows innative_table/async_decimal.rs— that file also heldunrelated
async_hooks.AsyncLocalStoragerows (a prior file-size split bundled two unrelatedfamilies under one name); trimmed to just those and renamed to
async_hooks.rs(
ASYNC_DECIMAL_ROWS→ASYNC_HOOKS_ROWS)decimal.jsmanifest rows (perry-api-manifest'spart_1.rs, thebignumber.jsalias classin
part_4.rs, bothNATIVE_MODULESentries inentries.rs)feature_detect.rs's native-module scan list,stdlib_features.rs's feature-flip mappingjs_decimal_*) inperry-ui-android/src/stdlib_stubs.rsperry-ext-decimalworkspace member + path dependency in the rootCargo.tomlworkspace-architecture.json's entry (workspace_members83→82,externalize33→32)scripts/unrooted_local_shape_baseline.jsonscripts/native_result_ledger.{tsv,py}— 12js_decimal_*NR_HANDLE_IDprovider rows(arithmetic ops that return a new handle),
EXPECTED_ROWS/EXPECTED_PROVIDERS371/322 → 359/310.This gate reads
crates/perry-codegen/src/lower_call/native_table/*.rs+ the TSV directly andfails hard if either side drifts — confirmed green after the edit.
docs/src/stdlib/overview.md,docs/src/stdlib/other.md(+ itsdocs/examples/stdlib/other/snippets.tsanchor),docs/src/native-libraries/governance.md,docs/src/api/reference.md,docs/api/perry.d.tsLeft alone, deliberately:
docs/audits/rust-dependency-decisions-2026-09-14.{md,json}(dated,frozen audit snapshots, same convention as leaving
CHANGELOG.mdalone) andtest-files/test_parity_decimal.ts, which imports the real package with nonode_modulesof itsown — it was already quarantined pre-existing and unrelated to this PR:
test-parity/known_failures.jsontracks it under #8271 since 2026-08-17 ("Node 26.5.1 exits
ERR_MODULE_NOT_FOUNDfor 'decimal.js'… absent from package.json/package-lock.json"), it's in
test-parity/parity_matrix_baseline.json'sallowed_statuses: [parity_fail], and it's already intest.yml'sSKIP_TESTS. Left as the #8271audit trail's problem, not this removal's.
A pre-existing red test found on the base branch, not caused by this PR:
perry-hir'sfluent_chain_lowering.rshadnative_fluent_chain_still_dispatches_through_native_methods(
new Decimal(1).plus(2).times(3).toString(), no import), asserting the exact ambient/no-import,spelling-based dispatch #10699 itself eliminated. Bisected — it's already red on #10699's own tip
(
08325f1e6), passing only on #10699's parent commit. Confirmed the same failure mode holds forevery one of the 5 names (tested
Command), so there's no still-present sibling to repoint it at.Deleted with an explanatory comment; flagged on #10699 directly
(#10699 (comment)) since it's that PR's own
regression, not this removal's.
Acceptance test: real arithmetic + instanceof + the two named defects, no
compilePackagesentryBuilt on perrymaster (
--profile perry-dev,-p perry -p perry-runtime-static -p perry-stdlib-static),confirmed
.amtimes moved. Test project:{ "dependencies": { "decimal.js": "^10.6.0" }, "type": "module" }No
perry.compilePackagesentry at all. Compile log:Compile package wildcard: expanded to 1 installed package(s)— real AOT compile from source, exactly as #10699 unblocks.Diffed the compiled binary's output against
node --experimental-strip-types(Node 26.5.1, thepinned oracle):
One residual mismatch, found by this acceptance test and not caused by this PR:
d.constructor.nameis""in Perry vs."Decimal"in Node. Traced it to the real decimal.jssource (
clone()-built ES5 function constructor,module.exports = Decimal, noclassat all) —isolated repros show a same-file factory-built function constructor's
.nameis fine, and the exactprototype-replacement shape is fine, but the same shape imported cross-module via CJS interop loses
the function's own
.namebefore.constructoreven enters into it. Not fixed by, and not causedby, this removal — everything else checked matches Node exactly. Filed as #10702.
Verification
cargo check --workspace --all-targets(excluding the cross-host UI crates per this repo's ownexclusion list) under
RUSTFLAGS="-D warnings": clean.cargo test -p perry-hir --tests: 459+ lib tests + all integration binaries, 0 failures (afterremoving the pre-existing-red test above).
cargo test -p perry-codegen --tests: 1632 lib tests + all integration binaries incl.manifest_consistency, 0 failures.cargo test -p perry-api-manifest --tests: 39+4+other binaries, 0 failures.cargo test -p perry --test issue_10439_native_binding_import_provenance: all 5 pass, includingdecimal_default_name_reaches_real_source_under_compile_packages.python3 scripts/native_result_ledger.py: passes at the new 359/310 counts.python3 scripts/binding_governance.py --check: OK (39 extension crates, was 40).node scripts/binding_pins.mjs --check: OK (36 pinned, was 37).python3 scripts/workspace_architecture.py --check: OK.cargo fmt --all -- --check: clean.SKIP_COMPILE_GATES=1 ./scripts/run_lint_gates.sh: 77 of 79 passed (compile tier skipped). Theone non-pre-existing failure (
cargo fmt) was fixed in this PR; the other (Public benchmark evidence freshness) is the documented pre-existing red on every PR in this repo.Not run / out of scope
run_lint_gates.sh(known-red on Linux per this campaign's contract).tests plus the direct acceptance test instead.
constructor.namegap) — out of scope for a removal PR.CLAUDE.mdedit — the maintainer bumps at merge time.Umbrella-feature coupling check
bundled-decimalis referenced only by perry-stdlib'sfullfeature list, which this PRalready updates. Checked every other feature umbrella in
crates/perry-stdlib/Cargo.toml(crypto,database,ids, etc.) — none referencesbundled-decimal. This removal doesn't touch any featurebundled-lru-cache/bundled-commanderneed either. The three removal PRs (this one, #10685, #10686)are independent on this axis and can merge in any order relative to each other.
Rebased onto main @
91a566c8af(train 226, v0.5.1605) — genuine rebase, not a mergeThis PR was stacked on
fix/10439-native-binding-import-provenance(#10699's branch), whichsquash-merged into main, so its original base commits are no longer reachable from main as such.
Identified the 2 commits genuinely unique to this branch (
git log <10699-branch-tip>..<this-branch>)and replayed only those via
git rebase --onto origin/main <10699-branch-tip> <this-branch>, the sametechnique #10679 (axios, stacked on #10673's branch) used.
Recomputed triple: workspace_members = 77, externalize = 28, keep = 44 (merge=1, remove=1,
review=3 unchanged; sum 77), independently reproduced by
workspace_architecture.py --check --print-summaryfrom the resolved tree — not the stale 82/32/45 this PR previously recorded (that wasagainst a base of 83, several trains back). Main's baseline confirmed before deriving: 78/29/44
(train 226, post-axios).
Hit the recurring false-merge trap on
workspace-architecture.jsonfor real this time — meaningthe opposite of the last several rebases: git raised genuine conflict markers (HEAD=78/29/44 vs
theirs=82/32/45, textually different enough that the 3-way merge couldn't silently collapse them).
Resolved to 77/28/44 by hand, confirmed by the script. The crate-map deletion of
perry-ext-decimalitself applied cleanly with no conflict.
A new instance of the same silent-wrong-merge class showed up on
docs/api/perry.d.tsanddocs/src/api/reference.md— both auto-merged with zero conflict markers, and the body contentwas correctly stripped of decimal.js sections, but the header count lines silently kept main's stale
value (2067/132 and 3009/134 — main's exact current numbers, decimal.js not yet subtracted). Caught by
regenerating both from a freshly built
perry-devbinary rather than trusting the clean merge:corrected to 2066/131 and 2983/132.
scripts/native_result_ledger.py'sEXPECTED_ROWS/EXPECTED_PROVIDERSrecounted from the resolvedtree, not adjusted arithmetically. This PR's original branch recorded 359/310 against a base of
371/322; main is now green at 376/326 (post-#10738). Running the script on the actual resolved tree
(after all other conflicts were resolved) gives the real current values: 364 rows / 314 providers
— not derivable by subtracting this PR's old delta (17/16) from main's new base, since that delta was
measured against a different tree shape. Confirmed by running the script twice: once to discover the
real row count (temporarily setting
EXPECTED_ROWSand re-running to surface the real provider count),then setting both and confirming a clean pass with no stale-provider or kind-mismatch errors.
scripts/unrooted_local_shape_baseline.jsonre-derived, not left at a technically-passing stalevalue.
--checkreported 577 < baseline 578 (an improvement, so it passed) — but per the standinginstruction to re-derive rather than leave a passing-but-stale number, ran
--update-baselineto bringthe file to 577.
Also resolved:
Cargo.lock(took main's side, regenerated viacargo metadata --offline, zeromarkers, zero
perry-ext-decimalentries),Cargo.tomlversion (main's, 0.5.1605),crates/perry-api-manifest/src/entries/part_1.rs(main already lacks the uuid/jsonwebtoken rows thisPR's stale diff still carried; resolved to neither those nor decimal.js's rows),
crates/perry-stdlib/Cargo.toml'sfullfeature list (main already lacksvalidation; removedbundled-decimalfrom main's current list rather than reintroducingvalidation),crates/perry-hir/tests/fluent_chain_lowering.rs(a comment-only conflict — main already carries#10699's own consolidated explanation for why this test was removed, from a follow-up fix landed
directly on the shared branch tip before this PR's own base; took main's version rather than this PR's
redundant restatement of the same fact). Confirmed the file rename this branch performs
(
async_decimal.rs→async_hooks.rs, since only async_hooks dispatch rows remain in that file afterdecimal's rows are stripped) is intentional and that
native_table/mod.rsreferences the new namecorrectly.
None of #10750's at-cap files (
perry-codegen/src/stmt/let_stmt.rs,perry-hir/src/lower/stmt_loops.rs,perry-runtime/src/gc/tests/copying.rs,perry-runtime/…/module_keys.rs,perry/…/cjs_wrap/tests.rs,perry-codegen/src/rooting/mod.rs) are touched by this diff — confirmed viagit diffagainst main,not assumed from the removal's usual shape.
Gates re-run on the rebased tree:
cargo fmt --checkclean,cargo check --workspace --all-targets -D warningsclean (noperry-ext-decimal, noperry-ext-axios— landed;perry-ext-dotenvstill present— #10691 hasn't landed yet),
check_file_size.shOK,run_lint_gates.sh SKIP_COMPILE_GATES=178/79(only the known public-baseline red),
git diff --statempty after every gate run. No re-run of theacceptance test — nothing in train 226 changes what decimal.js/big.js/bignumber.js do; the acceptance
result above still stands.
Left as draft per instruction — this PR is a pathfinder for the two structurally identical PRs
(#10708, #10712) also stacked on the same now-squash-merged branch with the same stale counts; they are
not touched by this work.
Rebase note (2026-09-20)
Rebased onto
main@b9ba951ff861c61afb845bfbdfa574cb0fa4080e(train 239) as part of a4-PR sequential rebase campaign together with #10795, #10677, #10680 — all four
independently rebased onto this same main SHA and pushed together.
Base-pointer check, since the brief flagged this PR's as possibly wrong: verified
directly — this branch's actual fork point (
chore: release merge train 226,91a566c8af5) is an ancestor of current main, 55 commits behind. It is not stacked onthe unmerged tip of
fix/10439-native-binding-import-provenancethe way #10677/#10680 werestacked on their shared branches; #10699 (which carries #10439's fix) landed on main via
the normal merge-train process before this branch's own fork point. So this needed only a
plain
git rebase origin/main, not--ontosurgery — the two-step unstack described in thecampaign brief did not apply here after all.
baseRefNamewas alreadymain.Conflicts were the heaviest of the four (91 total lines of conflict markers across 21
files, since this branch was 55 commits stale) but all fell into two shapes already seen on
the other three PRs: (a) main had independently removed something adjacent (
uuid/qs,fastify,lru-cache/commander,dayjs/date-fns) at the same list position this PR'sdecimal.js/big.js/bignumber.jsentries occupied — resolved against current main'sactual content, not either conflict side blindly; (b) generated files (docs, ledgers,
baselines, governance table) — fully regenerated from the resolved tree via their own
tools.
Two things found only by rebasing, not visible on either parent:
crates/perry-hir/src/lower_patterns.rs'sdetect_native_instance_exprwent fullydead and tripped
-D warnings'unreachable_codelint. Itsnew-expression match armused to recognize five names (
Big/Decimal/BigNumberfrom this PR,LRUCache/Commandfrom the already-landed refactor(stdlib): remove lru-cache native binding #10708/refactor(stdlib): remove commander native binding #10712) — with all five gonethe match had zero live arms, so the two-stage
let module = match … { _ => return None }; match ctx.lookup_native_module(…) {…}dance became provably unreachable.Simplified the arm to what it always evaluates to and rewrote the doc comment. This is
the sequencing interaction the campaign brief warns about (
each one's correct numbers depend on which land before it) showing up as a real compile warning, not just a stalecount: neither this PR's diff nor refactor(stdlib): remove lru-cache native binding #10708/refactor(stdlib): remove commander native binding #10712's touched this exact file's other half,
so nothing before rebase-time could see the combination.
test-files/test_parity_decimal.ts+ itstest-parity/known_failures.jsonentrywere left behind by the original PR (unlike refactor(stdlib): remove cron/exponential-backoff/moment/node-forge native bindings #10795, which deleted its own moment/cron/
backoff fixtures as part of the same removal). Deleted both — decimal.js has no
Perry-specific behavior left to validate, and the fixture was already skip-listed as a
broken oracle (Node itself can't resolve
decimal.jspost-npm ci, parity: 2026-08-17 dark-debt audit — 93 parity + 27 compile failures unlisted after six dark weeks (90.7% aggregate) #8271) before thisPR. Confirmed via
parity_known_failures.py --audit(part ofrun_lint_gates.sh) thatremoving the entry doesn't orphan anything.
Verified
crates/perry/tests/issue_10439_native_binding_import_provenance.rsstillpasses — its
decimal_default_name_reaches_real_source_under_compile_packagestestcompiles a fake
decimal.jspackage viaperry.compilePackagesand asserts the realcompiled source runs, not a native-handle interception. With the native binding gone there
is nothing left to intercept, so this is now testing the same (already-true-on-main)
shape as the file's own
lru_cache_.../commander_...sibling tests. Ran all three:cargo test --profile perry-dev -p perry --test issue_10439_native_binding_import_provenance→3 passed, 0 failed. (First attempt reported all three failing with an identical "runtime
library does not match this Perry compiler" error — a stale-archive artifact from building
perry-runtime-staticandperryin overlapping invocations while iterating in the sametarget dir, not a real regression;
cargo clean -p perry -p perry-runtime -p perry-stdlib -p perry-runtime-static -p perry-stdlib-static+ a fresh combined build resolved it andall three passed.) This crate's suite wasn't named by this PR's diff, so per the brief:
flagging explicitly that this PR's change affects a test in a suite it doesn't touch.
Recomputed triple:
workspace_members=69(decision_counts: externalize=20, keep=44,merge=1, remove=1, review=3) — needed a full recompute; a stray
"perry-ext-decimal"entryalso survived the auto-merge in the per-crate map, same shape as #10677/#10680;
native_result_ledger: 344 rows / 295 providers (reflects both the decimal.js row removaland the
async_decimal.rs→async_hooks.rssplit the original PR's own commit performed —the same file used to carry both decimal and async_hooks
NativeModSigrows together);unrooted-local-shapetotal: 554.These numbers assume main is still at the stated SHA — whichever of the four PRs lands
first moves the ground under the other three's counts.
Shared-crate check:
decimal.jsandbignumber.jsalready sharedperry-ext-decimalwithin this PR's own scope (by design, per the PR body above);
big.jswas never aseparate
[bindings.*]entry (routes through the same class-name recognition without itsown well-known-bindings row). No sharing with anything outside this PR's own removal set.
Gates:
cargo fmt --all -- --checkOK;cargo check --workspace --all-targetsunder-D warningson the defaultdevprofile (excl.perry-ui-gtk4) — clean, 0 warnings (afterthe
lower_patterns.rsfix above);run_lint_gates.sh SKIP_COMPILE_GATES=1— 78 of 79passed (1 pre-existing, #10707, not chased);
binding_governance.py --checkOK;binding_pins.mjs --checkunder Node 26.5.1 OK;check_file_size.shOK. Compile tier notrun. No gap sweep run. No acceptance re-run for the package-compile behavior itself (only
the
issue_10439integration-test re-run above, which was necessary given the dead-codefinding).