Skip to content

Remove WebAssembly format plugins and Wasmtime: built-in plugins only - #440

Merged
schmitch merged 3 commits into
mainfrom
claude/437-remove-wasm-plugins
Oct 24, 2026
Merged

schmitch merged 3 commits into
mainfrom
claude/437-remove-wasm-plugins

Conversation

@schmitch

@schmitch schmitch commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Fixes #437

Stacked on #435 (it deletes plugins/helm, which #435 keeps as the WebAssembly tests' subject). It retargets to main once #435 merges.

Format plugins loaded as WebAssembly components were too big an API to keep stable. Forge now supports only built-in plugins: crates under plugins/ that the server links in, like NuGet. This removes about 9,700 lines.

Removed

  • Runtime: forge-plugin's wasm module (Plugin::load, HostLimits, WasmPlugin, the digest pin, Origin) and the wasmtime / wasmtime-wasi dependencies. cargo tree -p forge-server has no Wasmtime any more.
  • Contract glue: forge-plugin-api's component feature, export_component!, the WIT conversion macros, wit/format.wit and forge_plugin::testing.
  • plugin.toml: the component key and the [limits] table, which are now refused as unknown keys.
  • Configuration: the [plugins] section. A config that still has it (or FORGE_PLUGINS__*) starts as before: the section is ignored like any other unknown top-level key. Also removed from .env.example and forge.toml.example.
  • Admin API: builtin and sha256 in GET /admin/formats. The web UI no longer names a format "(plugin )".
  • Server: the 64 KiB manifest-summary bound applied only to WebAssembly plugins, so it is gone too.
  • Example plugin: plugins/helm, crates/plugin/tests/component.rs and crates/server/tests/plugins.rs.
  • Tooling:
    • cargo xtask plugins and plugins-check.
    • The CI plugins job, removed from REQUIRED_JOBS in release.yml, CI_JOB_GROUP in ci-changes.sh and the required-checks list in DEVELOPMENT.md. Branch protection's required checks need plugins removed by hand.
    • The wasm32-wasip2 target in the test job.
    • The Dependabot wasmtime group.
    • The Apache-2.0 WITH LLVM-exception license in about.toml: the crates left under it also offer plain Apache-2.0 or MIT.
  • Docs: docs/format-plugins.md (loading WebAssembly plugins, the sandbox, the artifact-keeper comparison), plugins/README.md, README.md, DEVELOPMENT.md, AGENTS.md and docs/deployment.md now describe built-in plugins only.
  • Changelog: fragments for WebAssembly-only fixes (228, 229, 234) are dropped. 233 stays: its upstream-origin rule still guards NuGet proxies.

WebAssembly plugins shipped as a preview in 1.x. As agreed for 2.0, there is no upgrade note.

Kept

  • FormatPlugin and the {mount}/{repo}/… dispatcher.
  • The host's guarantees:
    • the query bounds;
    • the response-header allowlist;
    • the rule that upstream requests go only to the repository's upstream and the origins its documents name;
    • the bounded ids and versions.
  • NuGet as a built-in plugin.

Admin screen

No new admin API, only two fields removed from GET /admin/formats. The repository form follows.

Tests run locally

  • cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo clippy -p forge-e2e --features forge-e2e --tests -- -D warnings; cargo xtask changelog --check
  • cargo test -p forge-plugin -p forge-plugin-api -p forge-format-nuget -p xtask -p forge-oci; cargo test -p forge-server --lib (203, including the ignored [plugins] section)
  • cargo test -p forge-server --test plugin_contract (8), --test group_proxy (2), --test registry (32), --test browse (10), --test admin (44)
  • web: pnpm run tsc, pnpm run test (399), pnpm run build
  • Not run locally: the rest of the server integration suites, and the gated forge-e2e suite (compiled with clippy only).

🤖 Generated with Claude Code

https://claude.ai/code/session_01JpCggxduZYrAYTnobHTzhY

