Skip to content

refactor(stdlib): remove mysql2 native binding - #10680

Closed
proggeramlug wants to merge 5 commits into
mainfrom
wip/mysql2-removal
Closed

proggeramlug wants to merge 5 commits into
mainfrom
wip/mysql2-removal

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Removes the mysql2 native binding so import mysql from "mysql2" resolves to
the real npm package, per the owner's decision to stop shipping hand-written
Rust reimplementations of npm packages (they drift from the real thing — see
the jsonwebtoken.verify example in the campaign background).

Must not merge before #10675 (wip/10661-dyn-eval-class-expr, this PR's
base). mysql2's real source does not compile without that PR's dyn_eval
class-expression support — generate-function builds mysql2's row parsers
with a runtime new Function(...) that returns a class expression.

What was removed and why

Two candidate locations turned out to be genuinely separate, both hand-written
reimplementations of mysql2 using sqlx directly:

  • crates/perry-ext-mysql2 — the governance-tracked binding
    (docs/src/native-libraries/governance.md: "Source package", target
    "Compile the upstream package source"). Wired into
    well_known_bindings.toml's [bindings.mysql2] / [bindings."mysql2/promise"],
    and the crate a plain import mysql from "mysql2" (no compilePackages)
    actually linked against.
  • crates/perry-stdlib/src/mysql2/ (~1870 lines) — a second,
    independent mysql2 implementation gated behind perry-stdlib's
    bundled-mysql2 feature (default-on via full). It defined the exact same
    js_mysql2_* symbol names as perry-ext-mysql2, in a separate handle
    registry
    (perry-ffi's handle table and perry-stdlib's common::handle
    table are explicitly documented as disjoint integer spaces — see
    crates/perry-ffi/src/handle.rs). Its dispatch_mysql2_method/
    dispatch_mysql2_property dynamic-dispatch fallback (for Drizzle's
    interface-typed client fields) could only ever resolve handles created by
    its own js_mysql2_create_connection/createPool — which lose the link
    to whichever archive the linker picks between two archives exporting the
    same symbol names. In the default (full) feature build both crates ship
    js_mysql2_*, so this was already a live footgun, not merely inert.

Both were removed. Neither is separable from "the mysql2 native binding"
— they are the same category of hand-written duplicate the campaign targets,
just delivered through two different mechanisms (well-known ext-crate flip vs.
a default-on stdlib feature).

Also removed the bundled-mysql2 HIR heuristic in
perry-hir/src/lower/expr_call/native_module.rs (mysql2_config_signature /
detect_bundled_mysql2_create) that recognized a bundler-inlined
(webpack/turbopack) createPool/createConnection call by its config-object
shape and routed it to perry-ext-mysql2's FFI symbols. That workaround
existed only because the AOT binary couldn't run mysql2's generate-function
row parsers; #10675 fixes that generally via dyn_eval, so the heuristic (and
its bundled_mysql2_tests module, trimmed rather than deleted — it also
covered an unrelated is_process_active_array_helper test, kept under a
renamed native_module_helper_tests mod) is no longer needed.

