Repository navigation
Conversation
Round 50 — Fastly SDK correctness pass (commit
|
Round 51 — round-50 carry-overs + Spin WASI write mechanics (commit
|
Startup fixture validation closeoutPushed head: The startup-attestation fixture now retains a child-owned ephemeral listener and atomically publishes bounded endpoint/PID/nonce metadata. Its first prescribed HTTP response must still attest; sticky rejection, request ordinals and the original absolute startup deadline remain unchanged. Production transport, public APIs, audited pins and portable process-controller semantics are unchanged. Executed verification
The retained RED fixture regression fails before the repair (exit 101); the repaired startup group passes all 15 tests. This proves the released-port gap, not the historical intermittent refusal's exact cause. The passing Cloudflare routing/shutdown sample does not explain or waive older shutdown or timing failures. Evidence and remaining limits: audit, plan. No thread is resolved or disposition changed. The manual hosted checklist, historical failures, independent current-head review, candidate freeze and durable qualification remain open. Restored validation tools and failure captures are retained; no worktree is removed or deployment/merge performed. Next actor: maintainers for independent review and the manual hosted checks. |
prk-Jr
left a comment
There was a problem hiding this comment.
PR Review
Summary
Follow-up review of head a7d7fd0f (base cf2c57b1), focused on the delta since my last review at 9b31a697 (52 commits, 145 files; production changes in core, all four adapters, macros and CLI). My earlier blocking findings are resolved, and I found no new blocking defect in the paths reviewed, so I'm approving. The remaining items below are non-blocking.
😃 Praise
- The earlier blockers were fixed at the right layer with discriminating tests. TE+CL rejection samples
Transfer-Encodingbefore hop-by-hop stripping, so Connection-nominated TE is still caught, while HEAD/304, 1xx/204 and 205 keep their own paths. The response-egress validator now requires exact equality with the embedded 26-probe schedule, with coherent-subset/rename/reorder regressions. Spin derivesContent-Lengthfrom the actual buffered bytes after removing caller CL/TE.
Prior findings
- Verified fixed: TE+CL stale length, validator subset acceptance, Spin buffered uploads without CL,
app!unqualifiedResult/Ok, emptyConnectionmembers, external-adapter Breaking note, extractor cap docs. - Manifest sibling discovery: the disclosure in
docs/guide/cli-reference.md(Working Directory) plus theEDGEZERO_MANIFESTrecommendation is an acceptable resolution of a policy choice.
Findings
Non-blocking
- 🤔 Fastly batch heads now also use the 1 ms pulse, including
Bypass(crates/edgezero-adapter-fastly/src/outbound.rs:388, inline). - ⛏ Spin sends
Content-Length: 0on bodiless DELETE/OPTIONS (crates/edgezero-adapter-spin/src/outbound.rs:905, inline). - 🏕 Audit docs still publish local absolute paths (from my earlier review, unchanged):
/Users/ag/...appears 164 times across 16 files indocs/audits(includingdocs/audits/evidence/*.json), anddocs/.vitepress/config.mtsstill excludes onlysuperpowers/**. Suggest scrubbing to a placeholder, or excluding audits from the site and linking them on GitHub. - 🤔 Scaffold Git fallback still has no
rev(crates/edgezero-cli/src/generator.rs:307,:344, from my earlier review, no reply yet): generated projects can follow EdgeZeromainwhile seeding exact pins. Pinning the fallback to the binary's commit would fix it. - 🤔 Wasmtime download in CI still has no checksum (
.github/workflows/test.yml, pre-existing, from my earlier review). - 📝 CodeQL is red on 4 false positives:
rust/hard-coded-cryptographic-valueatcrates/edgezero-test-harness/src/main.rs:2212,:2232,:2247,:2267. These are in#[cfg(test)]code, and the flagged value is the fixture launch label"expected", compared only for equality. CodeQL is not a required check here, but dismissing these alerts as used-in-tests would turn the check green.
📌 Out of Scope
- This approval covers code review of the reviewed paths at
a7d7fd0f. It does not replace the manual hosted checks, candidate freeze or qualification still listed as open in the PR description. - Not reviewed in depth: most of the test-harness/fixture delta, the docs delta, Spin/Fastly
cli.rsserve/override flag filters, andpush_cloud.rs.
CI Status
- Hosted at
a7d7fd0f: all required checks pass (fmt, test, per-target wasm clippy/tests for Cloudflare/Fastly/Spin, docs). CodeQL fails (see 📝 above). - Local targeted runs: harness response-egress 7 passed; core head/context/pre-dispatch/router 110 passed; Spin scheduling 16 passed; Fastly host lib 182 passed. Fastly/Cloudflare/Spin WASM suites were not run locally (local Viceroy mismatch); the hosted wasm jobs cover them.
| body.recorder().cloned() | ||
| } | ||
|
|
||
| fn head_handle(_pending: &PendingHead) -> Option<u32> { |
There was a problem hiding this comment.
🤔 Batch heads now always take the opaque 1 ms pulse path, including Bypass
At 9b31a697, batch slots used PendingHead::Direct, so head_handle returned a handle and turn could select on the host until the earliest deadline. Since 6004d8a (preserve SDK cache selection for batch slots), every buffered Send and batch head goes through send_async, and head_handle always returns None. So every head is opaque, and progress.rs:911 caps each host wait at 1 ms while observe_ready polls every pending head slot each turn.
Effect: a batch of N slots against slow origins does about one turn per millisecond, each polling N pending requests, for the whole head wait. That also applies to Bypass slots, which have no SDK cache state to preserve. The capability guide (docs/guide/capabilities.md:416-418) and CHANGELOG describe the pulse as applying to "Cached SDK Send heads".
This extends the scope of the 1 ms pulse thread you already declined, so I'm not asking to change the trade-off. Suggest at least updating the docs to say it covers buffered Send and batch heads under both cache policies. If the CPU cost matters, restoring a direct handle for Bypass slots would bring back host select there. Evidence: source comparison against 9b31a697, not measured.
There was a problem hiding this comment.
CREATOR: fixed in b97efec1. The capability guide and changelog now disclose the 1 ms pulse for buffered Send and batch heads under both cache policies, including Bypass, and its O(N) readiness polling cost. The approved SDK/cache path, B31 timers and logical deadlines are unchanged; no CPU benchmark or hosted performance qualification is claimed. Leaving the thread open for reviewer verification.
| body: &Body, | ||
| headers: &mut HeaderMap, | ||
| ) -> Result<Fields, EdgeError> { | ||
| if !matches!(*method, Method::GET | Method::HEAD) |
There was a problem hiding this comment.
⛏ Content-Length: 0 on bodiless DELETE/OPTIONS
request_fields inserts Content-Length for every buffered body unless the method is GET/HEAD, including an empty one. So a default OutboundRequest DELETE or OPTIONS goes out with content-length: 0. RFC 9110 §8.6: a user agent SHOULD NOT send Content-Length when the request has no content and the method semantics do not anticipate such data. Some strict origins and WAFs treat this differently.
Suggest skipping the insert when the bytes are empty and the method is not POST/PUT/PATCH. A zero-length POST should keep Content-Length: 0. Source-read only; I did not compare the wire behaviour of the other adapters.
There was a problem hiding this comment.
CREATOR: fixed in b97efec1. Known-empty DELETE/OPTIONS omit the synthesized Content-Length and unnecessary request-body writer; empty POST/PUT/PATCH retain Content-Length: 0. SDK-resource and actual Send/Begin wire controls cover those methods. A fresh SDK 8 / Spin 4.1 CI run also passed the resource, async, wire and ingress phases. The host may emit exactly an empty chunk terminator for DELETE/OPTIONS; that limitation is documented without relaxing strict GET/HEAD suppression. All captures remain qualification:false. Leaving the thread open for reviewer verification.
ChristianPavilonis
left a comment
There was a problem hiding this comment.
📝 PR review — a7d7fd0f
Summary
This PR implements portable outbound HTTP and request-lifecycle contracts across core and the four adapters. Changes are requested for four verified P2 defects: CLI-only compilation, qualification telemetry filtering, fixture-build cancellation, and evidence output contaminating build identity.
Eight inline comments contain the approved findings: 4 🔧 blocking and 4 🤔 non-blocking documentation corrections.
CI status
- fmt: PASS —
cargo fmt --all -- --check. - clippy: PASS —
cargo clippy --workspace --all-targets --all-features -- -D warnings. - tests: PASS —
cargo test --workspace --all-targets: 2,701 passed, zero failed, one ignored across 33 binaries. - Workspace feature compilation, Spin WASM compilation, and strict provider-target Clippy with adapter/test-utils features: PASS.
- Harness: 653 passed, zero failed, three ignored. Tooling: 169 passed with the required harness executable configured; the initial unconfigured invocation failed because that environment prerequisite was omitted.
- Documentation/legacy/dependency/forwarding guards: PASS. Inventory: 255 criteria / 514 legs,
qualified: false. - GitHub CodeQL: FAIL on this head, reporting four hard-coded test nonce values at
crates/edgezero-test-harness/src/main.rs:2212,2232,2247,2267. Inspection shows deterministic endpoint-validation test inputs rather than cryptographic secrets; these appear to need false-positive triage, not treatment as four confirmed production vulnerabilities.
Verification limits
All executable source, authored documentation and lockfiles received complete reads after the scoped coverage-completion passes. Full manual coverage remains incomplete for six large raw/generated evidence files: four historical probe JSONLs, the acceptance inventory, and the compressed reviewed-case corpus. These were mechanically parsed/validated, not fully manually audited.
No provider deployment, full four-adapter runtime rerun, or hosted qualification was performed in this review. Existing GitHub provider jobs are separate evidence; local checks and the focused reproductions do not promote capability or qualification claims.
| @@ -58,6 +59,6 @@ default = [ | |||
| "edgezero-adapter-cloudflare", | |||
| "edgezero-adapter-spin", | |||
| ] | |||
| cli = ["dep:clap"] | |||
| cli = ["dep:clap", "dep:handlebars"] | |||
There was a problem hiding this comment.
🔧 P2 — Enable adapter CLI helpers in the CLI-only feature selection
The new imports in adapter.rs and manifest_source.rs require edgezero_adapter::cli_support, which is gated behind the dependency's cli feature. This feature currently enables only Clap and Handlebars, so the documented adapter-free CLI configuration now fails with two E0432 unresolved imports. Default/all-feature builds mask the missing activation through the provider adapters.
Fix: enable the dependency feature explicitly:
cli = ["dep:clap", "dep:handlebars", "edgezero-adapter/cli"]Also add an isolated CLI-only compilation check.
Verification: cargo check --offline --locked -p edgezero-cli --lib --no-default-features --features cli exits 101. The same check with --features 'cli,edgezero-adapter/cli' exits 0 without repository edits.
There was a problem hiding this comment.
CREATOR: fixed in b97efec1. The cli feature explicitly enables edgezero-adapter/cli. The isolated cargo check --offline --locked -p edgezero-cli --lib --no-default-features --features cli now runs in CI and the prescribed suite rather than relying on provider feature unification. The isolated check passed for the published repair. Leaving the thread open for reviewer verification.
| pub(super) fn main(qualification: bool) -> Result<(), fastly::Error> { | ||
| fixture_fastly::initialize_launch(env!("CARGO_BIN_NAME")); | ||
| fastly::init(); | ||
| fixture_core::init_fixture_logging(telemetry)?; |
There was a problem hiding this comment.
🔧 P2 — Preserve lifecycle telemetry in the qualification entrypoint
fixture-fastly-qualification calls main(true), but this installs the Warn-only FixtureLogger before dispatching /qualification/*. Both the facade maximum and FixtureLogger::enabled() reject Info, while all four lifecycle records in ProbeTrace use Info on the edgezero_qualification target. The documented 26-probe run therefore cannot collect its required 104 lifecycle events or pass the evidence validator, regardless of response correctness.
Fix: in qualification mode, allow this target's Info records through both filters, or send the structured records directly to the telemetry sink. Add an emission regression; raising only the facade maximum is insufficient.
Verification: a scratch binary using the actual fixture-core dependency emits zero qualification Info records and one Warn control. Raising the facade maximum to Info still leaves the qualification record suppressed. This is a qualification collection defect, not a claim of a production security vulnerability or hosted guarantee.
There was a problem hiding this comment.
CREATOR: fixed in b97efec1. Qualification Info records pass both the facade maximum and the logger target filter, and their JSON is written without a log prefix. Ordinary fixture Info stays filtered while Warn/Error controls remain visible. The regression fixture_logging_emits_raw_lifecycle_events_but_filters_ordinary_info exercises actual emission; the 78-case qualification fixture suite passed again locally. This repairs collection, not hosted lifecycle qualification. Leaving the thread open for reviewer verification.
| command.args(["--bin", "fixture-axum-outbound-progress"]); | ||
| } | ||
| command.arg("--message-format=json-render-diagnostics"); | ||
| let output = command.stderr(Stdio::inherit()).output()?; |
There was a problem hiding this comment.
🔧 P2 — Supervise fixture builds so cancellation reaches Cargo
This non-Cloudflare build branch blocks in Command::output() without registering the child with Process/LIVE_GROUPS or checking cancellation. The controller's signal handler only flags cancellation and signals registered groups. A direct SIGTERM therefore leaves the controller and Cargo blocked until the build returns; forcibly terminating only the controller can orphan the build.
Fix: preserve Cargo JSON capture, but launch/wait through the existing Process::spawn_with_stdout ownership and cancellation path, then parse its captured stdout. Add a direct-controller signal regression for this actual build branch, including descendant cleanup.
Verification: with a freshly built HEAD harness and a fake Cargo that sleeps for 30 seconds, both the controller and build were still alive six seconds after direct SIGTERM to the controller PID. The dedicated scratch process group was subsequently killed and reaped.
There was a problem hiding this comment.
CREATOR: fixed in b97efec1. Builds, metadata capture and version probes use the existing supervised Process owner with separate bounded stdout/diagnostics. Direct-controller cancellation regressions prove Cargo/descendant termination before safety cleanup, not merely after killing the test group. The fresh pre-repair harness baseline passed 661 tests with three helper entrypoints ignored, including these regressions. Leaving the thread open for reviewer verification.
| let mut entries = fs::read_dir(path)?.collect::<io::Result<Vec<_>>>()?; | ||
| entries.sort_by_key(fs::DirEntry::file_name); | ||
| for entry in entries { | ||
| if !ignored_output(&entry.path()) { |
There was a problem hiding this comment.
🔧 P2 — Keep selected evidence output out of the source/build hash
--output accepts arbitrary empty directories, but this recursive crates/ hash excludes only conventional generated-directory names. A valid output such as crates/edgezero-test-harness/results/run-1 is consequently included. Staging artifacts or writing build/events records changes the source identity between cargo_build() and the later provider_command()/Fastly launch capture without any source or configuration change, causing startup attestation to reject the run.
Fix: consistently exclude the canonical selected output subtree from every identity capture while preserving dirty/untracked source hashing. Keep attestation strict rather than caching away a changing digest. Add an output-only write/staging regression using a nonconventional directory name.
Verification: a controlled synthetic-tree probe using the actual hash module (only capture visibility changed) produces different digests after event and staged-artifact writes under fixed compiler, Cargo, environment and source inputs. The build-to-launch recapture sequence is present in the harness source.
There was a problem hiding this comment.
CREATOR: fixed in b97efec1. Every fresh identity capture excludes only the canonical selected evidence subtree, including a nonconventional path. Scoped restoration handles nested output selections, unwinding and independent threads; dirty/untracked source files outside that subtree still change the digest. Regression tests cover writes/staging and restoration, without caching away source changes or relaxing launch attestation. Leaving the thread open for reviewer verification.
| The pinned `miniz_oxide` state reserves a 32 KiB sliding window and a 64 KiB | ||
| inflate state. The codec wrapper reserve is 4 KiB and the shared EdgeZero | ||
| stream output buffer is 8 KiB. The measured source subtotal is therefore | ||
| 73,728 bytes before allocator metadata, fragmentation, task stacks, and host |
There was a problem hiding this comment.
🤔 P3 — Reconcile the flate audit's subtotal
The listed 64 KiB state reserve, 4 KiB codec-wrapper reserve and 8 KiB output buffer total 77,824 bytes even assuming the 32 KiB sliding window is already included in the state. That gives about 13.47x headroom under 1 MiB, rather than the stated 73,728 bytes and more than 14x. The accompanying flate_fixed_charge_covers_source_audited_payload_subtotal regression checks the wrapper reserve but omits it from its subtotal.
Suggested fix: explain which components overlap or are excluded, or include the wrapper reserve and correct the subtotal/headroom and corresponding test calculation. This discrepancy is not evidence that the 1 MiB policy reservation is insufficient; no runtime limit increase is requested.
There was a problem hiding this comment.
CREATOR: fixed in b97efec1. The audited subtotal now includes the 4 KiB wrapper: 65,536 + 4,096 + 8,192 = 77,824 bytes, approximately 13.47x below the unchanged 1 MiB reservation. The corresponding core regression includes the same three terms. No decoder pin or runtime charge was increased. Leaving the thread open for reviewer verification.
|
|
||
| An initialization `Err` ends the SDK loop. `Hooks::build_app` is infallible by signature: a panic remains a sandbox failure, not a fabricated initialization `Result`. Do not retry after partially completed global initialization. | ||
| An initialization `Err` leaves `Sandbox` empty. Standard serving propagates that |
There was a problem hiding this comment.
🤔 P3 — Describe standard Fastly assembly-failure retry accurately
This section explicitly describes current production interfaces, but standard serve_app_with_hooks does not propagate every application assembly error and terminate. Its retained.initialize(...) failure branch delivers the typed error through detached egress. If delivery succeeds, the callback succeeds, no failed app is retained, and the next request retries assembly. This wording and the related statement in docs/superpowers/plans/2026-09-15-reusable-app-lifecycle.md:140–141 contradict that implementation and EZ-22.
Suggested fix: distinguish recoverable application assembly failures from fatal logging/setup or terminal-delivery errors, and describe detached error delivery plus successful-only retention/retry in both places. The runtime should not be changed to match this stale description.
The current branch was traced through send_assembly_error, FastlyRequestDelivery::into_standard_result and FastlyResponseDelivery::standard_result.
There was a problem hiding this comment.
CREATOR: fixed in b97efec1. Both the reusable-lifecycle design and plan distinguish recoverable application assembly failures from fatal setup or terminal-delivery errors. Standard Fastly detached delivery succeeds without retaining a failed app, and a later request retries assembly; production behavior was not changed to match the old prose. Leaving the thread open for reviewer verification.
| The EZ-23 ready legs share one full Axum suite command, including ignored tests: | ||
|
|
||
| ```sh | ||
| scripts/run_test_nonzero.sh --include-ignored --inventory axum/native-tcp,unit/axum,axum/http1,axum cargo test --offline --locked -p edgezero-adapter-axum --no-default-features --features axum,test-utils --all-targets |
There was a problem hiding this comment.
🤔 P3 — Synchronize the documented Axum full-suite command with the inventory
This example omits axum/http1-chunked from the inventory selector. The guard deliberately matches the exact declared command, so copying this invocation fails sentinel selection before running any tests.
Suggested fix: append ,axum/http1-chunked to the inventory argument, matching the current inventory/CI command. Check executable full-suite examples through the existing read-only sentinel lookup so exact-selector changes do not leave unusable commands behind.
Verification: the current HEAD harness's acceptance --sentinels ... --command ... lookup exits 1 for the documented command with no ready test sentinels for selected environment. The corrected command exits 0 and returns 43 sentinels.
There was a problem hiding this comment.
CREATOR: fixed in b97efec1. The documented inventory selector includes axum/http1-chunked and the docs guard checks the exact command through the existing sentinel lookup. That lookup finds all 43 sentinels. The current explicit-executor Axum CI attempt passed its complete native-test phase; its later wire attestation failure remains separately recorded and is not called a full-suite pass. Leaving the thread open for reviewer verification.
| ) -> ServeSummary<fastly::Error> | ||
| where | ||
| A: Hooks, | ||
| F: FnMut(&fastly::Request, &mut Extensions); | ||
| Prepare: FnMut(&mut fastly::Request, &mut Extensions), | ||
| Finalize: FnMut(&mut edgezero_core::Response) -> State; |
There was a problem hiding this comment.
🤔 P3 — Use the actual Response type path in the current serving signature
edgezero_core::Response is not a root re-export; the alias is defined at edgezero_core::http::Response. Copying this newly reconciled current-interface bound produces E0425, while production imports the correct type.
Suggested fix: use:
Finalize: FnMut(&mut edgezero_core::http::Response) -> State;No production alias needs to be added solely to satisfy this example.
A scratch metadata compilation against an existing core rlib fails for the documented path and succeeds with edgezero_core::http::Response; inspection of the root exports and production signature confirms the mismatch.
There was a problem hiding this comment.
CREATOR: fixed in b97efec1. The current serving signature uses edgezero_core::http::Response, matching the actual alias and production import. No compatibility root re-export was added. Leaving the thread open for reviewer verification.
dhruv8sh
left a comment
There was a problem hiding this comment.
Verdict: REQUEST_CHANGES
CI Status
| Gate | Result |
|---|---|
cargo fmt --all -- --check |
Pass |
cargo clippy --workspace --all-targets --all-features -- -D warnings |
Pass |
cargo test --workspace --all-targets |
Pass (2701 passed, 0 failed) |
| GitHub checks | All pass except CodeQL |
Scope note: 526 files (+292k/-14k). Core redirect code and the Axum outbound client were read in full; Fastly outbound and core head/batch/scope/progress/response_egress were scanned for risky patterns.
Blocking
- Spin SDK pinned to the
stackpop/spin-rust-sdkfork (Cargo.toml:110), reintroducing stackpop references removed by #419. Also in the test-harness fixtureCargo.tomlfiles,crates/edgezero-cli/src/generator.rs:1194,1208anddocs/audits/2026-10-27-spin-sdk-eager-progress.md:64. Fix: host the fork under IABTechLab or wait for an upstream release with spin-rust-sdk PR #169. edgezero newwrites the fork git dependency into every scaffolded app (generator.rs:286).- The PR body says "qualification false", with unexplained timing failures, workerd shutdown captures, and open manual hosted checks / HTTP/3 legs. Which must close before merge? Should this be a draft until then?
- Too large to review reliably (589 commits: core API, four adapters, harness, CI, pins, ~68k lines docs). Please split: core outbound -> each adapter -> harness/CI -> docs.
- CodeQL fails with four
rust/hard-coded-cryptographic-valuealerts atcrates/edgezero-test-harness/src/main.rs:2212, 2232, 2247, 2267(likely false positives on fixture nonces). Dismiss with a reason or change the fixtures.
Non-blocking
- Axum ignores
connect_timeout(crates/edgezero-adapter-axum/src/outbound.rs:67,:113,:133-141): only used to label errors; the shared reqwest client never sets it, unlike Spin. The test at:1408passes only because it builds its own client. Apply it or reject it invalidate_options(:150). Proxy-Authorizationsurvives cross-origin redirects (crates/edgezero-core/src/outbound/redirect.rs:403-407). StripPROXY_AUTHORIZATIONtoo and document that other credential headers are kept.- No guard on https->http redirects (
redirect.rs:398); a 307/308 re-sends the body over plain HTTP. Stop on downgrade unless policy allows it. - Host override differs per adapter (
crates/edgezero-adapter-cloudflare/src/outbound.rs:336-340): Spin rejects it, Cloudflare sets aHostheader Workersfetch()likely ignores (unconfirmed). Reject invalidate_supported_options(:3722) or add a contract test. unsaferaw Fastly calls bypass the workspaceunsafe_codedeny (crates/edgezero-adapter-fastly/src/fastly_response_abi.rs:1,outbound.rs:364/393/484), tying the adapter tofastly-sys/fastly-shared=0.13.1. Needs maintainer sign-off and a tracking issue to return to the SDK.- Response header limits default to unlimited (
crates/edgezero-core/src/outbound.rs:1518-1523). Suggest defaults (e.g. 64 KiB / 100 fields). - Many exact
=pins in[workspace.dependencies]; core addscrc32fastandadler2purely as version anchors, risking downstream conflicts. Please document the trade-off. - Test harness is outside the workspace (
Cargo.toml:12), socargo test --workspaceskips it; CI builds it separately (.github/workflows/test.yml:75-87) but the documented gates don't say so. Update CLAUDE.md/gate list or add it to the workspace. - Upload buffering is inconsistent: Cloudflare (
outbound.rs:782-792) and Axum (outbound.rs:330-404) buffer the whole upload up to the cap; Spin streams. Document or stream everywhere. - Unbounded batch size (
crates/edgezero-core/src/outbound.rs:733-789). Add aMAX_BATCH_REQUESTScap. - Missing
LocalSetdetected by catching a panic (crates/edgezero-adapter-axum/src/outbound.rs:291-302); underpanic = "abort"this kills the process. Check for theLocalSetexplicitly. - Axum Cargo tidy-ups:
serdeis a required dep but only used by the config snapshot and one test; the Axum adapter gains a dev-dependency on the Cloudflare adapter, worth questioning.
Praise
Every unsafe block has a SAFETY comment and lint exceptions give reasons. Tokio stays inside Axum and core avoids std::time::Instant. All four adapters disable automatic redirects and decompression. Dependabot groups the audited decoder crates. The PR body is candid about what is still open.
| # https://github.com/spinframework/spin-rust-sdk/pull/169 | ||
| # Return to a released upstream SDK only after that repair and the coordinated | ||
| # source/classifier/progress checks pass; see docs/audits/2026-10-27-spin-sdk-eager-progress.md. | ||
| spin-sdk = { version = "=7.0.0", git = "https://github.com/stackpop/spin-rust-sdk.git", rev = "6c59ed5b4fcb377072763aee0b27a3abdd8edb72", default-features = false, features = ["http", "key-value", "variables"] } |
| "spin-sdk = { version = \"7\", default-features = false }".to_owned(), | ||
| concat!( | ||
| "spin-sdk = { version = \"=7.0.0\", ", | ||
| "git = \"https://github.com/stackpop/spin-rust-sdk.git\", ", |
There was a problem hiding this comment.
Blocking: edgezero new writes this stackpop fork git dependency into every scaffolded app. Same fix as the workspace Cargo.toml pin.
Restore isolated CLI activation, supervised progress tooling, raw qualification telemetry and stable evidence identities. Correct empty Spin request framing, nonce fixtures and documentation while preserving outbound limits, deadlines and ownership contracts. Validation: all five primary Rust gates, 2702 workspace tests, 660 harness tests, 38 tooling tests, isolated CLI compilation and the outbound documentation contract. Full four-adapter/demo and hosted qualification gates remain open.
Summary
Startup Fixture Validation Closeout (2026-11-09)
Latest pushed head:
a7d7fd0f.The test responder now owns its ephemeral listener continuously and publishes bounded PID/nonce/endpoint metadata before the first prescribed request. First-response attestation, sticky failures and the original absolute startup deadline remain intact. Production outbound behavior, hard-cut APIs, pins, limits and capability levels are unchanged.
Details: audit and plan. Manual hosted checks, independent current-head approval, freeze and durable qualification remain open. Existing manual checkboxes and review threads are unchanged. Earlier checkpoint results below are retained as history.
Signed-Origin Image Cache Policy Clarification (2026-11-09)
Pushed
c8fd1939under AG's direct approval. This carries the migration requirements from Trusted Server #1516 without changing production APIs, transport, SDK/runtime pins, deadlines, limits or capability levels.Bypasswithout optimizer options; final optimized GET usesPlatformDefaultwith options. Signing, preflight decisions and private/no-store error rendering stay application policy. No automatic extra fetch or second transport.Plan/checkpoint and verification boundaries. Hosted S3/optimizer checks, previous timing/shutdown failures, candidate freeze, durable Q5 publication and independent acceptance remain open. Fresh GitHub checks are separate. No deployment, thread resolution, dismissal or merge. Maintainer checkboxes are unchanged.
Earlier Checkpoint: Native Timer And Shutdown Investigation (2026-11-08)
Pushed
25114e66. This is a narrow Axum timer repair with co-located tests and audit/changelog updates; public APIs, SDK/runtime pins, capabilities and acceptance limits are unchanged.sleep_until; a paused-time regression fails at 120 ms before the fix and passes at the original 100 ms target afterward. Native early success remains only a wakeup, not logical expiry. Runtime/driver failures and overflow remain typed.kevent; this does not distinguish signal notification from stalled drain propagation. Four separate JavaScript-only controls pass but do not prove bootstrap causation. Temporary tracing/profiling code was removed after retaining captures; no new script, CI probe or profiler dependency ships.RUST_TEST_THREADS=2 bash scripts/run_tests.shexits 1: Axum and Fastly pass, then Cloudflare's real routing probe requires SIGKILL after the unchanged five-second TERM grace. Preserve run18e64816e16e8f68-663-0; no retry is substituted. Four focused native-timer tests also pass on the committed head.Detailed investigation and evidence limits. New-head hosted checks are separate; older green checks are not reused. No deployment, capability promotion, thread resolution, review dismissal or merge. Maintainer checkboxes are unchanged.
Earlier Checkpoint: Local Reuse And Shutdown Closeout (2026-11-08)
Pushed
ebab57ea. This is a test-harness/documentation checkpoint, not a production API or runtime-policy change.Verification is mixed. The full prescribed
RUST_TEST_THREADS=2 bash scripts/run_tests.shpasses, including all four adapter suites, generated app, demo and documentation guards. Harness: 650 passed / zero failed / three opt-in tests ignored. All 30 additional workflow format/lint/WASM/docs commands and the other four primary Rust gates pass.However, separate default-parallel and two-thread workspace runs both exit 101 on the unchanged Axum pending-upload target: 107.941125 ms and 112.950416 ms versus 105 ms. Both failures are retained, not dismissed or called pre-existing. Reduced parallelism is not an established repair; no threshold, assertion or qualification gate was relaxed.
Investigation and evidence limits. Fresh GitHub checks belong to this head and must be read separately; earlier green checks are not substituted. Reviewer acceptance, manual hosted checks, strict timing/cancellation gaps, candidate freeze and durable Q5 remain open. No merge-ready claim, deployment, capability promotion, thread resolution, review dismissal or merge.
This current status supersedes the historical checkpoints below. The maintainer's hosted checkboxes are unchanged.
Earlier Checkpoint: Fastly Callback-Ownership CI Repair (2026-11-08)
Pushed
26612053, a two-file test/changelog repair approved by AG. The original CI failure was reproduced unchanged on repetition 6; forcing a typed timer error reproduces it deterministically. The test incorrectly treated per-exchange timer destruction as callback closure, although an early connection error must release that timer immediately.The repaired test observes the managed callback scope and exactly-once callback-family resource release, covers standalone/wrapped helpers with pending/failed timers, and retains the post-callback batch
Internalassertion. Existing deterministic pending-driver cleanup tests remain unchanged. No production code, APIs, pins, deadlines, limits, assertions, capability levels or qualification gates were relaxed.RUST_TEST_THREADS=2 bash scripts/run_tests.shattempt exited 1 when the Cloudflare ingress fixture required SIGKILL after the unchanged five-second workerd shutdown grace. The unchanged retry exited 1 because Fastly smoke returned 2:custom_lazy_initialization_recoverywas unverified because all five callbacks were not observed in one guest. These failures are retained; their causes are not established and are not labelled pre-existing, waived, or converted to passing results.Fresh GitHub CI is running separately at
26612053. This is not an all-green or merge-ready claim. Existing review dispositions, manual hosted checkboxes, strict timing/cancellation gaps, candidate freeze and Q4/Q5 qualification remain open; no deployment, capability promotion, thread resolution or merge occurred.Approved Qualification Amendments (2026-11-08)
Implemented in
dcbf622funder AG's direct approval:The current handoff records current-head checks, per-thread replies and remaining review decisions. Older checkpoints below retain their historical status; they are not current completion claims.
TS Reposted Review Repairs
The six reposted TS findings are repaired in
6f0cc74c, with a separate fixed reply and executed evidence in each original thread. Reviewer acceptance remains pending; no thread was resolved by the author, and other reviewers' threads are untouched.The scoped changes complete nonblocking Fastly buffered readiness through head/data/EOF and cooperative yields, add routed AC2 expiry coverage and bindings, restore the positive Rust deferral regression, and correct the remaining checklist, idle-policy and acceptance-reference text. Public outbound contracts, hard-cut APIs, SDK/runtime pins and qualification limits are unchanged.
Validation at the exact committed head passed: all five primary Rust gates; the complete
bash scripts/run_tests.sh; and the 33-command lint/build/docs matrix covering adapter feature selections, all three WASM targets, fixtures and demo. Workspace: 2685 passed, zero failed, one existing ignored, 33 binaries. Harness: 626 passed, zero failed, two existing ignored. All four local adapter integration suites and the generated-project gate passed. The deferral spelling mutation failed as intended and was restored before the commit.The initial terminal-stdin interruption and the local Cloudflare tool-version failure are retained; the final committed-head run used noninteractive stdin and the ingress fixture's lock-matched wasm-bindgen. Fresh GitHub checks are running; they are not declared fully green. This is local validation, not a frozen or hosted qualification record.
Qualification remains open: the strict local lifetime run retained cold Begin at 8548 us against the unchanged 7000 us bound. SDK parity, unknown optimizer blocking horizon, manual hosted evidence, candidate freeze and Q4/Q5 are not waived. No deployment or capability promotion was performed. The manual hosted checklist below is unchanged.
Implements the portable outbound HTTP and request-lifecycle contracts across core and the Axum, Cloudflare, Fastly, and Spin adapters.
start_batch_until, indexednext, explicitcancel, orderedcollect, and thesend_all_untilconvenience path.start_batch_untiltakes an observation cutoff: reaching it stops observation even when individual slots retain budget, while earlier cutoffs remain a supported partial-result operation.PlatformMetadatafacts for memory ceilings, live inbound request population, and host-ingress accounting, preserving source and explicit unknown reasons.Fits,Exceeds, and typedIndeterminateoutcomes; publishes canonical Axum, Cloudflare, Fastly, generic Spin, and Akamai Functions profiles.CompletedorCutoff. OnlyCutoffpermits unresolved slots in a successful result. Explicit adapter failure, premature driver EOF, and duplicate or out-of-range indices returnOutboundBatchFailure, preserving the precise error and every terminal slot collected before failure.MonotonicClock::deadline_afteranchors relative cutoffs to that clock. Equality expiry wins and backwards time fails closed.ResponseEgressCompletion, transferred directly throughPreparedIngress,ResponseEgressEnvelope, and the soleResponseEgressAttempt. Terminal state is stored before the response-scoped completion and global observer run, each exactly once and behind independent panic boundaries. No response-extension carrier or envelope extraction bypass remains.ResponseEgressCompletion::joincomposition so independent response-owned resources share one exactly-once terminal report, and hard-cuts detached normalized errors toSend { completion, deadline } | Abortwith request-start-relative bounded deadlines.AdmissionDecision::Abort. Axum closes the owned HTTP/1 connection before body polling; Cloudflare, Fastly, and Spin return a fixed provider error at their strongest available pre-response boundary and remain conservatively classifiedBestEffort.Hooks::configureplus core-ownedApp::build::<A>(platform). Successful hooks must preserve the complete adapter-selected metadata; core rejects changed facts instead of restoring them. Typed configuration failures propagate unchanged and stop serving before request handling. The generated scaffold keeps finite ingress policy with core-owned empty lifecycle tokens; the checked-in demo retains the full application-owned resource-composition example.AbortController, Fastly's low-levelstream_to_client, and Spin's WASI response/body/result writers.Current Checkpoint: Event-Driven Workers Cancellation
Head:
9b31a697, including maincf2c57b1. Implementation and evidence boundaries.The PR is ready for review, not draft, but remains unqualified. Historical checkpoint references to draft status describe their then-current state; they are not the live PR state.
9b31a697retains 17 passed/two failed constituent scenarios, exit 1, plus failed tail validation. Cold Begin is 8 ms >7 ms; ordinary-close cancellation/cleanup is unproved. These map to 12 passed/two failed lifetime legs. All previous failures, including the preceding6e5ce765capture, remain retained; no warmup, tolerance change, reset substitution or retry-for-credit.NameInUsefail-closed rather than adopting unverified settings. Hosted controls and maintainer re-review remain open. Other non-blocking review suggestions are not silently marked resolved.Local unqualified review packet:
/private/tmp/pr275-9b31a697-closeout.tar.gz, SHA-256878876dda65f8404af5b75215631e4402c5dce80f8b73a11e0080ac5c17faa3f. It retains 52 hashed payloads plus their manifest, actual raw failures/builds, the caught fixture-ordering failure and final verification. Temporary retention is not durable Q5 publication. New-head CI runs separately; no prior-head green check is relabelled as new-head proof. Your eight manual hosted checkboxes are unchanged. No deployment, final freeze, capability promotion, review dismissal or merge is performed.Earlier Checkpoint: Workers Batch Cutoff
Head:
8f82547b. Repairs a confirmed adapter-owned scheduling gap without changing public APIs, request budgets, capability levels or SDK/runtime pins. Specification, regression and native-evidence boundaries.The local review packet contains 99 hash-verified files:
/private/tmp/pr275-cutoff-coordinator-packet.tar.gz, SHA-25627837dc0fdb5785550ced06f7666e58091508e9ac64bbd11c884d2755195be68. It preserves RED/GREEN and final verification logs, the actual native patch/build and all failures, separately from the final source patch. Temporary local storage is not durable qualification. Demo/templates require no signature migration and inherit the adapter repair. No deployment, freeze, merge or maintainer review-state change is performed; the eight manual hosted checkboxes below are unchanged. New-head CI must execute separately.Earlier Checkpoint: Exact-Head Evidence Mapping
Tracking commit:
46019b2d. This documentation-only checkpoint maps evidence for reviewed source562acc1dedbf169315853900f9395e7ff5160076; it does not freeze or qualify either revision. Audit and evidence boundaries.12287f9f; Cloudflare/Spin do not embed a source SHA. The 30 successful checks associated with reviewed head562acc1ddo not establish exact-head runtime qualification.The local review packet contains 231 hash-verified files:
/private/tmp/pr275-562acc1d-closeout-packet.tar.gz. SHA-256:d96a6a50a80b87dad910fe43e2ca71d53ea887f7711d83cc5d26867af56fc4d6. It retains the original metadata draft separately, corrected pre-freeze record, complete derived leg map, raw captures/builds and supporting CI crosswalk. This temporary archive is not durable Q5 publication. Source APIs, adapters, demo/templates, SDK/runtime pins and outbound guarantees are unchanged. No deployment, freeze, merge or change to the maintainer-managed PR review state is performed. The eight manual hosted checkboxes below are preserved unchanged.Earlier Checkpoint: Workers Timer Setup Repair
Head:
562acc1d. The reviewed repair, regressions, specification, driver plan and changelog are committed and pushed. Source is clean. Investigation and evidence boundaries.Hosted CI at this update: 30 successful / 0 neutral or skipped / 0 running or queued / 0 failed reported checks. Local verification is not a substitute for unfinished hosted checks.
A separate, hash-verified review packet contains 111 files preserving raw controls, temporary instrumentation, RED/GREEN logs, final verification and exact-commit runtime artifacts. Packet SHA-256:
00a5573ac25d504e50e1953bb585ffb043b04a7d10bb6a440268bc0e78e6eb25. Lifetime Wasm SHA-256:e4730e8f068c15ac35b7c7e28e70327fb06097d787eee7eba60fa6ac26c6c6bd. Prior macOS/Linux failures and earlier packets remain retained separately; diagnostic passes are not copied into release evidence. Local temporary storage is not durable Q5 publication.No public API, SDK/runtime pin, capability, application policy, deadline, observation cutoff or tolerance is changed. Demo/template APIs remain unchanged. No deployment, candidate freeze or merge is performed; this PR remains draft. Hosted verification remains the maintainer's checklist below.
Maintainer Hosted Verification (Manual)
The maintainer will perform and check off these hosted gates manually. No deployment is delegated. Record the exact candidate SHA and link durable evidence; unchecked means unverified, not passed. Keep documented BestEffort/Unsupported limitations unless stronger behavior is actually proved.
Local CI, parser replay and native diagnostics do not check off these hosted gates. Acceptance identities and remaining local failures stay unchanged.
Earlier Checkpoint: Completed-Test Host-Diagnostic CI Repair
Head:
f82e4025. The prior head has 29 successful checks/one failed Fastly job. Its native library reports 309 passed/zero failed, but a known host diagnostic is concatenated directly after a complete namedok; the sentinel guard incorrectly rejects that line. This checkpoint changes only that guard, its co-located tests and tracking docs.fastly-lifecycle-evidenceartifact and fail-first regressions: 103 pass/6 expected failures, covering two formats and four exact inventory environments.okimmediately followed by the existing anchored timestamped Viceroy diagnostic. Reject arbitraryok...suffixes, malformed/missing timestamps, unrelated diagnostics, failed/ignored statuses and wrong names. Preserve every sentinel, listing checks, positive zero-failure summaries, and command/stream exit handling. No workflow, invocation or inventory change.See the repair and verification tracker and original failing job.
Earlier Checkpoint: Absolute Deferred Batch Dispatch
Head:
158b0c0e. This checkpoint corrects the existing lifecycle fixture, not production outbound behavior. APIs/adapters, SDK/runtime pins, original deadlines, caps, acceptance identities and capability levels remain unchanged.DeadlineExceeded1,001 ms, original per-call deadlines 1,034 ms. The complete local suite still exits 1, with 16 pass/3 fail plus a final-log-tail failure: cold Begin entry 9 ms, pending-body cutoff 206 ms, and ordinary-close cancellation remain unqualified. Pending-head cutoff returns at 204 ms in this run; earlier failed observations are not erased. Retain the initial missing-workerd preflight as unverified exit 2.See the current tracker and audit.
Earlier Checkpoint: Native Spin Result Before EOF
Head:
8fbc4f83. This checkpoint changes the existing Spin SDK controls, validation and retained evidence only. Production APIs/adapters, SDK/runtime pins, original deadlines, acceptance identities and capability levels are unchanged.See the native record, pinned source analysis and implementation tracker.
Earlier Checkpoint: Explicit Reset Diagnostic
Head:
cd214362. This checkpoint changes test tooling and evidence only. Production outbound APIs, adapters, SDK/runtime pins, original deadlines, caps, acceptance identities and capability levels are unchanged.RequestCancelled, exactly-once SDK/source release, healthy survivor work and a clean diagnostic tail. Ordinary close still fails, with no victim terminal through the original coordination window. Reset success is diagnostic only, not a replacement acceptance gate.See the current diagnostic and runtime tracker.
Earlier Checkpoint: Native Runtime Boundaries And Linux Connect
Head:
f036425b. Production adapters, public APIs, provider pins, deadlines, caps and original acceptance identities are unchanged.defaultsocket in the existing Workers fixture launcher using the pinned Miniflare API. No entry-forwarding fallback; the SDK entry/control listener remains on a distinct ephemeral loopback port. Guest flags, modules, bindings, persistence and owned shutdown remain intact. Standard serve/deploy paths are unchanged.qualified:false; external, conditional and unpromoted scope is unchanged.See the current tracker and canonical Linux connect evidence.
Earlier Checkpoint: CI And Local Lifecycle Repairs
Head:
22c6386c. All 217 required-local acceptance legs now have executable bindings (255 criteria/511 legs; 246 ready/265 planned overall). Binding completeness is not passing runtime qualification. External, conditional and unpromoted scope remains unchanged.See the current implementation and evidence tracker for exact observations and remaining gates.
Earlier Checkpoint: Fastly Post-Delivery Batch
Head:
775366fd. Extend the existing D6 lifetime suite with a three-slot batch created after canonical response handoff, using the same retained client and original request clock. Preserve 34 ms batch entry, 534 ms cutoff and one-second per-call timeouts. No production API, SDK/runtime pin, capability or CI invocation changes.Earlier Checkpoint: Fastly Trickling Slots And Live-Batch Send
Checkpoint
f0ce2b38adds EZ-6 criteria 7/8 to the existing Fastly fixture and lifetime suite. Production outbound APIs, transport, scheduler, deadlines, limits, SDK/runtime pins and CI invocations are unchanged.See the master/D6 tracker, SUITES.md and changelog for exact scope and retained results.
Earlier Checkpoint: Fastly Origin-Body Arrival Coverage
Checkpoint
eb8ac5dfadds the missing EZ-6 criterion 6 case to the existing Fastly lifetime suite. No new runner, transport, scheduler, SDK probe, production API/policy, pin or CI invocation.See the current master/D6 tracker, SUITES.md and changelog for exact scope and evidence.
Earlier Checkpoint: Fastly Native Body-Readiness Witness
Checkpoint
5950548dadds the distinctly labelled, request-owned test-only Fastly native readiness witness. Production outbound APIs, deadlines, B31 policy, limits, SDK/runtime pins and CI invocations remain unchanged.See the implementation tracker, SUITES.md and changelog for scope and retained evidence. Demo/templates require no migration for test-only metadata.
Earlier Checkpoint: Spin Native Pending-Body Witness
Checkpoint
92e03fe8extends the existing request-owned, test-only native witness to Spin. Production outbound APIs, transport, deadlines and resource policies are unchanged.See the implementation tracker, SUITES.md and changelog for the verified scope and retained evidence. Demo/templates need no change for this test-only integration.
Earlier Checkpoint: Cloudflare Native Module Manifests
Checkpoint
deb00840repairs the existing local launcher for the selected Wrangler 4.131.0 / Miniflare 5.20260910.0-alpha / workerd 2026-09-10 combination. Production outbound APIs and adapters are unchanged.persist/v3layout, startup attestation, private diagnostics and owned disposal. Both smoke modes pass, including seeded config, declared-KV and outbound-progress checks. A separate bounded local diagnostic proves namespace...02survives process restart and is read before another write.See the current implementation tracker and SUITES.md for exact scope, checks and retained evidence.
Earlier Checkpoint: Native Pending-Body Witnesses
Checkpoint
3523e121adds finite, request-owned test-only SDK observations on Axum and Cloudflare. Prepared URI, clock, mode and budget come from shared dispatch; production policies are unchanged.CI follow-up
c6f3aaf0uses canonicalobservation_cutoffnaming. The unchanged guard, 28 Axum contracts and strict lint pass locally; all 30 reported checks passed at that checkpoint.next, beforecollect. Require full controller-selected target/origin identity, Batch/BatchCutoff, the original deadline, Pending before cutoff and release between cutoff and return. Preserve 34/200/205 ms targets and zero-head/read control.rootPathagainst the owned config directory with sanitized errors.modulesRules. Failed runs get no credit; SDK-reader unit tests do not substitute for actual fetch/runtime proof.See the implementation tracker and SUITES.md for exact checks and retained failures. The prior Fastly dispatch checkpoint retains its SDK-dispatch-only scope and three guarded proofs.
The previous focus compiler checkpoint added numeric and compiler ownership through the existing grouped Rust check; its 434-test harness and other verification remain recorded separately, not relabelled as fresh evidence. Earlier provider-boundary proofs, typed-focus approval/CLI lint, audit formatting and tooling consolidation retain their scopes and open gates.
Earlier Checkpoint: Registration Observations And Connect Capabilities
outbound-connect-timeout: Fastly declares independent provider-backed support as Native; Axum, Cloudflare and Spin retain BestEffort acceptance. Fastly's split-free flexible phase budgeting is Native. These declarations do not qualify hosted connect precision, DNS/TLS coverage, blocking-call preemption, deadlines or cancellation.Checkpoint:
2cbbc549, following registration observations at00a9edbd. The implementation tracker records exact scope, evidence and remaining gates. This checkpoint is historical; current readiness and check status are recorded above.Earlier Checkpoint: Response-Owned Outbound Handoff
Checkpoint:
abbc2c11. Detailed local artifacts and failures are recorded in the D6 response-handoff tracker checkpoint.Earlier Checkpoint: Core Mixed-Observation Acceptance Binding
EZ-6/acceptance/22@unit/core, replacing its placeholder with five executable receipt/accumulator proofs. Run six exact three-slot cases: fresh and mixed check/next/collect under Completed, Cutoff and an original typed driver failure. Stage terminal production after both mixed receipts transfer.--lib outbound::; discover all 56 exact sentinels, including the original 51 redirect proofs. No new job or per-test CI list. The old redirect-only selection fails before execution because it omits the five batch proofs. Use the shared raw Cargo log path without relabelling older evidence.Checkpoint:
279c5a93.Earlier Checkpoint: Buffered Cap During Batch Progress
caps-while-waitinglifetime case through the production clients: 128 KiB decoded gzip trickling over 300 ms, independent 1 MiB decoded / 64 KiB buffered / 256 KiB encoded limits, healthy B/C siblings, and the original 34/534 ms batch timeline.Checkpoint:
8c11307d. Final local artifacts and individual failed timing preconditions are recorded in the D6 buffered-cap tracker checkpoint.Earlier Checkpoint: Reviewed Spin SDK Integration
6c59ed5b4fcb377072763aee0b27a3abdd8edb72(WASIp3 0.10.0 / wit-bindgen 0.63.0). Align the root, demo, reusable/request-fidelity fixtures, generator and all four application lockfiles.Checkpoint:
87b5e1ce. These are local regression results, not a frozen candidate or hosted qualification. D6 closure, native body-entry evidence, consumer acceptance and hosted qualification remain open. The acceptance inventory remains 32 ready / 479 planned and unqualified.Earlier Checkpoint: Fourth-Slot Per-Call Expiry
Implemented in cd8e77e4, within the approved D6 acceptance work:
Earlier Checkpoint: Readiness-Driven Test Origins
Implemented in d3f48564, under the requester's scoped fixture-accept approval:
CI diagnostic follow-up 11b8f2c4 adds underlying errors to two existing request-fidelity version-test assertions. The prior Linux workspace failure occurred before the collector tests; its OS/process cause was not exposed and remains unproven. The fresh run passes both the request-fidelity step and the complete shared-harness tests on Linux. No test conditions, retries, version policy or subprocess behavior changed; other CI checks and provider qualification remain separate.
Earlier Checkpoint: Same-Client CPU Calibration
Implemented in 0d09236a, under the requester's scoped calibration approval:
Earlier Checkpoint: CPU Stretch Characterization
Implemented in 44baaf3b:
Earlier Checkpoint: Pending Cutoff Lifetime Probes
Implemented in 73ed39ba, following the main integration:
host-head-written-only, not proof that the SDK consumed headers or entered a body read. Full criterion 16, remaining D6 work and hosted qualification stay open. Production outbound code, signed SDK/decoder pins, frozen requirements/interfaces and capability levels are unchanged; inventory remains 32 ready/479 planned and unqualified.Earlier Checkpoint: Coordinated Spin SDK Executor Upgrade
Implemented in 7b68f737:
e65ff90dadf4173b08b14194e878ad3acd555337; its DCO check passes. Upstream Rust 1.94 CI remains separate from local Rust 1.98.1 verification.spawn_local. Root, demo, reusable fixture and generator use identical Git URL/revision and package version; guards compare all three. Lock changes stay within the affected SDK/bindings/macro graph. Decoder/map contracts remain unchanged.qualified: false; full acceptance binding, candidate freeze and authorized hosted qualification remain open.Earlier Checkpoint: Begin/Batch Lifetime Probes and SDK Gap
Implemented in 834a009e:
wit-bindgen 0.57.1.qualified: false. CPU-stretch, remaining lifetime/registration/consumer acceptance, candidate freeze and authorized hosted qualification remain open.This is a verified test/diagnostic checkpoint, not a passing full lifetime suite or completed feature qualification.
Earlier Checkpoint: Standalone Test Harness and Redirect Bindings
Implemented in b5f94c70:
crates/edgezero-test-harness, with a non-published standalone workspace and its own lockfile. Remove the old runner package/directory without an alias or duplicate implementation. Keep deployable fixture apps separate and unit/contract tests in their owning crates.qualified: false. Readiness records executable assertions, not consumer adoption, applicability approval or exact-candidate qualification.This completes the approved runner relocation and local redirect binding checkpoint, not the whole adoption plan. Lifetime/registration acceptance, successful native optimizer transformation/redirect/performance evidence, consumer integration, candidate freeze and authorized hosted qualification remain open. Optional idle-body policy is not silently adopted. No deployment, capability promotion or production outbound behavior change occurs.
Earlier Checkpoint: Local Workerd Redirect Acceptance
Implemented in 4e64db99:
outbound-wirematrix and bounded two-origin servers as Spin. A fixture-only route obtains the production client from the canonical request context; no Fetch replacement, parallel outbound transport or new host-language runner is used.Successful native optimizer redirects, conditional idle-policy coverage, complete criterion-level binding and consumer/hosted acceptance remain open. The inventory remains eleven ready legs, 500 planned and
qualified: false.Earlier Checkpoint: Rust Spin Wire Harness
Implemented in 361da4f1:
--adapter spin --suite outbound-wirein the existing Rust fixture harness. No Python or Node replacement runner, compatibility wrapper, dependency changes or second process supervisor remains.This checkpoint is test-tooling only. No hosted deployment, capability promotion, candidate freeze or optimizer performance claim is made. The inventory remains eleven ready legs, 500 planned and
qualified: false.Earlier Checkpoint: Provider Redirect Boundaries
Implemented in 699cd49c:
Workerd/origin parity, successful optimized-first-hop redirects, conditional idle-policy coverage, complete criterion-level acceptance binding, candidate freeze and consumer/hosted qualification remain open. Native optimizer dispatch is preserved; unavailable-boundary controls do not establish transformation or performance. No deployment is performed. The inventory remains eleven ready legs, 500 planned and
qualified: false.Earlier Checkpoint: Fastly Cooperative-Wake CI Repair
Implemented in f57b8130:
qualification: false.Still open: provider-runtime redirect acceptance, exact-candidate criterion bindings, resource-policy decisions and consumer/hosted qualification. All previous outbound guarantees and direct native Image Optimizer integration remain intact.
Earlier Checkpoint: Explicit Redirect Following
Implemented in e02c2360:
HttpClient::followAPI with a required synchronous application policy and validated 1..=20 redirect limit. Plain Send, Begin and Batch remain unfollowed.Still open: other provider-runtime Follow parity, actual Fastly optimizer-hop mapping, consumer composition, exact-candidate criterion bindings, resource-policy decisions and hosted qualification. The inventory remains eleven ready legs, 500 planned and
qualified: false. No deployment or capability promotion occurred, and the PR remains draft. Current tracker.Earlier Checkpoint: Shared Outbound Pipeline and Ownership
Implemented in 2be1dd87:
Open at that checkpoint: explicit same-client redirect following (now implemented in the checkpoint above), remaining exact-candidate acceptance bindings, resource-policy decisions and hosted qualification. Local runtime evidence does not promote capabilities or prove end-client delivery. The PR remains draft. See the current tracker.
Earlier Checkpoint: Live Paired Time
Implemented in d86d4c0d, with the isolated Cloudflare test-ordering correction in f4d660b1:
with_time/ Axumtry_with_time, removing clock-only constructors without aliases.OutboundTimefor live asynchronous deadline handling. Check timers before source polling, preserve operational errors and diagnostics, retain clock high-water observations across chunks/yields, and release terminal/cancelled ownership.This completes only the approved sequencing checkpoint. The public head-first trait, settlement/context issuance, batch receipts, eager Begin, redirect integration and hosted qualification remain open. Requirements and frozen Plan 02 hashes are unchanged. See the verification audit.
Earlier Checkpoint: Bounded Synthesized Headers
Added in
d47c8026:This checkpoint is not completion of the broader adoption plan or hosted qualification. The full head-first/eager/redirect migration, Fastly's failed G2 preserving-read proof, all nine failed Fastly framing SDK parity controls, Cloudflare overflow recovery, consumer integration and exact-candidate hosted qualification remain open. No capability is promoted, no compatibility layer is restored, and the PR remains draft.
Reviewer correctness follow-up
Addressed R1–R4 in
92111839:Main merge and shared-policy follow-up
Addressed R5 and R6 in
91f4af38, merging main683202c6without restoring superseded APIs:OutboundBatch::from_futures; adapters retain preflight validation, exchange ownership, clocks, and terminal samples. Ready results remain retained, driver EOF/index invariants remain enforced, and cutoff releases pending futures before reporting termination. Fastly retains its distinct provider-handle driver.ResponseBodyPolicyandapply_response_body_policy, preserving declared-length checks, encoded limits, decoding/header rewriting, decoded limits, passthrough, and rechunk order. Transport reads, bodyless handling, deadlines, cancellation, and final buffering remain adapter-owned.Result<(), E>through a wrapper that prevents SDK-generated second responses.R7's dependency-audit-script deduplication remains deferred; dependency contract checks remain unchanged and pass.
Bounded native ingress and config follow-up
ConfigValuereturns. Axum constructors requireConfigStoreLimits;from_mapis fallible. Reads share payloads, and local config push updates require a server restart.serde_json 1.0.150, hash canonical JSON incrementally, and release extraction's raw handle before secret retrieval. A moving-reallocation malformed-root probe measured 36,428 requested peak bytes under a 100,060-byte staging cap, with zero retained bytes after rejection.Unsupportedand response egress remainsBestEffort. Local emulators and guest contract tests are not deployed runtime evidence.Bounded provider reads and lifecycle qualification infrastructure
FinalizationRegistrycleanup support. Generated and demo Workers explicitly enableenable_weak_ref, and regression tests inspect their TOML rather than assuming an exact one-flag string.try_opennow returns typedConfigStoreError.Downstream acceptance impact
Cloudflare
outbound-deadlinesandstreamed-upload-deadlinesareBestEffort, notNative. Downstream acceptance suites must use best-effort deadline wording and must not claim exact cancellation enforcement until deployed host-observed evidence exists.The response completion, ingress abort, and fallible application-assembly changes are intentional breaking changes. Consumers must provide a completion on every response-producing admission decision and propagate
App::build::<A>(platform)failures.Evidence boundaries
Capability declarations remain conservative where provider behavior is not proved:
Unsupportedon all adapters.Nativeon Axum andBestEfforton Cloudflare, Fastly, and Spin because finite host-side teardown is not proved or synchronously preemptible.Nativeon Axum's owned HTTP/1 connection andBestEfforton Cloudflare, Fastly, and Spin because provider transport reset/close is not directly observable.BestEfforton every adapter because no boundary proves end-client receipt; provider-specific blocking and teardown limits are documented.Unsupported; provider parsing/materialization, SDK copies, informational responses, trailers, allocator overhead, and other host-owned memory remain outside guest-visible caps.BestEfforton every adapter because provider operations are not proved cancellable within a finite wall-clock interval.BestEffortpending a deployed host-observed cancellation artifact. Fastly and Spin retain their separately documented deadline and isolation limitations. Fastly declares split-free phase budgeting Native; its independent connect setting remains unqualified for hosted timing precision.Validation
This checklist records validation across PR checkpoints. The exact latest reruns and remaining acceptance failures are listed above; it is not a claim of hosted qualification or a fresh run of every historical matrix.
scripts/run_tests.shcargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-features -- -D warningscargo test --workspace --all-targetscargo check --workspace --all-targets --features "fastly cloudflare spin"Closes
Closes #109.
Closes #113.
Closes #147.
Closes #148.
Closes #436.
TS cutover follow-up, November 11
Adds an optional read-only received-head preparation callback for structurally validated input. Applications retain authenticated facts before native sanitation; this cannot read a body, change headers, bypass admission, or return a response. Existing admitted pre-dispatch hooks retain their timing.
Current head:
410a16238b7cb740275ad69b9af628cd52c57bdc.Local combined-RC qualification at
36f8e9c9c2c93661aaa73f2ca956cec3bc9e4c92: workspace tests 2,947 passed / 6 ignored; all-feature Axum 568 passed, including 36 production-hosting, 6 AWS startup and 4 celld startup cases; core doctests 19 passed / 13 ignored; strict workspace Clippy, formatting, feature compilation and Spin WASM check passed under Rust 1.98.1. Narrow TS consumer proof under Node 24.20.0: all four real proxy tests and typed prepared config/secrets/router startup passed. This is not final TS-stack/image/deployment qualification. Fresh hosted checks are still required.Retained callback-scope fixture follow-up
Commit
14a6ca8bb5a5cbe055a1f725bdab8f42569a3bf0removes an IO-timing assumption fromretained_client_resolves_fresh_callback_scope. The original test failed locally on repetition 3 because both observed batch slots could already be complete after a legitimate loopback refusal. The fresh-callback observation is retained, then a new unpolled batch is retained for the unchanged stale-scope Internal assertions. Callback count remains exactly two. Production code, deadlines and completion semantics are unchanged. All 20 fixed filtered repetitions, the complete 325 Fastly WASM unit tests and strict Fastly WASM Clippy pass with the explicitly repaired local Viceroy. Fresh hosted verification is running.