Skip to content

fix(build): stop discarding the bindings/javascript release profile - #2296

Merged
gHashTag merged 1 commit into
masterfrom
fix/workspace-profile-ignored
Aug 20, 2026
Merged

fix(build): stop discarding the bindings/javascript release profile#2296
gHashTag merged 1 commit into
masterfrom
fix/workspace-profile-ignored

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Closes #2295

The defect

Cargo prints this on every invocation in this workspace, on master today:

warning: profiles for the non root package will be ignored, specify profiles at the workspace root:
package:   <repo>/bindings/javascript/Cargo.toml
workspace: <repo>/Cargo.toml

bindings/javascript/Cargo.toml declares opt-level = "z" and lto = true.
The crate is in the root members array, so Cargo discards both and builds it
with the default release profile (opt-level = 3, lto = false).
release.yml publishes that crate to npm with
wasm-pack build --target bundler --release, run from inside the crate
directory — but wasm-pack resolves the enclosing workspace, so the published
.wasm has been built speed-optimized and un-LTO'd.

Correction to the premise I was handed

The task that produced this PR described bootstrap/Cargo.toml as the crate
declaring the orphaned profile. That is not true of master — it is true
of the branch feat/wave-547/host-heapsort. On master,
bootstrap/Cargo.toml has no [profile] section at all, and a scan of every
Cargo.toml in the tree finds exactly one member declaring one:
bindings/javascript. Cargo's own warning names the same single file. The bug
is real; the crate named in the brief was not.

Why the profile was not moved to the workspace root

Moving [profile.release] verbatim to the root would apply opt-level = "z"
to all five other members, including the t27c compiler that 8+ workflows
build with cargo build --release -p t27c. That silently size-optimizes the
compiler — a far bigger behavioral change than the bug.

Scoping it per-package at the root is not possible; Cargo rejects it:

error: failed to parse manifest at `<repo>/Cargo.toml`

Caused by:
  `lto` may not be specified in a `package` profile

lto, panic and rpath cannot appear in a package profile override.

The change

One line pair in the root Cargo.toml: bindings/javascript moves from
members to exclude, joining bindings/python and tools/converter which
were already excluded. The crate becomes its own workspace root, so Cargo
honours its existing [profile.release] verbatim and only for that crate.

No profile value is added, removed or tuned. The [profile.release] block
in bindings/javascript/Cargo.toml is not touched by this PR.

Acceptance test — the warning is gone

Same command, same worktree, pristine origin/master (98c44f6) vs. this
branch, stderr captured to a file and byte-counted:

$ cargo metadata --no-deps --offline --format-version 1 1>/dev/null 2>err
BEFORE exit=0 stderr_bytes=384
AFTER  exit=0 stderr_bytes=0

=== BEFORE stderr ===
warning: profiles for the non root package will be ignored, specify profiles at the workspace root:
package:   .../bindings/javascript/Cargo.toml
workspace: .../Cargo.toml
=== AFTER stderr ===
=== (end) ===

Cargo now reports the crate as its own workspace root, which is what makes the
profile apply:

$ cd bindings/javascript && cargo metadata --no-deps --offline --format-version 1 | grep -m1 workspace_root
"workspace_root":".../bindings/javascript"

Honesty limits (BINDING)

  • Binary size and build time were not measured, before or after, for either
    t27c or the .wasm. Free disk was 390 MiB and this workspace's
    target/ reaches ~1.1 GiB, so no release build was attempted. I have not
    demonstrated that the published .wasm gets smaller — only that Cargo now
    honours the profile it previously discarded. Someone with disk should run
    wasm-pack build --target bundler --release in bindings/javascript before
    and after and record both .wasm sizes.
  • Loose end from exclusion: an excluded crate no longer shares the root
    Cargo.lock, and this PR does not add one for bindings/javascript, so its
    dependencies resolve freshly at release time and it leaves workspace-wide
    cargo build/cargo test coverage from the root. Nothing in CI depended on
    either (release.yml cds into the crate; no workflow greps for a clean
    tree), but unpinned resolution for a published npm artifact is a real gap,
    recorded rather than silently accepted.

Files

  • Cargo.toml — membership only, no profile values
  • docs/NOW.md — new entry at top, Last updated: 2026-08-20, append-only
    (numstat 134 0)

bindings/javascript/Cargo.toml declares opt-level="z" and lto=true, but the
crate is a non-root workspace member, so cargo discarded both and emitted
"profiles for the non root package will be ignored" on every invocation.
release.yml publishes this crate to npm via wasm-pack, so the shipped .wasm
was built speed-optimized and without LTO.

Moving the profile to the workspace root was rejected as a fix: it would
apply opt-level="z" to all five other members including the t27c compiler.
A per-package override cannot carry lto -- cargo errors with "`lto` may not
be specified in a `package` profile".

Instead bindings/javascript moves from members to exclude, matching the
existing treatment of bindings/python and tools/converter. The crate becomes
its own workspace root, so cargo honours its profile verbatim and only there.
No profile value is changed.

Verified: cargo metadata --no-deps --offline stderr goes 384 bytes -> 0 bytes
against pristine origin/master, exit 0 both. Binary size and build time were
NOT measured (390 MiB free disk); see the Honesty limits in docs/NOW.md.

Closes #2295
@gHashTag
gHashTag enabled auto-merge (squash) August 20, 2026 04:18
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-08-20 04:23:34 UTC

Summary

Status Count
Total Open PRs 19
PRs with Failing Checks 4
PRs with All Checks Green 15
READY 7
FAILING 4
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=cbbfac87dff3 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@github-actions

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@gHashTag
gHashTag merged commit 7e8de87 into master Aug 20, 2026
27 of 49 checks passed
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.

build: workspace discards bindings/javascript [profile.release]; npm wasm ships un-optimized

2 participants