Skip to content

September release candidate (DO NOT MERGE) - #1112

Draft
ChristianPavilonis wants to merge 714 commits into
mainfrom
rc/202609
Draft

ChristianPavilonis wants to merge 714 commits into
mainfrom
rc/202609

Conversation

@ChristianPavilonis

@ChristianPavilonis ChristianPavilonis commented Sep 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

September release candidate.

This PR is an integration branch for release-candidate validation. Do not merge it into main.

RC head 6c87bfb8f. main is fully contained (0 commits behind).

Merged PRs (milestone 202609)

Eighteen milestone PRs are already merged into main and inherited here. All are verified
present in this branch.

Release blocker: unreleased EdgeZero dependency. All six EdgeZero crates are pinned
to rev = "12c3215c", an unmerged commit on
EdgeZero PR 381, not a release tag.
v0.0.8 is still the latest tag. This RC cannot ship until that PR merges and the pin
moves to a tag. The pin moved five times during integration, so re-verify the lock
immediately before any release build.

Review status: fifteen of the sixteen included PRs are not approved. Only #900,
#901, #902, #903, #1157 and #1159 carry an approving review. The rest carry
CHANGES_REQUESTED and were merged here so the milestone could be validated as a whole.
Their inclusion is provisional and does not mean the review feedback was addressed.

Contents

Milestone 202609 has 17 open PRs. Sixteen are integrated here; #1179 is not.

PR Review Status in RC
#900 approved included
#901 approved included
#902 approved included
#903 approved included
#1157 approved included, EC stack tip
#1159 approved included
#1052 changes requested included
#1074 changes requested included
#1076 changes requested included
#1107 changes requested included
#1121 changes requested included
#1137 changes requested included
#1154 changes requested included
#1169 changes requested included
#1175 changes requested included, carries the EdgeZero pin
#879 changes requested included, see the note below
#1179 changes requested not merged

That accounts for all 35 PRs carrying the 202609 milestone: the 18 merged through
main listed above, 16 integrated here from open branches, and #1179 excluded.

Exclusions and caveats

#1179 pins a diverged EdgeZero revision. Its c4841b60 is 7 commits ahead of the RC's
12c3215c but 62 behind. Those 62 contain the whole Fastly store-selector series that
#1175 depends on, including fix(fastly): apply canonical store selectors at deploy and
feat(fastly): load runtime config by service version. Merging it would roll the
dependency back and revert #1175 at the dependency level. It needs rebasing onto the
current pin.

#879 is included, with one of its tests changed. Its
config_push_does_not_use_the_runtime_key_override_without_the_key_flag asserted that a
runtime EDGEZERO__STORES__CONFIG__<ID>__KEY override must not move where ts config push
writes, and that only an explicit --key flag should. That holds under EdgeZero v0.0.8,
which #879 was written against, and the test passes on its own branch. It does not hold
under 12c3215c, the pin this RC carries: with the env var set and no --key flag, the
push writes to active_config instead of the default blob key. Verified by instrumenting
the assertion to print the keys actually written.

config push is entirely edgezero_cli, so this behavior cannot be changed from this
repository. The test was renamed to
config_push_follows_the_runtime_key_override_without_the_key_flag and now asserts what
the pinned runtime does, with a comment recording that this is a behavior change from
v0.0.8 rather than the intended contract. This is worth upstream review on EdgeZero
PR 381 before the pin moves to a release tag:
an operator exporting that variable for
runtime reasons now also redirects their config pushes.

Conflict resolution

Conflicts were resolved as three-way merges. Each conflicted file was audited by commit
subject to establish which side carried work the other had never seen, because several
RC-side features postdate the branches. Resolutions worth reviewing:

Semantic conflicts that auto-merged without markers

Four breakages merged cleanly at the text level and were caught only by compiling and
running the suites:

  • AuctionCollectDeps gained timings and placement on the RC side while main's new
    parser-seam streaming tests constructed it without them (E0063). Both sites now pass
    RequestTimings::new() and AuctionWaitPlacement::InStream.
  • platform/timed_kv.rs overrode only count_keys_with_prefix after the EcKvStore
    trait made list_keys_with_prefix required and the former a provided default (E0046).
  • settings.rs kept both sides' copies of the same two consent-store tests (E0428).
  • Split origin shareability from template eligibility, and add the readthrough evidence gate #1169 added a NamedRoute for /_ts/admin/cache/purge without the route_class field
    the RC's access telemetry requires. It is RouteClass::Other, since unlike the sibling
    admin routes it does not operate on Edge Cookie state.