Format plugins loaded as WebAssembly components were too big an API to
keep: the forge:format WIT contract, the component glue, the Wasmtime
sandbox and its limits, and the configuration around them. Forge now
supports built-in plugins only, crates under plugins/ that the server
links in, like NuGet.

Gone: forge-plugin's wasm runtime (Plugin::load, HostLimits, the digest
pin), wasmtime and wasmtime-wasi, forge-plugin-api's component feature,
export_component! and wit/, the component and limits keys of
plugin.toml, the example plugin plugins/helm and its tests, `cargo xtask
plugins` and `plugins-check`, the CI `plugins` job (and its place in the
release gate), the wasm32-wasip2 target, and builtin/sha256 in
GET /admin/formats. A config that still has a [plugins] section fails
startup and says what changed. The 64 KiB summary bound applied to
WebAssembly plugins only, so it goes too.

The host contract stays covered by the native probe plugin, which now
also checks that a repository whose format is missing answers 503. The
changelog fragments that described WebAssembly-only fixes (228, 229,
234) are dropped.

Fixes #437

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JpCggxduZYrAYTnobHTzhY
Brings in main via #435. The Helm plugin's files and the WebAssembly
plugin tests stay deleted; main's #283 test there (a proxy of an
unreachable upstream answers 503) moves to group_proxy.rs with its NuGet
half. Main's new "every format lives in plugins/" text in AGENTS.md,
README.md and DEVELOPMENT.md now says plugins are linked into the
server.

A leftover [plugins] section is now ignored, like any other unknown
top-level key, rather than refused at startup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JpCggxduZYrAYTnobHTzhY
Base automatically changed from claude/43-helm-oci-only to main October 24, 2026 00:11
@schmitch
schmitch enabled auto-merge October 24, 2026 06:01

Copy link
Copy Markdown
Member Author

audit is red because of a new advisory, not because of this PR. RUSTSEC-2026-0387 was published 2026-10-23 for crypto-bigint 0.5.5 (timing variability in constant-time operations). This PR only removes dependencies, and main's Cargo.lock has the same crypto-bigint 0.5.5. So main fails cargo audit too, and so will the daily Audit run at 09:00. No fix exists in an open PR yet. I didn't re-run the job, because a known advisory fails the same way every time.

crypto-bigint comes in only through aws-sigv4's sigv4a feature (ECDSA P-256 via p256 / elliptic-curve 0.13), which the workspace turns on with aws-sdk-s3's sigv4a feature. SigV4a is only needed to sign requests to S3 Multi-Region Access Points, and nothing in Forge's code or docs uses one. Dropping the feature removes crypto-bigint, p256, ecdsa, elliptic-curve and five more crates from the lockfile:

 aws-sdk-s3 = { version = "1.85", default-features = false, features = [
-    "sigv4a",
     "http-1x",
     "default-https-client",
     "rt-tokio",
 ] }

The alternative is to ignore RUSTSEC-2026-0387 in .cargo/audit.toml with a rationale (SigV4a is only reachable with an MRAP bucket). The fix to main belongs in its own issue and PR. I've asked which way to go.


Generated by Claude Code

@schmitch
schmitch added this pull request to the merge queue Oct 24, 2026
Merged via the queue into main with commit 6c03e13 Oct 24, 2026
18 of 19 checks passed
@schmitch
schmitch deleted the claude/437-remove-wasm-plugins branch October 24, 2026 06:21
schmitch pushed a commit that referenced this pull request Oct 24, 2026
Cargo.lock conflicted: main dropped Wasmtime (#440), this branch the
SigV4a crates. Took main's lockfile and re-resolved it with cargo update
-w, which removes the same 11 crates as before and changes nothing else.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GcmkrXQyFekcS5VQgA7oGi
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.

Remove WebAssembly format plugins and wasmtime: built-in plugins only

2 participants