Skip to content

Upgrade to Rust 1.98.1 and align dependencies with EdgeZero - #1123

Merged
aram356 merged 19 commits into
mainfrom
chore/upgrade-rust-198-deps
Oct 22, 2026
Merged

aram356 merged 19 commits into
mainfrom
chore/upgrade-rust-198-deps

Conversation

@aram356

@aram356 aram356 commented Sep 6, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Aligns the toolchain and shared dependency pins with EdgeZero PR stackpop/edgezero#366, so both workspaces resolve the same major versions instead of fighting each other.

The Fastly adapter does not build on this branch. That is a single external blocker, tracked in #1122 and detailed at the bottom. Everything else — core, Axum, Cloudflare, Spin, CLI — compiles, lints and tests clean.

Toolchain

Tool From To
Rust 1.95.0 1.98.1
Node 24.12.0 24.20.0
Fastly CLI 15.1.0 16.0.0
Viceroy 0.17.0 0.21.0
wasmtime 44.0.1 48.0.1

CI derives every one of these from .tool-versions, so only that file and rust-toolchain.toml pin them — no workflow changes needed.

EdgeZero

Pinned to tag = "v0.0.10". Earlier revisions of this branch carried a revision pin on the head of #366, because no release yet contained the majors below. v0.0.10 does (fastly 0.13, sha2 0.11, spin-sdk ~7.0, validator 0.21), so the pin is a clean tag again and the comment explaining the workaround is gone.

