Conversation
CI's audit job on main (run 36787734566) fails on two advisories, published 2026-09-24, against the wasmtime that sandboxes WASM plugins: RUSTSEC-2026-0316 (GHSA-jqpg-j7w6-42pr), wasmtime 46.0.3: dynamic record lifting can allocate beyond the hostcall fuel limit RUSTSEC-2026-0314 (GHSA-j2g9-4prp-pf6h), wasmtime-wasi 46.0.3: a guest can panic the host through a filesystem datetime overflow The job runs `cargo generate-lockfile` before auditing, so the Cargo.toml requirement itself has to move. wasmtime and wasmtime-wasi go from 46.0.1 to 49.0.1, the newest patched line. A targeted `cargo update -p wasmtime -p wasmtime-wasi` moves only the wasmtime tree (wiggle, pulley, every wasmtime-internal crate, cranelift 0.136, wasm-tools 0.258). Two wasmtime-wasi 49 API changes reach build_wasi_p1: - preopened_dir takes one FsPerms instead of DirPerms + FilePerms. /project's READ + READ becomes FsPerms::ReadOnly and /plugin's all() + all() becomes FsPerms::ReadWrite. The permission check at every call site is equivalent. - TCP and UDP are now off by default (46 had them on), so inherit_network() alone would leave a network-granted plugin with no sockets. The grant now also calls allow_tcp(true) and allow_udp(true), which is the 46 configuration exactly. IP name lookup stays off. Fuel, epoch and memory limits, trap mapping and the CLI context defaults are unchanged. New tests drive real WASI preview 1 calls to pin the read-only /project and read-write /plugin grants, `..` confinement, the no-grant case and the 256 MiB memory cap. They give the same results on main's 46.0.3, and fail when the 46.0.3 sandbox is weakened. Neither advisory looks reachable from fledge's host, which runs core modules over WASI preview 1 only. The upgrade ships anyway, because the runtime is a security boundary and audit gates CI. Building from source now needs rustc 1.96 (wasmtime 49's minimum; 46 needed 1.94). Adds the CHANGELOG entry under 1.8.1 and the SpecSync change record (draft, awaiting definition approval). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3ZZAEiUP7xRJPozhZb6rL
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3ZZAEiUP7xRJPozhZb6rL
There was a problem hiding this comment.
❌ Corvin says...
_
<(;\ .oO(oh no...)
|/(\
\(\\
" "\\
"Caw... validation failed..."
CI Summary
| Check | Status |
|---|---|
| Dependency Audit | ❌ cancelled |
| Integration (3 OS) | ❌ cancelled |
| Lint (fmt + clippy) | ❌ cancelled |
| Spec Validation | ❌ cancelled |
| Tests (3 OS) | ❌ cancelled |
Powered by corvid-pet
There was a problem hiding this comment.
❌ Corvin says...
_
<(;\ .oO(oh no...)
|/(\
\(\\
" "\\
"I'm pecking through the errors..."
CI Summary
| Check | Status |
|---|---|
| Dependency Audit | ✅ Passed |
| Integration (3 OS) | ❌ skipped |
| Lint (fmt + clippy) | ✅ Passed |
| Spec Validation | ✅ Passed |
| Tests (3 OS) | ❌ failure |
Powered by corvid-pet
…needs test (windows-latest) failed to compile on #538's first run: error[E0432]: unresolved import `windows_sys::Win32::System::JobObjects::CreateJobObjectW` --> src\lanes\execute.rs:659:76 windows-sys 0.59 compiles CreateJobObjectW only with the Win32_Security feature, because its first parameter is a SECURITY_ATTRIBUTES pointer. fledge declares only Win32_Foundation and Win32_System_JobObjects. On main the missing feature arrived through feature unification: cap-primitives 3.4.6, under wasmtime-wasi 46's cap-std, enables Win32_Security on windows-sys 0.59. wasmtime-wasi 49 dropped cap-std, so nothing turns it on any more. With --no-default-features, main had no Win32_Security edge at all, so a Windows build without the wasm feature was already broken. Declare the feature fledge uses. It is a feature flag only: no new crate and no Cargo.lock change. The CHANGELOG entry and the change record say so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3ZZAEiUP7xRJPozhZb6rL
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8ce1c85f00
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| wasmtime = { version = "49.0.1", optional = true } | ||
| wasmtime-wasi = { version = "49.0.1", optional = true } |
There was a problem hiding this comment.
Raise the declared Rust version with Wasmtime
Wasmtime 49 requires Rust 1.96, but this crate still declares rust-version = "1.89" and enables the Wasmtime dependencies by default. Consequently, users on Rust 1.94 or 1.95—both of which could build the previous Wasmtime 46 dependency—will select this release based on its manifest and then fail during dependency resolution or compilation. Update the package's rust-version to 1.96 (and any associated toolchain metadata) so the published compatibility contract matches the new default dependency floor.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
✅ Corvin says...
_
<(^\ .oO(Caw! ^v^)
|/(\
\(\\
" "\\
"Caw! Your code sparkles like a dropped french fry."
CI Summary
| Check | Status |
|---|---|
| Dependency Audit | ✅ Passed |
| Integration (3 OS) | ✅ Passed |
| Lint (fmt + clippy) | ✅ Passed |
| Spec Validation | ✅ Passed |
| Tests (3 OS) | ✅ Passed |
Powered by corvid-pet
create_engine took wasmtime's default feature set. wasmtime 47 turned the GC, exception-handling and typed function references proposals on by default, and 49 added wide arithmetic, so the 46.0.3 to 49.0.1 upgrade alone let a plugin load modules that 46.0.3 rejected at compile time. Probe modules for each proposal are refused on main and accepted on 8ce1c85. Turn all four off explicitly. No plugin that ran on 1.8.0 can depend on them, and wasm32-wasip1 toolchains do not emit them by default. They are not free surface: RUSTSEC-2026-0315, fixed in the same 49.0.1 release, let call_ref and exception catch drop fuel accounting. engine_keeps_wasmtime_46_feature_set compiles a baseline module (bulk memory, sign extension, saturating truncation, multi-value, reference types, tail calls) and asserts one module per proposal is refused. It passes unchanged on main's 46.0.3, each refused module compiles under 49.0.1's defaults, and the test fails when the four calls are removed. The CHANGELOG entry and the draft change record (rationale, acceptance criteria, context, design, testing, tasks) say so. The record also notes a pre-existing gap left alone: StoreLimits sets no table_elements limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3ZZAEiUP7xRJPozhZb6rL
There was a problem hiding this comment.
✅ Corvin says...
_
<(^\ .oO(Caw! ^v^)
|/(\
\(\\
" "\\
"Caw! Found a shiny new spec!"
CI Summary
| Check | Status |
|---|---|
| Dependency Audit | ✅ Passed |
| Integration (3 OS) | ✅ Passed |
| Lint (fmt + clippy) | ✅ Passed |
| Spec Validation | ✅ Passed |
| Tests (3 OS) | ✅ Passed |
Powered by corvid-pet
…ask list Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3ZZAEiUP7xRJPozhZb6rL
There was a problem hiding this comment.
✅ Corvin says...
_
<(^\ .oO(Caw! ^v^)
|/(\
\(\\
" "\\
"Caw! Found a shiny new spec!"
CI Summary
| Check | Status |
|---|---|
| Dependency Audit | ✅ Passed |
| Integration (3 OS) | ✅ Passed |
| Lint (fmt + clippy) | ✅ Passed |
| Spec Validation | ✅ Passed |
| Tests (3 OS) | ✅ Passed |
Powered by corvid-pet
…dbox contract `specsync change ship` refused the no-spec draft because src/plugin/wasm.rs is production source and no declared module owned it. The change now declares plugin-wasm (no_spec_change false) and carries a delta: REQ-plugin-wasm-001 to 006 for the sandbox contract, plus the five spec sentences they contradict. testing.md maps each requirement to its evidence. The change stays a draft. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3ZZAEiUP7xRJPozhZb6rL
There was a problem hiding this comment.
✅ Corvin says...
_
<(^\ .oO(Caw! ^v^)
|/(\
\(\\
" "\\
"Caw! Found a shiny new spec!"
CI Summary
| Check | Status |
|---|---|
| Dependency Audit | ✅ Passed |
| Integration (3 OS) | ✅ Passed |
| Lint (fmt + clippy) | ✅ Passed |
| Spec Validation | ✅ Passed |
| Tests (3 OS) | ✅ Passed |
Powered by corvid-pet
Summary
auditjob onmainfails on two advisories against the wasmtime that sandboxes WASM plugins: RUSTSEC-2026-0316 (wasmtime 46.0.3, GHSA-jqpg-j7w6-42pr, dynamic record lifting can allocate beyond the hostcall fuel limit) and RUSTSEC-2026-0314 (wasmtime-wasi 46.0.3, GHSA-j2g9-4prp-pf6h, a guest can panic the host through a filesystem datetime overflow).cargo generate-lockfile, so theCargo.tomlrequirement has to move.wasmtimeandwasmtime-wasigo from46.0.1to49.0.1, the newest patched line. A targetedcargo update -p wasmtime -p wasmtime-wasimoves only the wasmtime tree: wiggle, pulley and everywasmtime-internal-*to 49.0.1, cranelift to 0.136.1, wasm-tools to 0.258,cap-stdreplaced by cap-primitives 4, andtoml1.1 insidewasmtime-internal-cacheonly.build_wasi_p1. Both are ported so the sandbox behaves exactly as before:preopened_dirtakes oneFsPermsinstead ofDirPerms+FilePerms./project(READ+READ) becomesFsPerms::ReadOnly;/plugin(all()+all()) becomesFsPerms::ReadWrite.inherit_network()alone no longer grants sockets. Anetworkgrant now also callsallow_tcp(true)andallow_udp(true), which is the 46 configuration exactly. IP name lookup stays off, and plugins without the grant keep sockets off.StoreLimits, theTrap::OutOfFuelandTrap::Interrupterror mapping, and the env/args/stdin/stderr defaults. The.cwasmcache stamp follows the requirement string, so each installed plugin recompiles once on its next run.src/plugin/wasm.rsmake real WASI preview 1 calls to pin/projectread-only,/pluginread-write,..confinement, no preopens without a grant, and the memory cap. They pass unchanged on main's 46.0.3 with the same errno values. Five of them fail when the 46.0.3 sandbox is weakened (/projectmade writable, memory limiter removed).windows-sysWin32_Securityfeature, whichCreateJobObjectWinsrc/lanes/execute.rsneeds. The feature had only ever arrived through feature unification from wasmtime-wasi 46'scap-std(cap-primitives3.4.6). 49 droppedcap-std, and this PR's firsttest (windows-latest)run failed to compile. Main's--no-default-featuresWindows build already lacked the feature. This adds a feature flag only, with no new crate and noCargo.lockchange.ValAPI. Preview 1 cannot form the 0314 overflow: a preview 1 guest passing extreme timestamps to 46.0.3 returned normally. The upgrade ships anyway, because the plugin runtime is a security boundary and audit gates CI.stable. Therust-version = "1.89"inCargo.tomlwas already below what 46 needed. It is left alone here; the change record's context explains why.create_enginenever set features itself, so the upgrade would have widened what a plugin can run. The engine now pins wasmtime 46's feature set. The new testengine_keeps_wasmtime_46_feature_setchecks that a baseline module compiles and that each of the four proposals is refused. It passes on main's 46.0.3, and it fails if the pins are removed.StoreLimitssets no table-element limit, so a plugin can grow a table far past the 256 MiB memory cap (same on 46 and 49).upgrade-wasmtime-past-rustsec-2026-0316-and-rustsec-2026-0314(bug fix, no canonical spec change). Definition approval is pending with orc/Leif. Nothing is approved, reviewed or shipped in this PR.Test Plan
cargo fmt --checkcargo clippy --locked -- -D warnings,cargo clippy --all-targets -- -D warningsandcargo clippy --locked --no-default-features -- -D warnings(rustc 1.98.0, macOS)cargo test --verbose --locked: 1097 unit tests (including the feature-set test) and every integration test binary passcargo auditagainst advisory DB9b3a3b7, the commit CI used: the branch lock and a freshgenerate-lockfileboth report 0 vulnerabilities, and main's lock still reports both (negative control)specsync check --force --strict --require-coverage 100,specsync lifecycle enforce --all,specsync change check --strict --require-coverage 100fledge trust verifycargo deny: not applicable, the repository has nodeny.tomlcargo tree --target x86_64-pc-windows-msvc -e features:Win32_Securityonwindows-sys0.59 now comes from fledge, with and without default features (no Windows target locally, so CI's windows cells are the compile check)🤖 Generated with Claude Code
https://claude.ai/code/session_01V3ZZAEiUP7xRJPozhZb6rL