A fix was also pushed to #1157's own branch (bd0b83a98): its rebase onto main left the
EidConflictEcKv test double missing list_keys_with_prefix, failing trusted-server-core
under cfg(test) and taking cargo fmt down as a cascade.

Verification

Run locally against the merged branch before each push:

Gate Result
cargo fmt --all -- --check pass
8 clippy targets (fastly, axum, cloudflare, cloudflare-wasm, spin-native, spin-wasm, cli, codegen) pass
cargo test-fastly 2920 pass
cargo test-axum / test-cloudflare / test-spin pass
ts CLI suite pass
cross-adapter parity 17 pass
npx vitest run 1179 pass
JS and docs format pass
browser integration (Playwright, nextjs) 21 pass, 1 skipped

ChristianPavilonis and others added 26 commits September 4, 2026 10:33
# Conflicts:
#	crates/trusted-server-cli/src/commands/audit/mod.rs
#	crates/trusted-server-cli/src/commands/config/init.rs
#	crates/trusted-server-core/src/config.rs
#	crates/trusted-server-core/src/integrations/js_asset_proxy.rs
#	crates/trusted-server-core/src/integrations/mod.rs
#	crates/trusted-server-core/src/platform/test_support.rs
#	docs/guide/getting-started.md
#	docs/superpowers/specs/2026-04-01-js-asset-proxy-design.md
#	docs/superpowers/specs/2026-06-22-ts-audit-js-asset-proxy-config-design.md
#	trusted-server.example.toml
Preserve JavaScript asset proxy candidate generation in the relocated
audit generator while retaining ad-template slot discovery.
Chrome opens several sockets per navigation: the document request, socket
pool preconnects that close without sending anything, and speculative
/favicon.ico, /robots.txt and /sitemap.xml fetches. The GPT fixture served
exactly one accepted connection and panicked on a connection that carried
no request, so whenever a preconnect won the accept race the listener was
gone before the navigation landed and the collector failed with
net::ERR_CONNECTION_REFUSED.

Replace the one-shot fixture with a server that accepts until the returned
guard is dropped, answers each connection on its own thread so a silent
socket cannot stall the document request, and treats a request-less socket
as normal. Cover both failure modes with tests that need no browser.
The set-tester endpoint minted the ts-tester cookie without Max-Age or
Expires, making it a session cookie. Safari deletes session cookies when
the browser quits, so Safari testers silently fell back to the baseline
arm on every restart. Add a 30-day Max-Age; /_ts/clear-tester already
expires the cookie explicitly and is unchanged.
Return empty 404 responses for speculative fixture requests and wake the
blocking acceptor on shutdown. Pin routing with real speculative paths.

Share the generation settle budget across initial, post-scroll, and GPT
waits while retaining a snapshot after exhaustion. Document the shared
budget and the two-empty-poll shortcut, with Chrome regression coverage.
Conflicts: publisher.rs (origin span now wraps the early-dispatch
pending-origin wait as well as the direct send, still dropping before
the abandonment-telemetry branch), main.rs (EdgeZero env parameter
threaded through the AppBuild span block and the finalize signature
gaining both mut ec_state and timings), app.rs (both sides' test-module
additions kept).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rface

Review round 3, the blocking route finding plus the config items:

- Publisher route templates now come from an operator allowlist
  (observability.route_sections, default empty): a first segment that
  matches an entry and has further depth emits the lowercased allowlist
  entry as /{section}/*; everything else emits /other/*. The shape
  heuristics (charset, length, digit bounds) are gone because they
  could not bound identity: depth-2 first segments are usernames under
  /{username}/posts shapes and single-segment paths are documents. The
  emitted value set is now fixed by configuration, so no
  request-derived byte reaches the row.
- Integration-proxy responses carry the registered route pattern
  verbatim (bounded, integration-defined) instead of a classifier
  output; the registry stores the pattern at registration.
- auction_enabled serializes only when false, so a pushed config
  cannot silently re-enable auction telemetry on rollback; with a
  serialization test alongside the observability one.
- The secret-store validator is renamed to validate_secret_store_key_name
  with a key_name parameter: it validates an identifier, never a
  credential, and the old name tainted the key name as a secret value
  in CodeQL, lighting up eleven pre-existing log sites.
- Docs: the tinybird table gains its three missing rows,
  max_body_bytes states the 1024 floor the code enforces, the rollback
  guidance now describes the real compatibility boundary (push a
  compat config first: drop [observability], access_enabled = false,
  and enabled = false for access-only deployments), and the fixture
  uses the example-domain convention.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The access sink streams the Tinybird response (the body is never
  consumed; buffered conversion materializes chunked bodies before the
  limit check) and newline-terminates rows to match the auction sink's
  NDJSON framing, with the recording client now asserting both.
- Poisoned RequestTimings locks recover via into_inner instead of
  silently dropping every subsequent sample: the guarded data are
  plain counters, so one panic cannot blank the header and row for the
  rest of the request. Module and spec docs updated to stop conflating
  poisoning with contention.
- The geo write-back skips 401 responses through a shared helper:
  resolve_geo_for_response short-circuits on 401 before consulting the
  carried state, so the old unconditional write downgraded a carried
  Resolved to Attempted and cost the row its country.
- TimedKvStore forwards exists, so decorating a store with a cheap
  metadata probe (Spin) no longer downgrades it to the get-and-discard
  default body; with a contradiction-stub delegation test.
- Post-send ordering is owned by run_post_send_steps, which both
  production sites route through, and the instrumented sequence test
  drives the real seam: elapsed stamped by send, then pull-sync, then
  telemetry.
- Axum: dev_server_service remains the standard path; new tests pin
  flag-off suppression and the extension round trip (a phase recorded
  in the handler must surface as ts-filter in the header); the
  outer-wrapper rationale is reworded to the terminal-freeze-point
  argument; the configuration guide notes the flag is read once at
  startup.
- The no-Cache-Control fail-closed case is pinned by a test, and t0's
  boundary (constructed after the adapter prologue) is documented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
prk-Jr and others added 18 commits September 24, 2026 12:05
# Conflicts:
#	crates/trusted-server-adapter-axum/Cargo.toml
#	crates/trusted-server-adapter-axum/src/app.rs
#	docs/.vitepress/config.mts
#	docs/guide/api-reference.md
#	docs/guide/configuration.md
# Conflicts:
#	crates/trusted-server-js/lib/test/prebid-artifact-integration.test.mjs
# Conflicts:
#	crates/trusted-server-core/src/publisher.rs
#	crates/trusted-server-js/lib/src/integrations/gpt_diagnostics/overlay.ts
#	crates/trusted-server-js/lib/test/integrations/gpt_diagnostics/overlay.test.ts
#	docs/guide/integrations/gpt-diagnostics.md
# Conflicts:
#	crates/trusted-server-integration-tests/fixtures/configs/viceroy-template.toml
#	docs/guide/fastly.md
# Conflicts:
#	crates/trusted-server-adapter-fastly/src/platform.rs
#	crates/trusted-server-core/src/publisher.rs
This reverts commit 9b4a994, reversing
changes made to eda2379.
EdgeZero PR 381's store-selector work made a runtime
EDGEZERO__STORES__CONFIG__<ID>__KEY override move the CLI's config push
destination on its own, with no --key flag. Under v0.0.8 it did not, which
is what this test asserted when PR #879 was written.

Record the pinned runtime's behavior so the release candidate is green, and
flag the change for upstream review rather than leaving the suite red.
# Conflicts:
#	crates/trusted-server-adapter-cloudflare/src/app.rs
#	crates/trusted-server-adapter-fastly/src/app.rs
#	crates/trusted-server-adapter-fastly/src/main.rs
#	crates/trusted-server-adapter-fastly/src/platform.rs
#	crates/trusted-server-cli/tests/config_store_defaults.rs
#	crates/trusted-server-core/build.rs
#	crates/trusted-server-core/src/ec/prebid_eids.rs
#	crates/trusted-server-core/src/publisher.rs
#	crates/trusted-server-integration-tests/fixtures/configs/viceroy-template.toml
#	docs/guide/configuration.md
return 'Delivery evidence: Not observed';
default:
return unhandledCase(cycle.delivery);
return unhandledCase(cycle.delivery) ?? 'Delivery evidence: Not observed';
@dhruv8sh
dhruv8sh added this pull request to stack #1218 September 29, 2026 11:40
@dhruv8sh
dhruv8sh removed this pull request from stack #1218 September 29, 2026 11:51
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants