Add dual-path EdgeZero entry point with feature flag (PR 14)#628
Conversation
Replace the app.rs stub with the full EdgeZero application wiring:
- AppState struct holding Settings, AuctionOrchestrator,
IntegrationRegistry, and PlatformKvStore
- build_per_request_services() builds RuntimeServices per request using
FastlyRequestContext for client IP extraction
- http_error() mirrors legacy http_error_response() from main.rs
- All 12 routes from legacy route_request() registered on RouterService
- Catch-all GET/POST handlers using matchit {*rest} wildcard dispatch
to integration proxy or publisher origin fallback
- FinalizeResponseMiddleware (outermost) and AuthMiddleware registered
…x handler pattern
- Remove Arc::new() wrapper around build_state() which already returns Arc<AppState>
- Remove dedicated GET /static/{*rest} route and its tsjs_handler closure
- Move tsjs handling into GET /{*rest} catch-all: check path.starts_with("/static/tsjs=") first
- Extract path/method from ctx.request() before ctx.into_request() to keep &req valid
- Replace .map_err(|e| EdgeError::internal(...)) with .unwrap_or_else(|e| http_error(&e)) in all named-route handlers
- Remove configure() method from TrustedServerApp (not part of spec)
- Remove unused App import
…, unused turbofish, and overly-broad field visibility - Drop `.into_bytes()` in `http_error`; `Body` implements `From<String>` directly - Remove `Box::pin` wrapper from `get_fallback` closure; plain `async move` matches all other handlers - Remove `Ok::<Response, EdgeError>` turbofish in `post_fallback`; type is now inferred - Drop now-unused `EdgeError` import that was only needed for the turbofish - Narrow `AppState` field visibility from `pub` to `pub(crate)`; struct is internal to this crate
Switches all four edgezero workspace dependencies from rev=170b74b to branch=main so the adapter can use dispatch_with_config, the non-deprecated public dispatch path. The main branch requires toml ^1.1, so the workspace pin is bumped from "1.0" to "1.1" to resolve the version conflict.
Replaces the deprecated dispatch() call with dispatch_with_config(), which injects the named config store into request extensions without initialising the logger a second time (a second set_logger call would panic because the custom fern logger is already initialised above). Adds log::info lines for both the EdgeZero and legacy routing paths.
matchit's /{*rest} catch-all does not match the bare root path /. Add
explicit .get("/", ...) and .post("/", ...) routes that clone the fallback
closures so requests to / reach the publisher origin fallback rather than
returning a 404.
Registers the trusted_server_config config store in fastly.toml with edgezero_enabled = "true" so that fastly compute serve routes requests through the EdgeZero path without needing a deployed service.
- Normalise get_fallback to extract path/method from req after consuming the context, consistent with post_fallback and avoiding a double borrow on ctx - Add comment to http_error documenting the intentional duplication with http_error_response in main.rs (different HTTP type systems; removable in PR 15) - Add comment above route handlers explaining why the explicit per-handler pattern is kept over a macro abstraction
aram356
left a comment
There was a problem hiding this comment.
Summary
Reviewed the 13 files that PR 628 actually changes vs its base (feature/edgezero-pr13-...). The dual-path entry point is a sensible migration shape, and the explicit GET/POST "/" routes + the header-precedence middleware test are the kind of load-bearing details that prevent future outages. However, the EdgeZero path currently diverges from the legacy path in ways that are security- and reliability-relevant, and the branch = "main" pin on upstream deps makes builds non-deterministic. Blocking on those.
Blocking
🔧 wrench
- Forwarded-header sanitization missing on EdgeZero path — legacy strips
Forwarded/X-Forwarded-*/Fastly-SSLbefore routing; EdgeZero hands the rawreqtodispatch_with_config. Withedgezero_enabled = "true"as the local-dev default, this is the default path. (main.rs:95) build_state()panics on misconfig —expect("should …")on settings / orchestrator / registry. Legacy returns a structured error response; EdgeZero now 5xx's with no detail. (app.rs:75)- Docstring "built once at startup" is misleading — every request spins up a fresh Wasm instance, so
build_state()runs per-request. Invites future false caching. (app.rs:61) - Stale
#[allow(dead_code)]on now-live middleware — five suppressions with "until Task 4 wires app.rs" comments. Task 4 is this PR. (middleware.rs:50,57,96,103,146) AuthMiddlewareflattensReport<TrustedServerError>intoEdgeError::internal(io::Error::other(...))— loses per-variant status code and user message; generic 500 instead of the specific error. (middleware.rs:122)edgezero-*deps pinned tobranch = "main"— non-deterministic builds; supply-chain path into prod via a moving upstream branch. Pin to a specificrevor fork tag. (Cargo.toml:59-62)
Non-blocking
🤔 thinking
- TLS metadata dropped on EdgeZero path —
tls_protocol/tls_cipherhardcoded toNone; legacy populates both. Low impact today (debug logging only), but a silent regression if any future signing/audit path reads them. (app.rs:123-124)
♻️ refactor
- 11 near-identical handler closures in
routes()— a pair of file-localmake_sync_handler/make_async_handlerhelpers would cut ~120 lines without harming auditability. (app.rs:175-301) FinalizeResponseMiddlewarehardcodesFastlyPlatformGeo— takeArc<dyn PlatformGeo>instead soMiddleware::handlecan be unit-tested end-to-end. (middleware.rs:68)build_per_request_servicesduplicatesplatform::build_runtime_services— extract a shared helper that takesClientInfo. (app.rs:111-127)
🌱 seedling
fastly.tomlflips local dev default to EdgeZero — combined with the blockers above, everyfastly compute servenow exposes them. Consider defaulting to"false"until the blockers land. (fastly.toml:52)
⛏ nitpick
AppStatefields can be private (notpub(crate)). (app.rs:62-66)- Root-route pairs clone closures four times — upstream
RouterService::get_manywould help. (app.rs:374-377)
📝 note
- The
dispatch_with_configcomment explaining theset_loggerpanic is excellent "why, not what" documentation. (main.rs:91-94)
👍 praise
operator_response_headers_override_earlier_headerscodifies a brittle precedence contract. (middleware.rs:217-233)- Explicit
GET "/"/POST "/"routes with the in-code explanation of matchit's wildcard gap prevent a future 404 outage. (app.rs:374-377)
CI Status
- browser integration tests: PASS
- integration tests: PASS
- prepare integration artifacts: PASS
- fmt / clippy / unit tests: not surfaced by
gh pr checks— please confirm these ran.
There was a problem hiding this comment.
Summary
Supplementary review — see aram356's review for the primary findings. This review covers additional items not raised there.
Non-blocking
🔧 wrench (cross-cutting, from earlier PRs in this stack)
set_headerdrops multi-valued headers:edge_request_to_fastlyinplatform.rs:187usesset_headerinstead ofappend_header, silently dropping duplicate headers. Pre-existing pattern (also incompat::to_fastly_request), but the EdgeZero path creates a new copy of the same bug.
🌱 seedling
parse_edgezero_flagis case-sensitive:"TRUE"and"True"silently fall through to legacy path. Considereq_ignore_ascii_caseor logging unrecognized values.
📝 note (cross-cutting, from earlier PRs)
- Stale doc comment in
platform/mod.rs:31: Referencesfastly::Bodyin publisher.rs, but PR 11 already migrated toEdgeBody.
♻️ refactor (cross-cutting, from earlier PRs)
- Duplicated
body_as_readerhelper: Identical function inproxy.rs:24andpublisher.rs:23. Extract to shared utility.
⛏ nitpick (cross-cutting)
- Management API client re-created per write: Each
put/deleteinplatform.rsconstructs a newFastlyManagementApiClient. Fine for current usage, noted for future batch writes.
📌 out of scope
compat.rsin core depends onfastlytypes: Already tracked as PR 15 removal target.
CI Status
- browser integration tests: PASS
- integration tests: PASS
- prepare integration artifacts: PASS
…n-provider-type-migration' into feature/edgezero-pr14-entry-point-dual-path
|
Superseding note: I re-posted the line-specific findings as inline comments after switching to the single-comment review-comments API with the PR head commit SHA. One additional high-priority finding is still not inline because the relevant code is outside this PR diff: P1 —
Suggested fix: thread |
|
@ChristianPavilonis Fixed the non-inline |
aram356
left a comment
There was a problem hiding this comment.
Summary
Round-3 review. The previously blocking findings from round 2 are all resolved: forwarded-header sanitization runs on the EdgeZero path, build_state returns a Result with a startup_error_router fallback, AuthMiddleware preserves per-variant status codes via http_error, FinalizeResponseMiddleware absorbs handler errors via IntoResponse, the AppState docstring is corrected, workspace edgezero deps are pinned to the full 40-char commit SHA 38198f9839b70aef03ab971ae5876982773fc2a1, parse_edgezero_flag is case-insensitive with full test coverage, HEAD/OPTIONS/PUT/PATCH/DELETE catch-all routes are registered, and FinalizeResponseMiddleware now takes Arc<dyn PlatformGeo> for testability.
This round surfaces two new blockers and four non-blocking findings. Both blockers are scope/behavior issues, not implementation bugs:
- Silent behavior change in
proxy.rs— integration-proxy redirect chains are no longer bounded bysettings.proxy.allowed_domains, and nothing in the PR body documents it. - Non-standard HTTP methods bypass the middleware chain — legacy
route_requestfalls through to publisher origin for every method; this path 405/404s them without runningFinalizeResponseMiddleware, dropping all TS/geo/operator headers. Contradicts theFinalizeResponseMiddlewaredoc contract.
Both are addressable in this PR without a large rework. Inline comments describe concrete fix options.
Local CI is green: cargo fmt --check, cargo clippy --workspace --all-targets --all-features -D warnings, and cargo test --workspace (867 tests).
Blocking
🔧 wrench
- Scope creep: silent integration-proxy allowlist semantics change —
proxy.rsnow lets integration proxies opt out ofsettings.proxy.allowed_domainsfor initial target and redirect hops. Not in PR description. See inline oncrates/trusted-server-core/src/proxy.rs:446. - Non-standard HTTP methods bypass middleware — TRACE/CONNECT/WebDAV verbs skip
FinalizeResponseMiddleware; TS/geo/operator headers dropped. Contradicts the doc contract. See inline oncrates/trusted-server-adapter-fastly/src/app.rs:149.
Non-blocking
🤔 thinking
- Per-request INFO-level routing log — noisy at production traffic; consider
log::debug!or once-per-cold-start. Inline onmain.rs:96.
📝 note
- No tests for
FinalizeResponseMiddleware::handle/AuthMiddleware::handle— the code changed this round has no direct unit coverage. Inline onmiddleware.rs:130. - No end-to-end test for the EdgeZero dispatch path — would catch the method-bypass regression directly. Inline on
app.rs:392.
CI Status
- browser integration tests: PASS (GitHub)
- integration tests: PASS (GitHub)
- prepare integration artifacts: PASS (GitHub)
- fmt: PASS (local)
- clippy: PASS (local)
- rust tests: PASS (local, 867 tests)
…on' into feature/edgezero-pr14-entry-point-dual-path
…dispatch_unregistered_method_returns_405_at_router_level
ChristianPavilonis
left a comment
There was a problem hiding this comment.
Summary
Reviewed the remaining PR #628 findings after excluding the consent_store replacement item and the orchestrator issue per discussion. I found two high-impact EdgeZero/legacy parity concerns plus a few documentation/comment accuracy issues. GitHub checks currently shown for the PR are passing.
aram356
left a comment
There was a problem hiding this comment.
Summary
Re-review against main-merge intent. The dual-path entry point and middleware shape are right, and prior round-2 blockers (build_state Result, forwarded-header sanitization, parse_edgezero_flag casing) are resolved. Three new functional regressions remain that change request handling vs legacy on identical input, plus two correctness/process gaps.
PR base is feature/edgezero-pr13-…; the diff vs main is 58 files because PRs 9–13 are unmerged. Findings below scope to the 13 files in this PR's actual delta.
CI: PASS (browser/integration tests, prepare artifacts).
Blocking
🔧 wrench
- EdgeZero path silently degrades when
consent_storeis misconfigured (compliance regression) —AppState::kv_storeis hardcoded toUnavailableKvStoreand the EdgeZero path never callsruntime_services_for_consent_route. Legacy returns 503 fail-closed whenopen_kv_store(name)fails (seeroute_tests.rs::configured_missing_consent_store_only_breaks_consent_routes); EdgeZero fail-opens becausetry_kv_fallbackswallowsKvError::Unavailablevia?. Inline onapp.rs:92. - Entry-point geo lookup overrides middleware's 401 geo-skip in production — Middleware correctly skips geo on 401 and emits
X-Geo-Info-Available: false; the entry-pointapply_finalize_headersthen runs an unconditional geo lookup and overwrites it with full geo headers when a real client IP is present. The unit test passes only because it bypassesmain()andlookup(None) → None. Inline onmain.rs:115. - Non-GET/POST methods on registered named-route paths regress to 405 — Named routes register a single method; matchit prefers the exact path over
/{*rest}, soHEAD /first-party/proxy,OPTIONS /auction,PUT /admin/keys/rotate, etc. return 405 (legacy proxies them to publisher origin). The existing 405 test only covers TRACE on/, which doesn't exercise this case. Inline onapp.rs:376. - Silent settings drop on entry-point
if let Ok(settings) = get_settings()— OnErr, response goes out without TS headers; legacy fails fast atbuild_state(). Inline onmain.rs:110. - PR description doesn't match the diff — undisclosed
tokio-test = "0.4"workspace dep (unused, not inCargo.lock); description says edgezero deps pinned tobranch=mainbut actual is a 40-char SHA;proxy.rsrefactor + new "Behavior change from pre-PR-14" doc paragraph (factually wrong vsorigin/main) not mentioned. Inlines onCargo.toml:86andproxy.rs:89.
❓ question
- Where is consent KV opened on the EdgeZero path? — If finding 1 is intentional (wired in PR 15/16), please link the issue/spec. Inline on
app.rs:92.
Non-blocking
🤔 thinking
- TLS metadata still hardcoded to
None—tls_protocol/tls_ciphernot populated fromFastlyRequestContext; silent regression for any future signing/audit path. Inline onapp.rs:124. Previously flagged. - Two geo lookups per request on the happy path — middleware + entry-point. Guard the second behind a "response missing TS headers" check. Inline on
main.rs:111. - Per-request double open of
trusted_server_configconfig store —is_edgezero_enabled+dispatch_with_configboth open it; SDK caches the handle, but the duplication is avoidable. Inline onmain.rs:66. Previously flagged.
♻️ refactor
- Eleven near-identical handler closures —
app.rs:273-359. Helper orroute!macro collapses them. Inline onapp.rs:351. Previously flagged. build_per_request_servicesduplicatesplatform::build_runtime_services— bodies identical except forclient_infosource. Inline onapp.rs:127. Previously flagged.- Module docstring overstates middleware coverage — top summary contradicts the "Startup error handling" section. Inline on
app.rs:9.
🌱 seedling
fastly.tomldefaults local dev to EdgeZero — everyfastly compute servereproduces the regressions above. Recommend defaulting to"false"until parity is reached. Inline onfastly.toml:48.
📝 note
- No EdgeZero-side test for the consent-store regression — mirror
configured_missing_consent_store_only_breaks_consent_routesdrivingTrustedServerApp::routes()after fix. - No EdgeZero-side test for HEAD/OPTIONS on a named-route path — add
dispatch_head_on_named_get_route_proxies_to_publisher. legacy_maincleanup TODO references issue #495 — confirm the issue coverscompat.rs,route_request,legacy_main, theapp::http_errorduplication, and the entry-point finalize wrap.
CI Status
- browser integration tests: PASS
- integration tests: PASS
- prepare integration artifacts: PASS
aram356
left a comment
There was a problem hiding this comment.
Summary
Round-5 re-review against feature/edgezero-pr13-… (PR's actual base). The round-4 blockers are resolved: EdgeZero now fails-closed on misconfigured consent_store (auction + fallback handlers call runtime_services_for_consent_route), the entry-point geo lookup skips on 401, every named path registers publisher_fallback_methods() so HEAD/OPTIONS/PUT/PATCH/DELETE no longer regress to 405, fastly.toml defaults edgezero_enabled = "false", and the previously undisclosed tokio-test dep is gone.
The feature is gated off in production (any flag-read failure falls back to legacy) and reversible by flipping one config-store value, so blast radius is bounded. Approving in spirit — but blocking on three specific items because the alternative is merging a PR with a stale description, no direct test for a security-relevant fix, and a regression-prone footgun in the route table.
Local CI: cargo fmt --check PASS, cargo clippy --workspace --all-targets --all-features -- -D warnings PASS, cargo test --workspace PASS (967 tests). GitHub CI on c17fa27e: browser/integration tests + prepare artifacts all PASS.
Blocking
🔧 wrench
- PR description does not match the diff. Says
Pin all four edgezero deps to branch=main— Cargo.toml actually pins torev = "38198f9839b70aef03ab971ae5876982773fc2a1"(Cargo.lock confirms). Missing from the description: theproxy.rsProxyRequestConfig.allowed_domainssemantics change, the/healthshort-circuit inmain.rs, thematch get_settings()finalize block inmain.rs, and thenamed_paths_primary_methodsbookkeeping inapp.rs. Reviewers shouldn't have to reverse-engineer the diff. Round-3 and round-4 both flagged the description being inaccurate. - Missing EdgeZero-side test for the consent-store regression. Inline on
route_tests.rs:184— see comment. The only existing test exercises the legacyroute_requestpath; the actual fix lives inapp.rs. named_paths_primary_methodshas no compile-time guard. Inline onapp.rs:444— see comment. Adding a new named route requires editing two places to stay consistent; mismatch silently regresses HEAD/OPTIONS to 405. Either fix here or file a tracked follow-up issue with explicit ownership.
Non-blocking
🤔 thinking
- Two geo lookups per request on the happy path (
main.rs:116) get_settings()runs 2× per EdgeZero request and is uncached (main.rs:110) — this also drives theINSECURE: …warning spam belowINSECURE: …warning spam on EdgeZero path. Direct consequence of the previous item: eachget_settings()call emits placeholder-secret warnings, so misconfigured deployments log them 2–3× per request. Should be emitted once at startup (cacheSettingsin aOnceLock).- Per-request double open of
trusted_server_config(main.rs:66) - TLS metadata still hardcoded to
Noneon EdgeZero path (app.rs:158) assert_ne!(status, METHOD_NOT_ALLOWED)is a brittle regression guard (app.rs:590)
♻️ refactor
- 11 near-identical handler closures in
routes()(app.rs:308) build_per_request_servicesduplicatesplatform::build_runtime_services(app.rs:146)fallback_handler.clone()runs ~59 times perroutes()call (app.rs:449)
📝 note
/healthshortcut has no test (main.rs:78)
🌱 seedling
AppState.kv_storeis dead state on most routes (app.rs:83)- Entry-point
apply_finalize_headerscould be conditional — paired with the "two geo lookups" finding; sentinel-header approach cleans both up post-#495.
👍 praise
finalize_handle_skips_geo_lookup_for_401(middleware.rs:331) —PanicGeois the right pattern for skip-condition tests.finalize_handle_absorbs_handler_error_and_injects_headers(middleware.rs:308) — locks down a real round-2 regression.dispatch_unregistered_method_returns_405_at_router_level(app.rs:598) — known limitation documented in test code, not a rotting comment.
CI Status
- browser integration tests: PASS (GitHub)
- integration tests: PASS (GitHub)
- prepare integration artifacts: PASS (GitHub)
- fmt: PASS (local)
- clippy
-D warnings: PASS (local) - rust tests: PASS (local, 967 tests)
ChristianPavilonis
left a comment
There was a problem hiding this comment.
Summary
I found 1 high-priority issue and 4 follow-up documentation/maintainability issues in the current PR diff. The main runtime concern is that the EdgeZero publisher fallback buffers streaming publisher responses into memory, regressing the legacy streaming path.
CI currently shown by gh pr checks: browser integration tests, integration tests, and prepare integration artifacts are passing.
Verdict: COMMENT because there are no P0 blockers in the included findings.
P1: Cap EdgeZero publisher fallback buffering via configurable publisher.max_buffered_body_bytes setting. When unset (default), buffering is unbounded, restoring pre-PR14 parity. When set, a BoundedWriter enforces the limit and returns a 500 on overflow instead of growing the Wasm heap without bound. P2: Extract resolve_geo_for_response helper to middleware.rs so the 401-skip rule is defined once and shared by both FinalizeResponseMiddleware and apply_entry_point_finalize. P2: Update get_settings doc to reflect OnceLock caching — first call loads and validates, subsequent calls clone the cached value. P2: Narrow startup-error module doc — responses may still receive entry-point finalization when settings reload succeeds after build_state fails. P3: Expand legacy_main doc to list all safe-fallback cases: disabled flag, config-store open failure, key-read error, and non-truthy values.
ChristianPavilonis
left a comment
There was a problem hiding this comment.
Summary
I reviewed the EdgeZero entry-point dual-path changes. Most previously raised blockers appear resolved, but I found two remaining EdgeZero-path parity issues that should be addressed before relying on the feature flag.
| .geo(Arc::new(FastlyPlatformGeo)) | ||
| .client_info(ClientInfo { | ||
| client_ip, | ||
| tls_protocol: None, |
There was a problem hiding this comment.
EdgeZero path drops TLS scheme detection, causing HTTPS requests to be treated as HTTP
build_per_request_services() sets both tls_protocol and tls_cipher to None. After the forwarded-header sanitization added in this PR, RequestInfo::detect_request_scheme() has no trusted TLS signal and falls back to "http" (crates/trusted-server-core/src/http_util.rs:222). That means publisher fallback URL rewriting and any scheme-sensitive logic on the EdgeZero path can generate http URLs for HTTPS traffic, unlike the legacy path which populates TLS metadata from Fastly.
Suggestion: Preserve a trusted scheme/TLS signal before dispatch, either by extending the EdgeZero Fastly context to include TLS metadata or by deriving a trusted HTTPS indicator from the Fastly request at the adapter boundary and threading it into ClientInfo.
| handler: NamedRouteHandler, | ||
| } | ||
|
|
||
| fn named_routes() -> [NamedRoute; 9] { |
There was a problem hiding this comment.
JA4 debug endpoint is bypassed by EdgeZero routing
The legacy path short-circuits GET /_ts/debug/ja4 before normal routing (main.rs:255), returning either the Fastly TLS fingerprint debug response or a 404 based on settings.debug.ja4_endpoint_enabled. The EdgeZero route table does not register this path, so when the feature flag is enabled the request falls through to the publisher origin instead. This contradicts the settings documentation that the endpoint returns 404 when disabled and breaks the debug feature when enabled.
Suggestion: Add an EdgeZero-path equivalent short-circuit before dispatch_with_config_handle, while the original FastlyRequest and TLS/JA4 accessors are still available, or register a dedicated route that can produce parity behavior.
Summary
TrustedServerAppor the preservedlegacy_mainbased onedgezero_enabledin thetrusted_server_configFastly ConfigStore. Missing, unreadable, or non-true flag values fall back to legacy.GET /healthas a cheap entry-point shortcut that bypasses logging, settings, and app construction.TrustedServerAppviaedgezero_core::app::HookswithFinalizeResponseMiddlewareandAuthMiddleware; auction and publisher fallback routes fail closed when a configured consent store cannot be opened.rev = "38198f9839b70aef03ab971ae5876982773fc2a1"and bumpstomlto"1.1".ProxyRequestConfig.allowed_domains:&[]is open mode for operator-configured integration proxies; a non-empty slice restricts first-party proxy initial targets and redirect hops.Changes
Cargo.tomledgezero-adapter-axum,edgezero-adapter-cloudflare,edgezero-adapter-fastly, andedgezero-coretorev = "38198f9839b70aef03ab971ae5876982773fc2a1"; bumptomlto"1.1"Cargo.locktomlversion changefastly.tomltrusted_server_configwithedgezero_enabled = "false"as the defaultcrates/trusted-server-adapter-fastly/src/main.rs/healthshortcut, EdgeZerodispatch_with_config, entry-pointmatch get_settings()finalize block for router-level 405/404 responses, and PR13 legacy streaming handlingcrates/trusted-server-adapter-fastly/src/app.rsTrustedServerApp, middleware wiring, consent-aware runtime service selection, table-driven named route registration, androutes_for_statetest seamcrates/trusted-server-adapter-fastly/src/middleware.rsapply_finalize_headershelpercrates/trusted-server-adapter-fastly/src/route_tests.rsHandlerOutcomeand the consent-store fail-closed behaviorcrates/trusted-server-core/src/proxy.rsProxyRequestConfig.allowed_domainsopen-mode versus restricted-mode semanticsCloses
Closes #495
Test plan
cargo test -p trusted-server-adapter-fastly dispatch_auction_with_missing_consent_store_returns_503cargo test -p trusted-server-adapter-fastlycargo test --workspacecargo clippy --workspace --all-targets --all-features -- -D warningscargo fmt --all -- --checkcd crates/js/lib && npx vitest run(not rerun in this cleanup)cd crates/js/lib && npm run format(not rerun in this cleanup)cd docs && npm run format(not rerun in this cleanup)Checklist
unwrap()in production code - useexpect("should ...")logmacros, notprintln!