Left alone, deliberately: a handful of shared perry-hir files
(local_natives.rs, native_new.rs, native_fetch.rs, misc.rs,
module_decl.rs, static_and_instance.rs) still pattern-match on the string
literals "mysql2" / "mysql2/promise" for class-shape inference (e.g.
tagging createPool()'s result as a Pool). These are now structurally
unreachable — the only two producers of a NativeMethodCall/NativeModuleRef
with that module string were NATIVE_MODULES membership (removed) and the
bundled-heuristic above (removed) — but hand-editing every multi-package match
arm in files shared with the concurrent axios/pg removal branches risked a
larger, conflict-prone diff for no behavioral change. Also left alone:
prose comments across perry-runtime/perry-codegen that cite real mysql2
source shapes (MockBuffer, generate-function, drizzle transactions) as
motivating examples for unrelated compiler features — those describe why the
compiler behaves a certain way, not the binding being removed.

Registries and gates touched

  • crates/perry/well_known_bindings.toml — drop [bindings.mysql2] /
    [bindings."mysql2/promise"]
  • crates/perry-api-manifest/src/entries.rs (+ entries/part_1.rs,
    entries/part_3.rs) — drop NATIVE_MODULES entries and all mysql2
    manifest rows
  • crates/perry-codegen/src/lower_call/native_table/databases.rs — drop the
    MySQL2 NativeModSig section
  • crates/perry-codegen/src/ext_registry.rs — drop the mysql2 FFI_REGISTRY
    rows
  • crates/perry/src/commands/stdlib_features.rs,
    optimized_libs/driver.rs, optimized_libs/freshness.rs — drop the
    mysql2bundled-mysql2 wiring
  • crates/perry/src/commands/compile/resolve.rs
    PERRY_NATIVE_EXTENSION_PACKAGES (this is what let mysql2's real .js
    source reach the module walker instead of being silently skipped as
    "handled by native stdlib")
  • workspace-architecture.json — drop the perry-ext-mysql2 decision entry
    and refresh the baseline counts (workspace_members, externalize)
  • scripts/unrooted_local_shape_baseline.json,
    scripts/string_payload_access_baseline.txt,
    scripts/native_result_ledger.tsv (+ EXPECTED_ROWS/EXPECTED_PROVIDERS
    in native_result_ledger.py) — drop entries for the deleted files/symbols
  • .github/workflows/test.yml, scripts/run_doc_tests.sh/.ps1 — drop the two
    explicit -p perry-ext-mysql2 cargo build args (compile-smoke + UI-backend
    jobs, doc-tests harness); these would otherwise fail with "no such package"
  • crates/perry-ui-android/src/stdlib_stubs.rs — drop the 14 js_mysql2_*
    Android stub exports
  • docs/src/api/reference.md, docs/api/perry.d.ts — regenerated
    (--print-api-manifest)
  • docs/src/native-libraries/governance.md — regenerated table (drops the
    perry-ext-mysql2 row) + a new "Completed source migrations" bullet,
    matching the existing slugify entry's pattern
  • crates/perry/src/commands/compile/collect_modules/binding_faithfulness.rs
    — dropped lookup_preserves_registered_subpaths_before_falling_back, the
    one test whose only real-world fixture (mysql2/promise's
    alias-of = "mysql2") no longer exists in well_known_bindings.toml (it
    was the only root+subpath alias in the whole table); the sibling test
    using "mysql2" as an arbitrary on-disk-directory fixture name is untouched
    since it doesn't depend on the registry.

Acceptance test: real query round-trip, no compilePackages entry

Built on the perrymaster host (--profile perry-dev, -p perry -p perry-runtime-static -p perry-stdlib-static, then PERRY_WORKSPACE_ROOT set
so auto-optimize could pull in the wrapper crates the real mysql2 source
needs — perry-wasm-host, perry-ext-net, perry-ext-events,
perry-ext-zlib). Test program:

import mysql from "mysql2/promise";
const conn = await mysql.createConnection({ host: "127.0.0.1", port: 3306, user: "pkgaudit", password: "pkgaudit_pw", database: "perry_pkgaudit_test" });
await conn.query("CREATE TABLE IF NOT EXISTS t (id INT PRIMARY KEY, val VARCHAR(64))");
await conn.query("INSERT INTO t (id, val) VALUES (1, 'hello-perry')");
const [rows] = await conn.query("SELECT val FROM t WHERE id = 1");
// ...DROP TABLE, conn.end()

with package.json:

{ "dependencies": { "mysql2": "^3" } }

No perry.compilePackages entry at all — not for mysql2, not for its
transitive deps. Compile log: Compile package wildcard: expanded to 60 installed package(s) (Perry's default automatic package-routing path,
already used by the slugify migration) compiled real mysql2 + its
dependency tree (generate-function, iconv-lite, long, lru.min,
named-placeholders, sql-escaper, aws-ssl-profiles, ...) from source.
One informational notice: generate-function/index.js:362's runtime new Function(...) — mysql2's row-parser factory — was "handled at runtime:
runtime interpreter (#6559)", i.e. dyn_eval, exactly the mechanism #10675
added.

Ran the resulting binary against the real local MySQL 8.0.46 server:

GOT_ROW=[{"val":"hello-perry"}]
RESULT: PASS

CREATE TABLE / INSERT / SELECT / DROP TABLE all round-tripped with the
real row parser, real wire protocol, real auth handshake.

Verification

  • cargo check/cargo build --profile perry-dev -p perry -p perry-runtime-static -p perry-stdlib-static: clean (confirmed .a mtimes
    moved after the edits)
  • cargo test -p perry-api-manifest -p perry-hir: all passing
  • cargo test -p perry-codegen --test manifest_consistency: all 5 passing
    (every_native_module_has_at_least_one_manifest_entry,
    every_dispatch_entry_has_manifest_counterpart, etc.) — confirms the
    registry edits are internally consistent
  • python3 scripts/binding_governance.py --check: OK (39 extension crates
    classified)
  • node scripts/binding_pins.mjs --check: OK (37 pinned, lock-step holds)
  • scripts/run_lint_gates.sh (SKIP_COMPILE_GATES=1): 76 of 77 passed.
    The one failure, "Public benchmark evidence freshness", is pre-existing on
    every PR in this repo (per the campaign's own fix-agent contract) — not
    touched here.
  • Real MySQL round-trip: see above.

Not run / out of scope

  • Compile tier of run_lint_gates.sh (known-red on Linux per the campaign
    contract; not run)
  • Full gap suite (host stalls under auto-optimize per the campaign contract);
    ran the targeted registry/consistency tests instead
  • No version bump / CLAUDE.md edit — per this campaign's convention, the
    maintainer bumps at merge time

Rebase note (2026-09-20)

Rebased onto main @ b9ba951ff861c61afb845bfbdfa574cb0fa4080e (train 239) as part of a
4-PR sequential rebase campaign together with #10795, #10677, #10704 — all four
independently rebased onto this same main SHA and pushed together. This PR's base is now
main
, not wip/10661-dyn-eval-class-expr: that branch squash-merged into main some
time ago, so this needed the two-step unstack — git rebase --onto origin/main <wip/10661 tip> pr-10680 followed by gh pr edit --base main.

Conflicts spanned 8 files on the removal commit (Cargo.lock, crates/perry-api-manifest/ src/entries/part_1.rs — a genuinely large one: main had independently inserted 40+
fastify manifest rows into the exact list position this PR's mysql2 rows occupied, since
fastify's own binding was removed by a different PR after this branch forked; resolved by
taking current main's file verbatim and deleting only the mysql2-specific entries, not
hand-merging the two unrelated changes — crates/perry-ui-android/src/stdlib_stubs.rs
same shape, crates/perry/src/commands/compile/collect_modules/binding_faithfulness.rs,
crates/perry/src/commands/compile/resolve.rs, docs/api/perry.d.ts,
docs/src/api/reference.md, docs/src/native-libraries/governance.md,
scripts/native_result_ledger.py, scripts/string_payload_access_baseline.txt,
workspace-architecture.json) plus 6 more on the second commit.

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-mysql2" entry
also survived the auto-merge in the per-crate map even after the baseline numbers were
fixed, which --check caught on a second pass (a technically-self-consistent baseline block
can still describe a workspace that no longer exists — the two checks are independent);
native_result_ledger: 328 rows / 293 providers (main's real ledger minus mysql2's 28
declarations, matching the original PR's own "leaving 343... 356→343" note's arithmetic
once resynced against a rebased main whose own baseline had also since moved to 356/307);
unrooted-local-shape total: 491.

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; re-derive before queuing a second
or third one.

Gates: cargo fmt --all -- --check OK (one cargo fmt --all pass needed after conflict
resolution, same comment-alignment class as #10677); cargo check --workspace --all-targets under -D warnings on the default dev profile (excl. perry-ui-gtk4) —
clean; run_lint_gates.sh SKIP_COMPILE_GATES=1 — 78 of 79 passed (1 pre-existing, #10707,
not chased); binding_governance.py --check OK; binding_pins.mjs --check under Node
26.5.1 OK; check_file_size.sh OK. .github/workflows/test.yml's own -p perry-ext-mysql2
removal (already part of this PR) auto-merged clean; verified -p perry-ext-pg on those
same two lines is untouched, since removing it is #10677's job landing independently.
Compile tier not run. No gap sweep run. No acceptance re-run.

@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 2 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 8 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 9ea0a357-3103-4c70-8893-baad296cf63e

📥 Commits

Reviewing files that changed from the base of the PR and between b9ba951 and 2a434bd.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • scripts/native_result_ledger.tsv is excluded by !**/*.tsv
📒 Files selected for processing (39)
  • .github/workflows/test.yml
  • Cargo.toml
  • changelog.d/10680-mysql2-native-binding-removal.md
  • crates/perry-api-manifest/src/entries.rs
  • crates/perry-api-manifest/src/entries/part_1.rs
  • crates/perry-api-manifest/src/entries/part_3.rs
  • crates/perry-codegen-js/src/emit/native.rs
  • crates/perry-codegen/src/ext_registry.rs
  • crates/perry-codegen/src/lower_call/native_table/databases.rs
  • crates/perry-codegen/src/lower_call/native_table/mod.rs
  • crates/perry-ext-mysql2/Cargo.toml
  • crates/perry-ext-mysql2/src/lib.rs
  • crates/perry-ext-mysql2/src/test_async_shims.rs
  • crates/perry-hir/src/lower/expr_call/native_module.rs
  • crates/perry-stdlib/Cargo.toml
  • crates/perry-stdlib/src/common/dispatch/method_dispatch.rs
  • crates/perry-stdlib/src/common/dispatch/property_dispatch.rs
  • crates/perry-stdlib/src/lib.rs
  • crates/perry-stdlib/src/mysql2/connection.rs
  • crates/perry-stdlib/src/mysql2/mod.rs
  • crates/perry-stdlib/src/mysql2/pool.rs
  • crates/perry-stdlib/src/mysql2/result.rs
  • crates/perry-stdlib/src/mysql2/types.rs
  • crates/perry-ui-android/src/stdlib_stubs.rs
  • crates/perry/src/commands/compile/collect_modules/binding_faithfulness.rs
  • crates/perry/src/commands/compile/optimized_libs/driver.rs
  • crates/perry/src/commands/compile/optimized_libs/freshness.rs
  • crates/perry/src/commands/compile/resolve.rs
  • crates/perry/src/commands/stdlib_features.rs
  • crates/perry/well_known_bindings.toml
  • docs/api/perry.d.ts
  • docs/src/api/reference.md
  • docs/src/native-libraries/governance.md
  • scripts/native_result_ledger.py
  • scripts/run_doc_tests.ps1
  • scripts/run_doc_tests.sh
  • scripts/string_payload_access_baseline.txt
  • scripts/unrooted_local_shape_baseline.json
  • workspace-architecture.json

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

Copy link
Copy Markdown
Contributor Author

Heads-up before this is queued: this PR's recorded workspace baseline is stale and will fail workspace_architecture.py --check on rebase.

It records workspace_members 82 / externalize 32 / keep 45. Main (023dc0b653) is at 80 / 31 / 44, so a removal landing on it must produce 79 / 30 / 44 — not 82. Five sibling removal PRs carry the identical 82/32/45, which is also mutually impossible: six different crates cannot all produce the same transition.

Full table and reasoning in #10739. The short version, for whoever rebases this:

  • Recompute from the resolved tree and let workspace_architecture.py --check --print-summary reproduce the number independently. Do not derive it from 83 by arithmetic, and do not copy a sibling's figure or one quoted in a comment — they all go stale as the queue advances.
  • The same hazard applies to scripts/native_result_ledger.tsv, scripts/string_payload_access_baseline.txt and the governance/pins tables. Regenerate with their own scripts rather than resolving by hand.
  • MERGEABLE will not catch this. The counts sit on different JSON lines from the deleted crate entry, so git auto-merges both sides without a conflict — chore(bindings): remove axios native binding, compile real axios from source #10679 rebased onto current main today, came out MERGEABLE, and still carried 82/32/45.

Also relevant to the acceptance run whenever it happens: #10735 is live on main — require.main === module is true in every compiled CommonJS module, so any dependency with a CLI entry guard runs its CLI branch when merely imported. A fix is in flight. If acceptance fails in a way that looks like the package misbehaving at import time, test a dependency-free fixture that never mentions the package before attributing it to this removal.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

This PR reports MERGEABLE, but its recorded counts are stale by twelve crates and will fail workspace_architecture.py --check on rebase.

It records workspace_members: 82 / externalize: 32 / keep: 45, derived when main was at a base of 83. Main is now at 70 / 21 / 44 — fourteen bindings have been removed since. A one-crate removal landing on today's main must produce 69 / 20 / 44, not 82/32/45.

Nothing about this is visible in the diff: the counts sit on different JSON lines from the deleted crate entry, so git auto-merges cleanly and GitHub reports the PR mergeable. See #10739 for the general mechanism.

A distinction worth drawing, because it caught me out

This PR's file is internally consistent: sum(decision_counts) == workspace_members == len(crates) = 82 in all three. It passes the three-way identity check that has caught two defects elsewhere in this campaign.

So the three-way check is necessary but not sufficient. It validates the file against itself, not against the tree the PR will land on. A file can be perfectly self-consistent and still describe a workspace that no longer exists. Both checks are needed:

  1. internal: sum == workspace_members == len(crates) — catches a merge that updated one field and not another;
  2. external: the values equal what the resolved tree actually contains after rebasing onto current main — catches staleness.

This PR passes (1) and fails (2). #10691 earlier failed (1) while looking plausible on (2). They are independent failure modes and neither check subsumes the other.

What this needs

A rebase onto current origin/main, with every absolute re-derived from the resolved tree rather than adjusted:

  • workspace-architecture.json — recompute, verify both checks above.
  • scripts/native_result_ledger.pyEXPECTED_ROWS/EXPECTED_PROVIDERS. Recount, do not subtract: the value is not obtainable by applying this PR's old delta to main's new base, because the tree shape differs.
  • scripts/unrooted_local_shape_baseline.json — re-derive even if --check passes; a technically-passing stale number is how native_result_ledger.py is red on pristine main (expected 371, found 376), and its path filter means it can only fail on an unrelated PR #10738's masked defect survived.
  • docs/api/perry.d.ts and docs/src/api/reference.mdregenerate from a fresh binary, header and body. These merge clean and stay stale, and nothing gates them; a stale declare module "..." block survived a clean merge on a previous removal.
  • Cargo.lock — after any git checkout --ours, re-sync immediately with cargo metadata --offline rather than trusting the next build to catch a stale perry-ext-* entry.

perry-bot and others added 5 commits September 20, 2026 13:07
Deletes perry-ext-mysql2 (the well-known-table crate that provided
js_mysql2_* symbols for plain `import mysql from "mysql2"`) and
perry-stdlib/src/mysql2/ (a second, duplicate hand-written mysql2
implementation gated behind the bundled-mysql2 feature). Removes the
supporting registry wiring: well_known_bindings.toml, NATIVE_MODULES /
manifest entries in perry-api-manifest, the native_table/databases.rs
MySQL2 codegen rows, ext_registry.rs FFI routing, the bundled-mysql2
HIR heuristic for bundler-inlined mysql2 (superseded by #10675's
dyn_eval class-expression support), stdlib_features.rs /
optimized_libs driver+freshness wiring, workspace-architecture.json,
and the unrooted-local-shape baseline entries for the deleted files.

Based on wip/10661-dyn-eval-class-expr (#10675) — mysql2 does not
compile from real source without that fix.

# Conflicts:
#	Cargo.lock
#	crates/perry-api-manifest/src/entries/part_1.rs
#	crates/perry-ui-android/src/stdlib_stubs.rs
#	crates/perry/src/commands/compile/collect_modules/binding_faithfulness.rs
#	crates/perry/src/commands/compile/resolve.rs
#	workspace-architecture.json
…docs)

- cargo fmt after the removal (entries.rs / resolve.rs realignment)
- drop the two explicit -p perry-ext-mysql2 args from .github/workflows/test.yml
  (compile-smoke + UI-backend jobs) and from run_doc_tests.sh/.ps1
- drop the 14 js_mysql2_* rows from scripts/native_result_ledger.tsv and
  update its EXPECTED_ROWS/EXPECTED_PROVIDERS counts (343/308)
- refresh workspace-architecture.json's baseline counts (82 members,
  externalize=32) so scripts/workspace_architecture.py --check passes
- rewrite scripts/string_payload_access_baseline.txt via --write-baseline
  (perry-ext-mysql2 row dropped, perry-stdlib 40 -> 38)
- regenerate docs/src/api/reference.md, docs/api/perry.d.ts, and
  docs/src/native-libraries/governance.md's generated table; add a
  "Completed source migrations" entry for mysql2

run_lint_gates.sh (SKIP_COMPILE_GATES=1): 76/77 passed, only the
pre-existing "Public benchmark evidence freshness" red.

# Conflicts:
#	crates/perry-api-manifest/src/entries.rs
#	crates/perry/src/commands/compile/resolve.rs
#	docs/api/perry.d.ts
#	docs/src/api/reference.md
#	docs/src/native-libraries/governance.md
#	scripts/native_result_ledger.py
#	scripts/string_payload_access_baseline.txt
#	workspace-architecture.json
…ysql2-removal rebase

Removes the stray perry-ext-mysql2 crate entry that survived the rebase's
auto-merge in workspace-architecture.json (the baseline block alone would
have passed --check while the per-crate map still named a deleted crate).
Resyncs Cargo.lock, recomputes native_result_ledger EXPECTED_ROWS/PROVIDERS
from the resolved tree (328 rows, 293 providers), and regenerates the
unrooted-local-shape / string-payload-access baselines, the generated
binding-governance table, and docs/api/perry.d.ts + docs/src/api/reference.md
from a fresh perry-dev build.
@proggeramlug
proggeramlug changed the base branch from wip/10661-dyn-eval-class-expr to main September 20, 2026 13:50
@proggeramlug
proggeramlug marked this pull request as ready for review September 20, 2026 13:54
proggeramlug pushed a commit that referenced this pull request Sep 20, 2026
Squashed rebase of #10680 on top of #10677. Generated/absolute-count files are left at main's values here and regenerated from their owning scripts in a later commit (#10739).

Non-obvious conflict call: #10680's side of crates/perry-hir/src/lower/expr_call/native_module.rs still contained native_module_member_path(), which main deleted with the node-forge binding. Taking 'theirs' would have resurrected it as dead code, so the whole hunk resolves to empty.
proggeramlug pushed a commit that referenced this pull request Sep 20, 2026
#10677 deleted perry-ext-pg and perry-stdlib/src/pg but left the call sites
that reference their symbols:

- lower_call/builtin.rs still lowered `new Client(cfg)`/`new Pool(cfg)` from
  an `import ... from "pg"` to `js_pg_client_new`/`js_pg_pool_new`. With no
  provider those are undefined at link time, which is exactly the failure the
  real `pg` package would hit (it constructs `new Client`). Dropped the two
  arms and the `"Client" | "Pool" => Some(&["pg"])" import gate together, so
  a user-defined Pool/Client falls through to the generic path (#536).
- runtime_decls/stdlib_ffi/data_stores.rs declared the ten js_pg_* externs.
- perry-ui-android/src/stdlib_stubs.rs defined seven js_pg_* stubs (#10680 had
  already dropped the matching mysql2 ones).
- perry-codegen-js browser-emit list and a native_table/mod.rs comment.
- scripts/run_doc_tests.sh / .ps1 still passed -p perry-ext-pg to cargo build,
  which no longer resolves.
proggeramlug pushed a commit that referenced this pull request Sep 20, 2026
…ysql2 removal

that is now 28 commits behind `main`, so neither side's numbers could be
merged (#10739). Every count below is what the owning script reports on this
resolved tree — none of it is arithmetic on the two PRs' figures:

  Cargo.lock                     cargo metadata --offline
                                 (drops perry-ext-pg, perry-ext-mysql2 and,
                                 via sqlx's mysql-rsa edge, rsa/pkcs1/
                                 crypto-primes)
  workspace-architecture.json    scripts/workspace_architecture.py --check
                                 --print-summary: members 66 -> 64,
                                 externalize 17 -> 15 (keep/merge/remove/
                                 review unchanged). The two `crates` policy
                                 entries are deleted; the script errors on a
                                 policy entry with no workspace crate.
  native_result_ledger.py/.tsv   scripts/native_result_ledger.py:
                                 349 -> 314 rows, 300 -> 279 providers.
                                 Both PRs landed on 349/300 for unrelated
                                 reasons, so the textual auto-merge agreed
                                 and was wrong.
  unrooted_local_shape_baseline  scripts/unrooted_local_shape.py
                                 --update-baseline: total 527 -> 428.
  string_payload_access_baseline scripts/string_payload_access_inventory.py
                                 --write-baseline: perry-stdlib 36 -> 28,
                                 the perry-ext-pg/mysql2 rows dropped.
  docs/src/api/reference.md      target/<profile>/perry --print-api-manifest
  docs/api/perry.d.ts            (run directly: regen_api_docs.sh hardcodes
                                 <worktree>/target/release/perry and silently
                                 truncates both files when that path is
                                 absent). 2870 -> 2829 entries across
                                 120 -> 117 modules, which is exactly the 41
                                 manifest rows (9 pg + 32 mysql2) and 3
                                 specifiers removed; tails intact.

Also folded in here: a stray `}` left in perry-hir's native_module.rs by the
conflict markers), the changelog fragments corrected to the results actually
measured on this branch, and a `pg` entry in governance.md's "Completed
source migrations" list to match the one #10680 added for mysql2.
@proggeramlug

Copy link
Copy Markdown
Contributor Author

Landed via merge train 245 (#10845), released as v0.5.1624 — merge commit b3bffd778c.

Carried together with its sibling removal, deliberately: #10678's duplicate-symbol hazard is only closed by removing both bindings, because each existed twice (the perry-ext-* crate and the pre-#466 in-tree perry-stdlib/src/<pkg> behind a bundled-* feature), defining the same extern "C" symbols with link order silently deciding the winner. Removing one leaves the other's pair intact.

Two things were redone rather than carried through the rebase onto v0.5.1623:

  • Cargo.lock was regenerated, not hand-merged. A hand-merge for a change that deletes two crates and their transitive trees is a guess; this took main's lock and let cargo reconcile it, then asserted the result (cargo metadata --offline --locked rc=0, no markers, no perry-ext-{pg,mysql2} / postgres / mysql_* entries).
  • Every absolute count was re-derived against the new base. Removal counts are chained, so a baseline computed against an older main is wrong against the current one. All eight ratchets green, and binding_governance --check was checked for discrimination rather than assumed live: rc=0 on the train, rc=1 naming both crates on main's file.

Validation on the union: lint 6-of-6 with no unexpected failures, 6 unit suites with an empty failing set, both compiler-output suites at failed_workloads=[] with no transient excused, repsel_census rc=0, and a 140-fixture gap sweep across seven areas with zero unexplained regressions and every area asserted live.

Closing here rather than merging — a train lands the commits directly, so the source PR has nothing left to merge.

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.

2 participants