Skip to content

Add Spin framework adapter#58

Open
ChristianPavilonis wants to merge 7 commits into
mainfrom
feature/spin
Open

Add Spin framework adapter#58
ChristianPavilonis wants to merge 7 commits into
mainfrom
feature/spin

Conversation

@ChristianPavilonis

@ChristianPavilonis ChristianPavilonis commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add a new mocktioneer-adapter-spin crate so Mocktioneer can run on the Fermyon Spin platform via WASI.
  • Register Spin as a supported adapter for existing Mocktioneer routes and adapter commands.
  • Add Spin-specific ignore/build configuration follow-ups from review.

Changes

Crate / File Change
crates/mocktioneer-adapter-spin/Cargo.toml New Spin adapter crate manifest with WASM target/dependency configuration
crates/mocktioneer-adapter-spin/src/lib.rs Spin HTTP component entrypoint delegating into edgezero_adapter_spin::run_app
crates/mocktioneer-adapter-spin/spin.toml Spin component manifest and build configuration
edgezero.toml Added Spin adapter support to existing routes and adapter commands
.github/workflows/test.yml Extended CI feature coverage for Spin
.gitignore Ignored Spin runtime log directories
Cargo.toml / Cargo.lock Registered the Spin crate and dependencies
CLAUDE.md Documented Spin target/workflow references

Closes

No issue provided.

Test plan

  • cargo test --workspace --all-targets
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo check --workspace --all-targets --features "fastly cloudflare"
  • Manual testing via cargo run -p mocktioneer-adapter-axum
  • Playwright e2e tests (cd tests/playwright && npm test)
  • Other: Rebased onto latest origin/main; tests not rerun in this session.

Checklist

  • Changes follow CLAUDE.md conventions
  • Business logic lives in mocktioneer-core, not in adapter crates
  • New routes added to both routes.rs and edgezero.toml (N/A — no new routes added)
  • Determinism preserved — no randomness or time-dependent logic
  • Ad markup rendered via templates in render.rs, not inlined in handlers (N/A — no ad markup changes)
  • New code has tests (colocated #[cfg(test)] or in tests/) (covered by workspace/build checks; no business logic added)
  • No secrets or credentials committed

@ChristianPavilonis ChristianPavilonis marked this pull request as ready for review March 12, 2026 19:08
@ChristianPavilonis ChristianPavilonis marked this pull request as draft March 12, 2026 19:09
@ChristianPavilonis ChristianPavilonis marked this pull request as ready for review March 31, 2026 15:01
@ChristianPavilonis ChristianPavilonis changed the title Support for spin framework Add Spin framework adapter Mar 31, 2026

@aram356 aram356 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR Review

Summary

The PR adds a Spin framework adapter following the existing adapter pattern. The adapter code itself is clean and minimal, but there are fundamental workspace integration issues that prevent the crate from building or being validated by CI.

Findings

🔧 Needs Change

  • Crate not in workspace members: crates/mocktioneer-adapter-spin is not listed in [workspace].members in root Cargo.toml. All CI gates (test, clippy, fmt) pass only because cargo doesn't know this crate exists — it is never compiled, tested, or linted.
  • Missing workspace dependencies: edgezero-adapter-spin and spin-sdk are referenced as workspace = true but not declared in [workspace.dependencies]. Hard build failure once the crate is added to workspace members.
  • Duplicate dependency with conflicting features: edgezero-adapter-spin appears in both [dependencies] and [target.wasm32.dependencies] with different feature specs. See inline comment for details.
  • Missing license.workspace = true: Inconsistent with Fastly and Cloudflare adapters.
  • Empty crate on host target: All code is #[cfg(target_arch = "wasm32")], leaving an empty lib for host builds.

❓ Questions

  • Does edgezero-adapter-spin exist upstream? It's not in Cargo.lock or workspace deps. If the edgezero framework doesn't have Spin support yet, this PR is premature.
  • Spin 2 vs Spin 3? spin_manifest_version = 2 + wasm32-wasip1 = Spin 2.x. Spin 3.x uses WASI Preview 2. Which is targeted?

🤔 Thoughts

  • spin.toml build command missing -p flag: Will try to build entire workspace for WASM, which will fail (Axum can't compile to WASM).

⛏ Nitpicks

  • Missing echo_stdout in spin adapter logging (edgezero.toml): Other adapters explicitly set this. Minor inconsistency.

🌱 Seeds

  • CI feature check: Once merged, cargo check --features "fastly cloudflare" should become --features "fastly cloudflare spin".

👍 Praise

  • Clean route registration: All existing routes correctly updated with "spin" in the adapters array. No routes missed.
  • Adapter stays thin: 12 lines delegating to edgezero_adapter_spin::run_app. Exactly the right pattern.

CI Status

  • fmt: PASS (but spin crate not checked — not in workspace)
  • clippy: PASS (but spin crate not checked — not in workspace)
  • tests: PASS (but spin crate not compiled — not in workspace)

Comment thread crates/mocktioneer-adapter-spin/Cargo.toml
Comment thread crates/mocktioneer-adapter-spin/Cargo.toml
Comment thread crates/mocktioneer-adapter-spin/Cargo.toml Outdated
Comment thread crates/mocktioneer-adapter-spin/src/lib.rs
Comment thread crates/mocktioneer-adapter-spin/spin.toml Outdated
Comment thread crates/mocktioneer-adapter-spin/spin.toml Outdated
@aram356 aram356 requested a review from prk-Jr April 9, 2026 16:47

@aram356 aram356 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR Review

Summary

Clean adapter addition that follows the thin-adapter pattern well. All CI gates pass (fmt, clippy, tests, feature check). One blocking item on dependency placement.

Findings

🔧 Needs Change

  • edgezero-core in wrong dependency section: Should be in base [dependencies], not WASM-only target section — inconsistent with Cloudflare adapter and fragile if the adapter evolves (crates/mocktioneer-adapter-spin/Cargo.toml:23)

❓ Questions

  • No main.rs fallback: Fastly adapter has a #[cfg(not(target_arch = "wasm32"))] fn main() stub. Spin is a cdylib like Cloudflare (which also lacks one), so this is consistent — confirming it's intentional?
  • Release-only builds for local dev: spin.toml source path and build command always use --release. Consistent with Fastly's pattern, but means spin up always does a release build.

🤔 Thoughts

  • anyhow dependency asymmetry: Neither Fastly nor Cloudflare adapters depend on anyhow. Justified by spin-sdk API contract — just noting the asymmetry.
  • Missing echo_stdout in spin logging section: Fastly adapter has echo_stdout = false, Spin doesn't. Cloudflare also omits it, so consistent with at least one adapter.

🌱 Seeds

  • Wildcard allowed_outbound_hosts: ["https://*:*"] is broad for a mock bidder making no outbound requests. Consider tightening to [] or documenting why (spin.toml:13).
  • Documentation updates needed: CLAUDE.md workspace layout, compilation targets table, and project overview don't mention Spin. Should be a follow-up.

📝 Notes

  • spin_manifest_version = 3 is correct for Spin 3.x
  • .gitignore additions for .spin/logs/ are appropriate
  • Cargo.lock changes bring in legitimate Spin ecosystem crates

CI Status

  • fmt: PASS
  • clippy: PASS
  • tests: PASS (90 tests)
  • feature check (fastly cloudflare spin): PASS

Comment thread crates/mocktioneer-adapter-spin/Cargo.toml Outdated
Comment thread crates/mocktioneer-adapter-spin/spin.toml Outdated
Comment thread crates/mocktioneer-adapter-spin/Cargo.toml Outdated

@aram356 aram356 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR Review

Summary

Clean, well-structured Spin adapter that follows established project patterns. One security-relevant finding around outbound permissions; the rest are questions and suggestions.

Findings

🔧 Needs Change

  • Overly permissive allowed_outbound_hosts: https://*:* grants full outbound HTTPS access but Mocktioneer never makes outbound calls (crates/mocktioneer-adapter-spin/spin.toml:13)

❓ Questions

  • Does edgezero-adapter-spin require outbound host permissions?: If the framework makes outbound calls at init or during request processing, the field needs to stay but should be scoped to specific hosts rather than a wildcard
  • Is edgezero-core needed as a direct wasm32 dependency?: lib.rs never imports from it directly — other WASM adapters have the same pattern, is it needed for Cargo feature unification? (crates/mocktioneer-adapter-spin/Cargo.toml:23)

🤔 Thoughts

  • Missing echo_stdout in logging config: Other adapters explicitly set this field; Spin section omits it (edgezero.toml:218)

📌 Out of Scope

  • Documentation needs updating: Adapters overview, architecture diagram, and CLAUDE.md compilation targets table don't include Spin yet — follow-up PR
  • EdgeZero CLI --adapter spin support: Confirm the CLI recognizes the spin adapter from edgezero.toml entries

CI Status

  • fmt: PASS
  • clippy: PASS
  • tests: PASS (71 unit + 19 integration)

Comment thread crates/mocktioneer-adapter-spin/spin.toml Outdated
Comment thread crates/mocktioneer-adapter-spin/Cargo.toml Outdated
Comment thread edgezero.toml

@aram356 aram356 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR Review

Summary

New mocktioneer-adapter-spin crate wiring Mocktioneer onto Fermyon Spin via wasm32-wasip2. Diff is tight and follows the existing Fastly/Cloudflare adapter template. Build works, tests pass, and the wasm target compiles locally (9.3 MB output). Blocking items are in-scope CLAUDE.md updates — the file was partially refreshed (CI gate line) but several other stale sections were missed. A few Cargo.toml hygiene questions round out the feedback.

Findings

🔧 Needs Change

  • CLAUDE.md — Project Overview sentence stale (CLAUDE.md:7-8): "Write once, deploy to Fastly Compute, Cloudflare Workers, or native Axum servers" — add Fermyon Spin.
  • CLAUDE.md — Workspace crate count / layout stale (CLAUDE.md:9 + 15-24): line 9 still says "Cargo workspace with 4 crates" (now 5), and the layout tree omits mocktioneer-adapter-spin/.
  • CLAUDE.md — Compilation Targets table missing Spin row (CLAUDE.md:67-71). Append:
    | Spin       | `wasm32-wasip2`          | Requires `spin` CLI for local/deploy |
    
  • CLAUDE.md — Key Files Reference table missing Spin entry (CLAUDE.md:290-292). Add:
    | Spin adapter       | `crates/mocktioneer-adapter-spin/src/lib.rs`       |
    

❓ Questions (inline)

  • Misleading Cargo.toml comment about "cloudflare/fastly pattern" — Fastly is target-gated, not unconditional.
  • anyhow declared unconditionally but only used in wasm-gated code.
  • spin-sdk with default-features = false — intentional? Worth a one-line justification.
  • allow(unused_imports) appears unnecessary since every use is already cfg-gated.

♻️ Refactor (inline)

  • [adapters.spin.commands] key ordering inconsistent with the other three adapters (builddeployserve).
  • Flag-order drift between the build command in edgezero.toml vs spin.toml.

🌱 Seeds / 📌 Out of Scope

  • No docs page for the Spin adapter. docs/guide/adapters/ has fastly.md / cloudflare.md / axum.md, and docs/guide/adapters/index.md:10-11 plus docs/.vitepress/config.mts:37-38 sidebar only enumerate edge adapters. Reasonable as a follow-up PR to keep this diff runtime-focused — worth a tracking issue.
  • CI never actually builds the spin wasm. test.yml installs only wasm32-wasip1 and runs cargo check --features on host. Matches Fastly's pre-existing gap, but a breakage in the target-gated src/lib.rs blocks wouldn't be caught. Worth a separate issue to tighten wasm build coverage across all three wasm adapters.
  • spin.toml watch list too narrow — won't retrigger on mocktioneer-core/src/**/*.rs or edgezero.toml changes during spin watch.

👍 Praise

  • Tight allowed_outbound_hosts = [] aligns with Mocktioneer's deterministic / self-contained design.
  • CI feature list (test.yml) and CLAUDE.md:164 updated in lockstep.
  • Full cfg-gating lets host tooling (fmt / clippy / test) run without wasm32-wasip2 installed.
  • .gitignore scoped narrowly to .spin/logs/ rather than a blanket .spin/.

CI Status (local verification)

  • cargo fmt --all -- --check: PASS
  • cargo clippy --workspace --all-targets --all-features -- -D warnings: PASS
  • cargo test --workspace --all-targets: PASS (19 tests)
  • cargo check --workspace --all-targets --features "fastly cloudflare spin": PASS
  • cargo build --release --target wasm32-wasip2 -p mocktioneer-adapter-spin: PASS (9.3 MB wasm)

Comment thread crates/mocktioneer-adapter-spin/Cargo.toml Outdated
Comment thread crates/mocktioneer-adapter-spin/Cargo.toml Outdated
Comment thread Cargo.toml
Comment thread crates/mocktioneer-adapter-spin/src/lib.rs Outdated
Comment thread edgezero.toml
Comment thread crates/mocktioneer-adapter-spin/spin.toml Outdated
Comment thread crates/mocktioneer-adapter-spin/spin.toml
Comment thread .github/workflows/test.yml

@prk-Jr prk-Jr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR Review

Summary

Spin adapter is thin and correct — delegates cleanly to edgezero_adapter_spin::run_app with all host-compat guards in place. The verification v1.1 changes are well-tested and add meaningful security improvements (SSRF guard, body limit, replay prevention). One blocking CI issue: viceroy is not pinned to a version, and v0.18.0 on crates.io now requires rustc 1.95 while the project is on 1.91.1.

Findings

🔧 Needs Change

  • viceroy not version-pinned (.github/workflows/test.yml:50): cargo install viceroy --locked has no --version; always pulls latest from crates.io; v0.18.0 requires rustc 1.95; project uses 1.91.1 — this is the exact failure in the CI log.

    Fix:

    - name: Setup Viceroy
      run: cargo install viceroy --version 0.17.0 --locked

    Alternatively, bump .tool-versions to rust 1.95 if all WASM targets support it.

❓ Questions

  • js-sys bundled into Spin PR: js_sys::Date::now() in verification.rs is gated on wasm32-unknown-unknown (CF Workers), not Spin (wasm32-wasip2). Was the verification v1.1 work intentionally squashed onto this branch, or is it a branch-merge artifact? Code is correct either way.

🌱 Seeds

  • wasm32-wasip2 not added in CI (.github/workflows/test.yml:47): CI adds wasm32-wasip1 only; Spin targets wasm32-wasip2. No build step exercises it today so CI passes, but a future cargo build --target wasm32-wasip2 step would fail immediately. Suggest adding rustup target add wasm32-wasip2 alongside wasip1 now.

👍 Praise

  • validate_jwks_host with url::Host::parse rejects raw IPs and path-traversal chars — solid SSRF guard
  • JWKS body bounded to 64 KiB — prevents response-body memory exhaustion
  • Timestamp freshness + host cross-check in v1.1 verification — good replay attack prevention
  • FIXED_BID_CPM replacing per-size phf map — simpler, eliminates WASM compat concern, aligns with CLAUDE.md determinism requirement
  • Comprehensive test coverage for all new verification paths (stale/future timestamps, host mismatch, missing fields, payload shape)

CI Status

  • fmt: PASS (local)
  • clippy: PASS (local)
  • tests: PASS (local)
  • feature check (fastly cloudflare spin): PASS (local)
  • CI (GitHub Actions): FAIL — viceroy install step (see blocking finding above)

Comment thread crates/mocktioneer-adapter-spin/Cargo.toml Outdated
- Add mocktioneer-adapter-spin to workspace members
- Add edgezero-adapter-spin and spin-sdk to workspace dependencies
- Add license.workspace = true to adapter Cargo.toml
- Fix duplicate edgezero-adapter-spin dependency, set default = []
- Add module doc and cfg_attr for non-WASM host compilation
- Update to Spin 3: manifest v3, wasm32-wasip2 target, spin-sdk 5.2
- Add -p flag to spin.toml and edgezero.toml build commands
- Update CI feature check to include spin
- Move edgezero-core to base [dependencies] with feature-unification comment
- Tighten allowed_outbound_hosts to [] in spin.toml
- Add echo_stdout = true to spin logging config in edgezero.toml
- Update CI gate docs to include spin feature in cargo check command
@ChristianPavilonis ChristianPavilonis requested a review from prk-Jr June 9, 2026 20:41

@prk-Jr prk-Jr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR Review

CI is green, but the current checks do not compile the Spin adapter on its real wasm32-wasip2 target. Host CI can pass because the actual Spin entrypoint is behind #[cfg(target_arch = "wasm32")].

Findings

🔧 Spin adapter does not compile for its real target (crates/mocktioneer-adapter-spin/src/lib.rs:20)

cargo build --release --target wasm32-wasip2 -p mocktioneer-adapter-spin fails with E0061 because edgezero_adapter_spin::run_app now requires the manifest source as its first argument. Suggested fix:

edgezero_adapter_spin::run_app::<MocktioneerApp>(
    include_str!("../../../edgezero.toml"),
    req,
)
.await

🔧 CI does not exercise the Spin wasm entrypoint (.github/workflows/test.yml:59)

cargo check --workspace --all-targets --features "fastly cloudflare spin" runs on the host target, so it misses wasm-gated Spin code. Please add a target-specific Spin check, for example:

rustup target add wasm32-wasip2
cargo check --target wasm32-wasip2 -p mocktioneer-adapter-spin --features spin

Verification

  • GitHub checks: PASS
  • cargo fmt --all -- --check: PASS
  • cargo clippy --workspace --all-targets --all-features -- -D warnings: PASS
  • cargo test --workspace --all-targets: PASS
  • cargo check --workspace --all-targets --features "fastly cloudflare spin": PASS
  • cargo build --release --target wasm32-wasip2 -p mocktioneer-adapter-spin: FAIL

@ChristianPavilonis

Copy link
Copy Markdown
Contributor Author

Addressed the latest review feedback in e96c2b6:

  • Updated the Spin entrypoint to pass include_str!("../../../edgezero.toml") into edgezero_adapter_spin::run_app.
  • Updated CI to install wasm32-wasip2 and run cargo check --target wasm32-wasip2 -p mocktioneer-adapter-spin --features spin.

Local verification completed:

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --all-targets
  • cargo check --workspace --all-targets --features "fastly cloudflare spin"
  • cargo check --target wasm32-wasip2 -p mocktioneer-adapter-spin --features spin
  • cargo build --release --target wasm32-wasip2 -p mocktioneer-adapter-spin --features spin

@aram356 aram356 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍 Looks good

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.

3 participants