Note that main pins v0.0.9, which does not carry them; this PR moves one release ahead rather than reverting to main's tag. The git URLs are IABTechLab/edgezero, following main's org move (#1323); v0.0.10 exists there at the same commit (85d933b8044d) the old stackpop tag pointed to.

Dependency majors

Matched to #366: fastly and log-fastly 0.12 → 0.13, spin-sdk ~6.0 → ~7.0, validator 0.20 → 0.21, sha2 0.10 → 0.11.

brotli stays at 8, for the reason #366 records and measures: async-compression still resolves brotli 8, so taking 9 on the direct dependency adds a second decompressor stack rather than replacing one.

Two further majors this workspace needs but #366 did not. sha2 0.11 moves RustCrypto to hybrid_array, and the ecosystem has to cross together: hmac 0.12 → 0.13 and chacha20poly1305 0.10 → 0.11. Without them, XChaCha20Poly1305::new receives an Array where it expects a GenericArray.

Source changes — six lines, no lint suppressions

Every fix addresses the actual API change. Nothing is silenced with #[allow].

  • new_from_slice moved from Mac to KeyInit in hmac 0.13 — ec/generation.rs, s3_sigv4.rs and ec/pull_sync_marker.rs bring the trait into scope with as _. (The third arrived on main after this branch was cut and surfaced in the merge.)
  • Array does not implement LowerHex as GenericArray did — settings_data.rs formats via hex::encode. (hex is already a dependency, already used for exactly this nearby. Hand-rolling hex is a trap: it trips indexing_slicing, then as-truncation, then arithmetic_side_effects in turn.)
  • Array::from_slice is deprecated in favour of TryFrom, which is an error under -D warnings. In http_util.rs the encode path builds a fixed [u8; 24] and converts infallibly via From; the decode path takes a runtime slice and uses TryFrom, returning None on a mismatch to match the function's existing Option contract — replacing a path that would previously have panicked.
  • Rust 1.98 flags two redundant imports — publisher.rs (std::io::Write) and cli/src/run.rs (clap::Parser) each import the trait at file scope, and the test module's use super::* already brings it in, so the module's own as _ copy is unused. Confirmed new to the toolchain rather than pre-existing: clippy on main under 1.95 is clean against the identical pairs.

chacha20poly1305 default features

sha2 0.11 pulls crypto-common 0.2, which declares an optional getrandom 0.4 dependency. The only thing enabling it is chacha20poly1305's own default getrandom feature (→ aead/getrandom → crypto-common/getrandom), which on wasm32-unknown-unknown is a hard compile_error!.

Rather than configure that crate, this disables the default: chacha20poly1305 = { version = "0.11", default-features = false, features = ["alloc"] }. The XChaCha nonce here is derived from SHA-256 for stable tokens and never drawn from the AEAD's RNG, so the feature was unused. cargo tree -i getrandom@0.4.3 on the Cloudflare target now reports nothing.

Verified the ciphertext does not move: a scratch crate encrypting a fixed URL with a fixed secret produces identical bytes with the default features on and off, so persisted proxy URL tokens stay valid.

Behaviour is unchanged, and this was verified rather than assumed

hmac 0.13 could plausibly have changed digests for keys shorter than the block size — which would silently invalidate every persisted EC ID and S3 SigV4 signature. Built scratch crates against both versions and compared:

0.12  short key (18 bytes): 6de2581fb61f36512e7d6f6f848a5f45586cc0502f5959302be94168ca2891d8
0.13  short key (18 bytes): 6de2581fb61f36512e7d6f6f848a5f45586cc0502f5959302be94168ca2891d8
0.12  block-length (64):    54be2c66676012b3a6c28720fd9ad115e0634b75407fcebcb9225f9dfd951f4a
0.13  block-length (64):    54be2c66676012b3a6c28720fd9ad115e0634b75407fcebcb9225f9dfd951f4a

Byte-identical. Existing identities remain valid.

Documentation

Viceroy install command updated to 0.21.0 in the getting-started, testing and error-reference guides, and three scripts that name it in their prerequisites.

The getting-started prerequisites keep their {{RUST_VERSION}} and {{NODEJS_VERSION}} placeholders. docs/.vitepress/config.mts installs a markdown hook that reads .tool-versions and substitutes {{<TOOL>_VERSION}} for every tool listed there, so those lines track the pins automatically and need no edit. Verified against a real npm run build: the rendered HTML reads "Rust 1.98.1", "NodeJS 24.20.0" and "Fastly 16.0.0".

docs/superpowers/** keeps its 1.95 and 0.17.0 mentions: dated design records describing the stack as it stood when each was written. Same exclusion #366 made.

The blocker: esi pins fastly ^0.12 (#1122)

esi 0.7.2 declares fastly = "^0.12" while EdgeZero requires 0.13. Both land in trusted-server-adapter-fastly, and esi_assembly.rs passes fastly::http::Response/Request across that boundary, so it sees two incompatible copies of the same types. ESI is unconditional there, not feature-gated.

The fix is one line and needs no source changes to esi. Cloning fastly/esi at v0.7.2 and changing only the manifest range to ^0.13 compiles clean, and with that patched in locally the entire workspace builds, Fastly adapter included.

Upstream main still reads ^0.12, and no open PR addresses it — fastly/esi#60 is the v0.7.2 release bump, touching only the workspace version and lockfile. #1122 lays out the two paths (upstream PR and wait, or carry it on the existing stackpop/esi fork behind [patch.crates-io]).

Closes

Closes #1124

Depends on #1122 for the temporary esi patch — that one stays open until the range bump is released upstream and the patch can be dropped.

Test plan

Verified on rustc 1.98.1, Node 24.20.0, Viceroy 0.21.0:

  • cargo fmt --all -- --check
  • cargo clippy-axum, clippy-cloudflare, clippy-cloudflare-wasm, clippy-spin-native, clippy-spin-wasm — all clean under -D warnings
  • cargo test-axum — 38 passed
  • cargo test-cloudflare — 40 passed
  • cargo test-spin — 80 passed
  • cargo test --package trusted-server-cli --target aarch64-apple-darwin — 209 passed, plus clippy --all-targets -D warnings
  • JS: 893 tests across 45 files, plus npm run format
  • Docs: npm run format
  • HMAC output compared byte-for-byte between 0.12 and 0.13 (above)

All gates run unconditionally now that the esi patch is committed:

  • cargo clippy-fastly — clean under -D warnings
  • cargo test-fastly — 221 adapter + 2944 core + 10 js + 10 + 21 openrtb + 4 doctests
  • cargo test-fastly-reuse — 221
  • cargo clippy-cli and cargo clippy-codegen — clean

CI: all 23 checks green, including the integration, browser and Fastly EC lifecycle suites.

Review notes

The [patch.crates-io] esi entry is the one piece of unusual wiring, and #1122 carries the context for removing it.

Match the toolchain and shared dependency pins to EdgeZero PR #366 so
both workspaces resolve the same major versions.

Toolchain: Rust 1.95.0 to 1.98.1, Node 24.12.0 to 24.20.0, Fastly CLI
15.1.0 to 16.0.0, Viceroy 0.17.0 to 0.21.0, wasmtime 44.0.1 to 48.0.1.
CI derives each from `.tool-versions`, so only that file and
`rust-toolchain.toml` pin them.

EdgeZero moves from tag v0.0.7 to the PR #366 head revision. The latest
tag, v0.0.8, still carries the 1.95 toolchain and the previous majors,
so it would contradict the pins below. Restore a tag once #366 merges.

Shared majors: fastly and log-fastly 0.12 to 0.13, spin-sdk ~6.0 to
~7.0, validator 0.20 to 0.21, sha2 0.10 to 0.11. brotli stays at 8 for
the reason recorded in #366: async-compression still resolves 8, so
taking 9 adds a second decompressor stack rather than replacing one.

sha2 0.11 moves RustCrypto to `hybrid_array`, which forces two further
majors this workspace needs but #366 did not: hmac 0.12 to 0.13 and
chacha20poly1305 0.10 to 0.11. Their fallout is three lines:

- `new_from_slice` moved from `Mac` to `KeyInit`, so `ec/generation.rs`
  and `s3_sigv4.rs` bring that trait into scope. HMAC output is
  unchanged, verified byte-for-byte against 0.12 for both a short key
  and a block-length key, so persisted EC IDs and SigV4 signatures stay
  valid.
- `Array` does not implement `LowerHex` as `GenericArray` did, so
  `settings_data.rs` formats via `hex::encode`.

sha2 0.11 also pulls crypto-common 0.2, which depends on getrandom 0.4.
That line renamed the browser RNG feature from `js` to `wasm_js`, so
the Cloudflare target needs a second getrandom entry to enable it.

The Fastly adapter does not build on this branch: `esi` 0.7.2 pins
fastly ^0.12 while EdgeZero requires 0.13, and both meet in
`esi_assembly.rs`. Upstream `fastly/esi` main is still on ^0.12.
Point the Viceroy install command at 0.21.0 in the getting-started,
testing and error-reference guides, the integration-tests README, and
the three scripts that name it in their prerequisites.

Fill in the Rust and NodeJS versions in the getting-started
prerequisites. Both were `{{RUST_VERSION}}` / `{{NODEJS_VERSION}}`
placeholders with no substitution step anywhere in the repo, so the
published page rendered the braces literally.

`docs/superpowers/**` keeps its 1.95 and 0.17.0 mentions: those are
dated design records describing the stack as it stood when each was
written.
`hybrid_array` deprecates `from_slice` in favour of `TryFrom`, which is
an error under the workspace's `-D warnings` clippy gate.

The encode path builds a fixed `[u8; 24]`, so it converts infallibly
via `XNonce::from`. The decode path takes a runtime slice, so it uses
`XNonce::try_from` and returns `None` on a mismatch, matching the
function's existing `Option` contract; the preceding length check
already guarantees 24 bytes, so this is unreachable in practice and
replaces a path that would previously have panicked.

Both conversions yield an owned `XNonce` where `from_slice` yielded a
reference, so the three use sites borrow explicitly.
@aram356 aram356 added dependencies Pull requests that update a dependency file rust Pull requests that update rust code edgezero and removed dependencies Pull requests that update a dependency file rust Pull requests that update rust code edgezero labels Sep 6, 2026
@aram356
aram356 marked this pull request as draft September 7, 2026 00:04
@aram356 aram356 self-assigned this Sep 7, 2026
`publisher.rs` imports `std::io::Write` at file scope, and the test
module's `use super::*` already brings it in, so the module's own
`Write as _` is redundant. Rust 1.98 reports it as an unused import,
which is an error under the workspace's `-D warnings` gate.

Confirmed new to the toolchain rather than pre-existing: clippy on
`main` under 1.95 is clean against the identical pair of imports.
`run.rs` imports `Parser` at file scope, and the test module's
`use super::*` already brings it in, so the module's own
`Parser as _` is redundant. Same shape as the `publisher.rs` case:
new under Rust 1.98, and an error under `-D warnings`.

Missed in the first local pass because `cargo check` on the CLI runs
neither `--all-targets` nor `-D warnings`; CI's clippy does both.
@aram356

aram356 commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

CI status after the two Rust 1.98 unused-import fixes.

Passing: cross-adapter parity, cloudflare (native + wasm32-unknown-unknown), spin (native + wasm32-wasip1), ts CLI (native), vitest, format-typescript, format-docs, CodeQL.

Failing — all four for the same reason: cargo fmt (the job also runs cargo clippy-fastly), cargo test, cargo test (axum native) (the job also runs the Fastly WASM release build), and prepare integration artifacts.

Each fails with the same two errors at the same two lines:

error[E0308]: mismatched types
   --> crates/trusted-server-adapter-fastly/src/esi_assembly.rs:96:9
error[E0631]: type mismatch in closure arguments
   --> crates/trusted-server-adapter-fastly/src/esi_assembly.rs:124:65

That is #1122 and nothing else — no other failure mode appears in any of the four logs. Every job that does not build the Fastly adapter is green.

Locally, with esi patched to fastly = "^0.13" (no source change to esi), cargo clippy-fastly is clean and cargo test-fastly passes 166 adapter + 2290 core + 2 js + 21 openrtb + 3 doctests. So these four go green the moment #1122 lands.

`esi` 0.7.2 pins `fastly = "^0.12"` while EdgeZero requires 0.13. Both
land in `trusted-server-adapter-fastly`, and `esi_assembly.rs` passes
`fastly::Request` and `Response` across that boundary, so the two
copies meet and the adapter fails to compile.

The fork changes only the version ranges, in the library and the six
examples that pin `fastly` themselves. No source changes: the crate
compiles and its suite passes unmodified against 0.13.

`fastly` 0.12 now drops out of the graph entirely, leaving one copy.

Temporary. Drop this patch once the range bump is released upstream;
tracked in #1122.
@aram356

aram356 commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

All CI checks pass with the esi patch in place.

Every job that was failing on the esi type conflict is now green: cargo fmt (which also runs clippy-fastly), cargo test, cargo test (axum native) (which also builds the Fastly WASM release), and prepare integration artifacts. The integration test jobs, which previously skipped because no artifacts were produced, now run.

The patch points at stackpop/esi@75bfbb396, branched from upstream v0.7.2. It changes only version ranges — the library plus the six examples that pin fastly themselves — with no source changes. esi's own suite passes against 0.13: 163 tests, 0 failed, under Viceroy 0.21.0.

fastly 0.12 is gone from the graph; one copy remains.

The patch is temporary and commented as such. It should be dropped once the range bump is released upstream — #1122 tracks that.

`{{RUST_VERSION}}` and `{{NODEJS_VERSION}}` were replaced with literal
versions on the mistaken belief that nothing substituted them. VitePress
does: `docs/.vitepress/config.mts` installs a markdown hook that reads
`.tool-versions` and replaces `{{<TOOL>_VERSION}}` for every tool listed
there. `{{FASTLY_VERSION}}`, four lines below in the same file, was
already relying on it.

Hardcoding the numbers dropped the guide out of that mechanism, so it
would have silently gone stale at the next toolchain bump. The
placeholders now resolve from the versions updated earlier in this
branch; verified against a real `npm run build`, whose rendered HTML
reads "Rust 1.98.1", "NodeJS 24.20.0" and "Fastly 16.0.0" with no
placeholder left unsubstituted.
Three conflicts, resolved as follows.

`CLAUDE.md` — main made it a symlink to `AGENTS.md` (#923) while this
branch still edited it as a regular file. Took main's symlink and moved
the toolchain-table, Viceroy-install and `rust-toolchain.toml` version
edits into `AGENTS.md`, which is now the real file.

`Cargo.toml` — main moved EdgeZero from tag v0.0.7 to v0.0.8; this
branch pins the head of EdgeZero PR #366. Kept the revision pin, because
v0.0.8 still carries fastly 0.12, sha2 0.10, spin-sdk ~6.0 and validator
0.20, so taking main's side would have undone every major this branch
exists to land. Verified against the published tag rather than assumed.
Refreshed the pin to #366's current head, 9ba4eae7b, which had moved on
since 40c52e3f; the one new commit adds a Spin 4.1 floor and a migration
doc, no dependency changes. Main's new `cssparser` entry is preserved.

`Cargo.lock` — regenerated from the resolved manifest. Resolves to a
single fastly 0.13.1 with the new majors intact and the esi fork patch
still in place.

Verified on the merged tree: all six clippy targets clean under
`-D warnings`, `cargo fmt` clean, test-fastly (191 adapter + 2661 core +
2 js + 21 openrtb + 3 doctests), test-axum, test-cloudflare, test-spin,
parity (13), CLI (212), 901 JS tests, and both format gates.
A merge of main was pushed to this branch from the GitHub web UI while
the local merge was under test. Merging it in rather than force-pushing
over it keeps that commit in the history.

That merge was made against 640e93d, an older main tip, so it predates
the eight commits that landed after it, #923 among them. Merging it into
the local merge, which is against current main, is what brings the
branch up to date; taking it alone would have left the PR conflicting.

Where the two resolutions differ, this keeps the local one: `CLAUDE.md`
stays the symlink to `AGENTS.md` that #923 introduced, with the version
edits in `AGENTS.md`, and `cssparser` from #1106 stays in the manifest.
Both were lost in the web-UI resolution because the commits that
introduced them were not in its base.

Re-verified after the merge: fmt and clippy-fastly clean, test-fastly
(191 + 2661 + 2 + 21 + 3), test-axum, test-cloudflare, test-spin.
EdgeZero v0.0.10 carries the majors this branch exists to land (fastly
0.13, sha2 0.11, spin-sdk ~7.0, validator 0.21), so the revision pin on
PR #366 is no longer needed. All six crates move to the tag and the
comment explaining why a tag would not work is gone with it.

Six conflicts, resolved as follows.

`.tool-versions` and the `AGENTS.md` toolchain table - main added AWS
CLI and Terraform entries and reflowed both tables. Kept main's
structure and rows, carried this branch's upgraded versions into them.

`Cargo.toml` - took v0.0.10 over main's v0.0.9. In the second hunk main
added `serde_yaml_ng` and `similar` adjacent to the `sha2` line; kept
both and held sha2 at 0.11. Verified that every dependency main added
since the merge base survives: assert_cmd, gix, predicates, rpassword,
tracing, serde_yaml_ng, similar.

`crates/trusted-server-integration-tests/README.md` - main rewrote the
section as "Test surfaces" and dropped the prerequisites list, whose
only stake here was a Viceroy version string that no longer appears.
Took main's rewrite whole.

`docs/guide/testing.md` - main trimmed the comments and added a `rustup
target add` line. Kept main's shape with the new Viceroy version; the
prose above it already states the requirement.

`Cargo.lock` - regenerated. Resolves to a single fastly 0.13.1 with the
new majors intact and the esi fork patch still in place: esi 0.7.2 is
still the newest published version and still pins fastly ^0.12, so
issue #1122 stays open.

One source fix. `ec/pull_sync_marker.rs`, added to main after this
branch was cut, calls `HmacSha256::new_from_slice`, which hmac 0.13
moved from `Mac` to `KeyInit`. Imported the trait as `KeyInit as _`,
matching the two sites already fixed here and the file's own style.

Verified on the merged tree: all eight clippy targets clean under
`-D warnings` (including the new clippy-cli and clippy-codegen), fmt
clean, test-fastly (221 adapter + 2944 core + 10 js + 10 + 21 openrtb +
4 doctests), test-fastly-reuse (221), test-axum, test-cloudflare,
test-spin, parity (17), CLI (858), 1211 JS tests across 50 files, the JS
and docs format gates, and the markdown gate outside docs/.
@aram356
aram356 requested review from ChristianPavilonis, dhruv8sh and prk-Jr and removed request for dhruv8sh and prk-Jr October 16, 2026 00:59
@aram356
aram356 marked this pull request as ready for review October 16, 2026 00:59
@aram356 aram356 added this to the 202610 milestone Oct 16, 2026

@ChristianPavilonis ChristianPavilonis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please declare and enforce the Spin 4.1+ runtime minimum introduced by the SDK 7 upgrade. Components built with this SDK cannot start on Spin 4.0.x because it cannot link wasi:http/types@0.3.0.

Document the prerequisite in the Spin guide and add a version preflight to the smoke script so unsupported runtimes fail with a clear message.

Comment thread Cargo.toml
@aram356
aram356 requested review from dhruv8sh and prk-Jr October 16, 2026 05:35
`spin-sdk` 7 imports `wasi:http/types@0.3.0`, which Spin 4.0.x does not
provide, so the SDK upgrade in this branch makes the component
unstartable on those runtimes. Nothing in the build catches it: the
component compiles, `cargo test-spin` passes, and only `spin up` fails,
reporting an unresolved import against the linker.

`scripts/smoke-common.sh` gains `smoke_require_spin_version`, which
parses `spin --version` and refuses anything below 4.1.0 with a message
naming the found version, the reason, and the install URL. It fails
closed when the version cannot be parsed or `spin --version` does not
run, so a broken toolchain cannot look like a pass. Comparison uses
`sort -V`, so 4.10.0 orders above 4.1.0 as it should. The smoke calls it
after the existing command checks, before building or starting the app.

`docs/guide/spin.md` gains a prerequisites section carrying the
requirement, the linker error it otherwise produces, and the note that
the smoke now catches it. The "With the Spin CLI installed" line that
opens the verification section now names the version.

No `.tool-versions` entry. asdf has no first-party Spin plugin, so a pin
would make `asdf install` fail until every developer added a third-party
one, and CI never installs or runs the Spin runtime (`test-spin` only
checks, builds and tests). The preflight enforces the floor where the
runtime is actually used.

Verified: the gate accepts 4.1.0, 4.10.0, 5.0.0 and 10.0.0, rejects
4.0.0, 4.0.3 and 3.9.9, and fails closed on unparseable output and a
non-zero exit. shellcheck clean on both scripts. Running the real
`./scripts/smoke-spin.sh` passes the preflight against the local Spin
4.1.0 and proceeds to build and launch; it then fails on an app-config
diagnostic assertion that fails identically on `main` at fa9837f, so
that failure is pre-existing and unrelated to this change.
Adds `spin 4.1.0` to `.tool-versions` and makes the smoke preflight read
its minimum from that line instead of hardcoding one, so the pin and the
check cannot drift. A missing `spin` entry now fails closed rather than
silently skipping the gate.

Every consumer of `.tool-versions` looks up one tool at a time, with
`awk '$1 == "..."'` or `grep '^<tool> '`, so the new line is inert to
the workflows and scripts that read the file; the helper uses the same
awk form. CI never calls `asdf install`, so an entry asdf cannot resolve
does not break it.

That resolution gap is real, though: asdf has no first-party Spin
plugin, so `asdf install` will not provide this one. The Spin guide now
says so, and points at the install guide or a community plugin. The pin
records the required version and is what the smoke checks against.

Also adds the Spin row to the `AGENTS.md` toolchain table, which lists
the other pinned tools.

Verified: the helper resolves the pin from any working directory via
`BASH_SOURCE`; bumping the pin to 9.9.9 in a scratch copy rejects the
local Spin 4.1.0, and deleting the line reports the missing pin, so the
file genuinely drives the floor. The version gate is unchanged, still
accepting 4.1.0, 4.10.0 and 10.0.0 and rejecting 4.0.3 and 3.9.9.
shellcheck clean, `cargo check-spin` clean, `cargo test-spin` 88 tests
passing, both markdown format gates clean.
@aram356

aram356 commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

CI status at 5c850c6: 20 passing, 1 failing. The failure is external to this branch.

prepare integration artifacts fails installing worker-build:

failed to select a version for the requirement `zip = "^2.1.3"`
  version 2.1.3 is yanked ... version 2.6.1 is yanked
required by package `binary-install v0.4.1`
    ... which satisfies dependency `binary-install = "^0.4.1"` of package `worker-build`

The zip maintainers yanked every release from 2.x through 9.0.2; only 9.0.3 (published 2026-10-13) remains. worker-build reaches zip ^2 through binary-install ^0.4.1, so cargo install worker-build cannot resolve at all right now.

Evidence that this is not from this branch:

  • Reproduced outside the repository: cargo install worker-build --root ./probe in an empty scratch directory fails the same way, on worker-build 0.8.7.
  • main resolves worker 0.8.5 in Cargo.lock, exactly as this branch does. crates/trusted-server-adapter-cloudflare/build.sh derives the worker-build version from that, so both get the same broken install.
  • Upgrading does not escape it: the newest worker-build 0.8.7 still depends on binary-install ^0.4.1.
  • main's last green run was 2026-10-15 16:28, before the yank took effect. Any PR that runs this job today will fail the same way, and main will too on its next run.

I have not tried to fix it here. It needs either a worker-build release that moves off binary-install ^0.4.1, or a pin/vendor workaround in build.sh plus a cargo update, and that belongs in its own change rather than inside a toolchain upgrade. Happy to open an issue, or to take it on separately if you would rather unblock this PR directly.

Everything else is green, including both Spin jobs and the CLI on macOS and Ubuntu.

The Cloudflare bundle step installs `worker-build` without `--locked`,
so Cargo re-resolves its whole dependency tree on every install. That
tree is not resolvable: `worker-build` depends on `binary-install`
0.4.1, which requires `zip ^2.1.3`, and the entire `zip` 2.x line is
yanked. `binary-install` 0.4.1 is still the newest release, and the
current `worker-build` 0.8.7 depends on it too, so there is no version
pair to upgrade to.

This surfaced now rather than in May 2025, when `zip` 2.6.1 was yanked,
because a warm Cargo index kept serving a resolvable answer. Yanking
`zip` 9.0.2 on 2026-10-16 at 03:33Z refreshed the index, and the next
fresh resolve failed. Runs from 21:27Z the previous evening passed on
the stale index, which is why other open PRs look unaffected.

`--locked` installs against the lockfile `worker-build` publishes, which
pins a working `zip`, so upstream yanks in versions it never selected
cannot break the install. Verified both directions with the exact
command the step runs: `cargo install -q --force --version "=0.8.5"
--locked worker-build` succeeds, and the same command without `--locked`
fails on the yanked `zip` versions. Matches the `--locked` already used
for the Viceroy install in the same workflow.
@aram356

aram356 commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

Correcting my previous comment, and fixing the failure in b17d64b.

What I got wrong. I said the zip yank was a fresh cascade that would break every PR today. The yank is not new: zip 2.6.1 was yanked in May 2025, and the whole 2.x line has been unresolvable since. Eight other open PRs pass this same job, which contradicted my explanation.

What is actually happening. crates/trusted-server-adapter-cloudflare/build.sh installs worker-build without --locked, so Cargo re-resolves its entire dependency tree every time. That tree cannot resolve: worker-build needs binary-install 0.4.1, which needs zip ^2.1.3. A warm Cargo index was serving a resolvable answer anyway. Yanking zip 9.0.2 at 2026-10-16T03:33Z refreshed the index, and the next fresh resolve failed. The passing runs on other PRs started 21:27Z the evening before, on the stale index; ours started 05:49Z, after.

So this was a latent breakage in the install command, not something this branch introduced, and not a new upstream event. It will hit main and every other PR on their next cache-cold run.

The fix is one flag: --locked, which installs against the lockfile worker-build publishes (pinning a working zip) instead of re-resolving. Verified both directions with the exact command the step runs:

cargo install -q --force --version "=0.8.5" --locked worker-build   → exit 0
cargo install -q --force --version "=0.8.5"          worker-build   → error: version 2.1.3 is yanked ...

No version changes and no vendoring, and it matches the --locked already used for the Viceroy install in the same workflow. Upgrading would not have helped: binary-install 0.4.1 is still the newest release and the current worker-build 0.8.7 depends on it too.

@dhruv8sh dhruv8sh left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Toolchain bump to Rust 1.98.1 plus the dependency majors aligned with EdgeZero v0.0.10. The source changes address the actual API breaks with no lint suppressions, the esi fork patch is a minimal range bump, and CI is fully green. Approving; the comments below are non-blocking.

1 of the inline comments below carries a one-click GitHub suggestion — use Commit suggestion to apply it. The remaining comments describe changes in prose because they touch Cargo.lock or a second manifest and can't be auto-applied.

Non-blocking

  • ♻️ Drop the getrandom_04 wiring by disabling chacha20poly1305's default features — see inline at Cargo.toml:82
  • ⛏ getrandom_04 comment attributes the dependency to the wrong crate — see inline at Cargo.toml:78-81
  • ⛏ Pin the esi fork by full SHA — see inline at Cargo.toml:145
  • 🤔 spin in .tool-versions makes asdf install complain — see inline at .tool-versions:6

Cross-cutting / body-level findings

  • 📝 PR description is out of date with the code — the description says the esi patch "is not committed here" and that "Fastly gates will be red in CI until #1122 is resolved", but commit e35e19c adds [patch.crates-io] esi = { git = "https://github.com/stackpop/esi", rev = "75bfbb396" } (Cargo.toml:144-145) and every check, Fastly included, is green. It also mentions an integration-tests README Viceroy update that isn't in the diff (harmless — no README pins a Viceroy version), and doesn't cover the later Spin 4.1 minimum (.tool-versions, docs/guide/spin.md, smoke_require_spin_version) or the Cloudflare worker-build --locked change. Worth refreshing before merge, since it likely becomes the squash commit text and currently implies #1122 still gates this PR.
  • 👍 Careful upgrade work — comparing HMAC 0.12 vs 0.13 output byte-for-byte to protect persisted EC IDs and SigV4 signatures, fixing the real API changes rather than adding #[allow], the TryFrom decode path removing a latent panic, and keeping the fork to a single range bump on the v0.7.2 tag (verified: stackpop/esi@75bfbb396d4c has the fastly/esi v0.7.2 tag as its sole parent and only changes fastly = "^0.12" → "^0.13" in esi/Cargo.toml, the six examples, and the lockfile).

CI Status

  • Analyze (actions): PASS
  • Analyze (javascript-typescript): PASS
  • Analyze (python): PASS
  • Analyze (rust): PASS
  • browser integration tests: PASS
  • cargo check/build/test (spin native + wasm32-wasip1): PASS
  • cargo check (cloudflare native + wasm32-unknown-unknown): PASS
  • cargo fmt: PASS (required)
  • cargo test: PASS (required)
  • cargo test (axum native): PASS
  • cargo test (cross-adapter parity): PASS
  • cargo test (ts CLI, native) (macos-latest): PASS
  • cargo test (ts CLI, native) (ubuntu-latest): PASS
  • CLAUDE.md symlink guard: PASS
  • CodeQL: PASS
  • format-docs: PASS (required)
  • format-typescript: PASS (required)
  • integration tests: PASS
  • integration tests (Fastly EC lifecycle): PASS
  • PBS Terraform and Compose checks: PASS
  • prepare integration artifacts: PASS
  • vitest: PASS

Comment thread Cargo.toml Outdated
Comment thread Cargo.toml Outdated
Comment thread Cargo.toml Outdated
Comment thread .tool-versions
Three conflicts, all from main and this branch changing the same lines.

`Cargo.toml` - main moved the EdgeZero git URLs from `stackpop` to
`IABTechLab` (#1323) while this branch moved the tag to v0.0.10. Took
both: the new org at v0.0.10. Verified the tag exists in the new
organization at the same commit the old one pointed to, 85d933b8044d,
so this is a URL change and not a different dependency.

`crates/trusted-server-adapter-cloudflare/build.sh` - main landed the
same `--locked` fix for the `worker-build` install that this branch
carried, independently. The commands are functionally identical, so this
keeps main's wording and flag order.

`Cargo.lock` - regenerated. Resolves EdgeZero from
`github.com/IABTechLab/edgezero` at v0.0.10 with a single fastly 0.13.1
and the new majors intact.

#1323 moved only the EdgeZero references; the `stackpop/esi` ones are
untouched on main, so the esi patch block still matching main's spelling
is correct and stays as it is.

Verified on the merged tree: all eight clippy targets clean under
`-D warnings`, fmt clean, test-fastly (221 adapter + 2944 core + 10 js +
10 + 21 openrtb + 4 doctests), test-fastly-reuse (221), test-axum,
test-cloudflare, test-spin, parity (17), CLI (858), 1211 JS tests, and
all three format gates.
Three review findings from dhruv8sh on #1123.

The `getrandom_04` renamed-package entry is gone, and with it the
`wasm_js` wiring in `trusted-server-core`. The entry was justified by a
wrong diagnosis: `sha2` does not pull getrandom 0.4. `crypto-common`
0.2 declares it `optional = true` behind a `getrandom` feature, and the
only thing enabling that feature is `chacha20poly1305`'s own default
`getrandom` → `aead/getrandom` → `crypto-common/getrandom`. Turning off
that default removes getrandom 0.4 from the Cloudflare graph entirely
rather than configuring it.

Safe because the XChaCha nonce is derived from SHA-256 for stable
tokens, not drawn from the AEAD's RNG: `http_util.rs` imports only
`Aead` and `KeyInit`, and nothing in the workspace calls
`generate_nonce` or `generate_key`. The two `OsRng` uses are ed25519
key generation through `rand`, untouched by this.

Confirmed the ciphertext does not move. A scratch crate encrypting a
fixed URL with a fixed secret produces the same bytes with default
features on and off:

  5a0f9fca0c02d1f46d2e00e67c3fd00ba5d825784329f4b3b5b588bbbe77b7ca...

so persisted proxy URL tokens stay valid. `cargo tree -i
getrandom@0.4.3` on `wasm32-unknown-unknown` now reports nothing; the
crate remains only on `wasm32-wasip1` via esi's `rand` and `uuid`,
which have native RNG and never needed the feature.

The esi patch rev is now the full 40-character SHA rather than a
9-character prefix, which is unambiguous on fetch. Verified it is the
same commit the lockfile already resolved.

On the fourth finding, the `spin` pin in `.tool-versions`: keeping it.
`fastly` and `viceroy` have no asdf plugin at all and have been pinned
there all along, while `spin` at least has a community one, so the file
is already an inventory of required versions rather than a strictly
asdf-installable manifest. `docs/guide/onboarding.md` says "asdf or
another version manager", and `docs/guide/spin.md` already documents
the missing plugin. CI is unaffected: every consumer greps one tool at
a time.

Verified: fmt clean, clippy-cloudflare-wasm, clippy-fastly and
clippy-spin-wasm clean, test-fastly (221 + 2944 + 10 + 10 + 21 + 4),
test-cloudflare, test-axum all passing.
@aram356

aram356 commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator Author

Merged main and addressed the review feedback.

Merge (847c9b2) — three conflicts. Cargo.toml: main moved the EdgeZero URLs to the IABTechLab org (#1323) while this branch moved the tag to v0.0.10, so this takes both; verified v0.0.10 exists in the new org at the same commit (85d933b8044d) the old tag pointed to. build.sh: main landed the same worker-build --locked fix independently, so this keeps main's wording. Cargo.lock regenerated.

Review fixes (4c5ca8a) — all four of @dhruv8sh's findings, with replies on each thread:

  • ♻️ getrandom_04 is gone. The finding was correct and my original diagnosis was wrong: crypto-common declares getrandom optional, and chacha20poly1305's default getrandom feature was the only thing enabling it. Disabling that default removes the crate from the Cloudflare graph. A/B'd the ciphertext to confirm persisted proxy URL tokens stay byte-identical.
  • ⛏ The misattributing comment went with it.
  • ⛏ esi rev is now the full 40-char SHA.
  • 🤔 Keeping the spin pin: fastly and viceroy have no asdf plugin and are already pinned there, so the file is an inventory rather than an asdf manifest, and the preflight reads its floor from that line so the two cannot drift. Details on the thread; easy to move if you prefer.

PR description — rewritten. It claimed the esi patch was "not committed here" and that the Fastly gates would be red until #1122, both false since e35e19c; it also mentioned an integration-tests README change that was never in the diff, and omitted the Spin 4.1 minimum and the worker-build --locked fix. Thanks for catching it, especially the point about it becoming the squash text.

Verified locally after both commits: fmt clean, eight clippy targets clean under -D warnings, test-fastly (221 + 2944 + 10 + 10 + 21 + 4), test-fastly-reuse, test-axum, test-cloudflare, test-spin, parity (17), CLI (858), 1211 JS tests, all three format gates.

aram356 added a commit that referenced this pull request Oct 21, 2026
@aram356
aram356 merged commit 43a2561 into main Oct 22, 2026
24 checks passed
@aram356
aram356 deleted the chore/upgrade-rust-198-deps branch October 22, 2026 00:22
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.

Upgrade to Rust 1.98.1 and align dependencies with EdgeZero

4 participants