Skip to content

October release candidate (DO NOT MERGE) - #1228

Draft
ChristianPavilonis wants to merge 234 commits into
mainfrom
rc/202610
Draft

ChristianPavilonis wants to merge 234 commits into
mainfrom
rc/202610

Conversation

@ChristianPavilonis

@ChristianPavilonis ChristianPavilonis commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

October release candidate, replacing September RC #1112.

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

Contents

The RC head e887cee0 contains main through 569ad862 (#1221), every open PR in milestone 202610 at the revision listed below, and the September revisions of the #1074 stack.

Open milestone PRs

PR Review Included revision Status in RC
#1052 changes requested 285e0037 included
#1107 changes requested b4a20f49 included; first RC revision with the trace implementation
#1175 changes requested 3add18d8 included; carries the EdgeZero v0.0.9 store-link changes
#1183 changes requested 3ddf6156 included
#1213 changes requested 941a5d8f included
#1251 changes requested 3993b725 included; stacked on #1107

Merged milestone PRs

#1137, #1166, #1173, #1176, #1177, #1179, #1180, #1181, #1182, #1210, #1214 and #1227 are in main and reach the RC through the main merge. Earlier RC merges of #1137 and #1173 through #1182 are superseded by their final main versions.

Closed PRs still carried

PR Included revision Note
#1074 a1523675 closed, superseded by #1261
#1076 58f8a354 closed, superseded by #1261; included through #1121
#1121 f951955f closed, superseded by #1261; September revision
#1154 0fa7dfb6 closed, superseded by #1261

#1261 has no milestone and is not in this RC. Swapping the carried stack for #1261 would require rebuilding the branch. #1217 was closed in favor of #1225 and was never included.

Each listed revision was verified as an ancestor of the RC head.

EdgeZero pin

The RC pins EdgeZero to 78439fd4 on the unreleased spec/pre-dispatch-request-fidelity branch. It is the only revision that has both the v0.0.9 store bindings #1175 needs and the pre-dispatch ingress hooks #1107 and #1251 need (they pin 965d482f, which predates v0.0.9). A released tag carrying both is a release gate.

RC-only integration changes

These adapt PRs to each other and exist only in this branch:

Verification

At e887cee0 on macOS: cargo fmt, all eight clippy gates, test-fastly, test-fastly-reuse, test-axum, test-cloudflare, test-spin, parity, the CLI suite and the native build-digest test (4,882 Rust tests, 0 failures), plus 72 vitest files, JS, docs and Markdown formatting.

jevansnyc and others added 30 commits August 24, 2026 19:02
* Add request phase timing design spec (Server-Timing subtimings + access telemetry)

* Address review round 1: freeze point, template-cache naming, snapshot semantics, KV scope, geo carry, route template, sink confirmation, sampling and query model, config rollback

* Address review round 2: auction-wait placement modes, conservative private-only header emission, non-null sorting key with service identity, coarse publisher route template, telemetry snapshot and outage behavior, tinybird flag decoupling, adapter phase semantics

* Add request phase timing implementation plan

* Address engineer review: KV timing decorator, try_lock sampling, route metadata extension, adapter-derived env, typed template-cache state, adapter-owned emission context, per-mode delivery semantics, Axum outer wrapper
…ite-back in middleware

Three final-review fixes for access telemetry correctness:

- Normalize the HTTP method to an allowlist (GET/HEAD/POST/PUT/DELETE/
  PATCH/OPTIONS, else "other") inside access_event_row, so a client-
  controlled extension-method token can never inflate the LowCardinality
  method column, regardless of which adapter builds the row.
- Guard emit_access_telemetry_after_send against snapshots carrying a
  degraded sample_rate of 0.0 (captured on the app-state-build-failure
  fallback path), which could otherwise be sampled in by freshly reloaded
  settings and corrupt the sum(1.0/sample_rate) volume estimator.
- Mirror the geo lookup write-back from apply_entry_point_finalize_headers
  into FinalizeResponseMiddleware::handle, so a middleware-finalized
  response that resolved geo via fallback carries the resolved
  GeoLookupState for the access-telemetry snapshot instead of showing
  country "unknown".
std::time::Instant::now() panics on wasm32-unknown-unknown, so every
publisher request on the Cloudflare adapter trapped when the timing
collector was constructed, and the two auction-wait sites would trap
once an auction dispatched. web_time re-exports std's Instant on every
other target, so Fastly, Axum, and Spin behavior is unchanged.

The publisher.rs sites are qualified locally because that module's
std Instant import still serves the pre-existing template-cache sites,
which are out of scope here.
The character allowlist alone does not bound identity: [a-z0-9_-] is
exactly the alphabet UUIDs, hex ids, reset tokens, and article slugs
are built from, and truncating to 32 characters still leaves a
globally unique prefix. A first segment now rejects whole to /other/*
when it exceeds 32 characters or carries more than 7 ASCII digits,
alongside the existing charset rejection. Year archives and
hyphenated section names still pass.

Extends the adversarial tests to the publisher-fallback path with
UUID, hex-id, token, and slug shapes, and fixes the stale event_date
reference in the row-builder doc.
- Gate building the access snapshot on tinybird.enabled and
  access_enabled, threaded through SendContext: a disabled deployment
  (the default) no longer pays env reads and String allocations on
  the pre-send path. DeliveryOutcome.snapshot becomes Option and the
  emitter treats None as nothing to send.
- Classify asset-fallback responses as route_class asset with the
  operator-configured route prefix as the template, instead of
  landing in the other/unknown bucket alongside 404s.
- Pin Phase::index() to PHASE_COUNT with a uniqueness-and-bounds
  test so a future variant fails the suite instead of panicking at
  runtime.
- Drop the tautological sampled-out emission test; the 0.0-rate
  behavior is covered by sampled_in_boundary_rates_are_unconditional.
- Clarify that the local dev config env var name genuinely triples
  trusted_server_config (prefix, store, key) rather than reading as
  a find/replace mistake.
Adds section 18 to the request phase timing spec: three first-call-wins
T0 offsets (auction dispatched, resolved, committed) on RequestTimings,
emitted as additive nullable columns on access_logs_raw with auction_id
as the join key to the per-bidder auction dataset. Answers the
overlap-proof questions the two existing clocks cannot: when the
auction started relative to request entry, when the final bid landed,
and when targeting was committed toward GAM.
Implements spec section 18: three first-call-wins marks on
RequestTimings (dispatched at the DispatchAuctionOutcome::Dispatched
arm, resolved after collect at both sites, committed after
write_bids_to_state at both sites), carried through TimingSnapshot into
four additive access_logs_raw columns: auction_dispatched_ms,
auction_resolved_ms, auction_committed_ms, and auction_id as the join
key to the per-bidder auction dataset. Null offsets mean no auction
ran; a failed dispatch records nothing. FORWARD_QUERY fills the new
columns with typed defaults for pre-existing rows.

No header emission, no config surface, no adapter changes: the values
ride the existing snapshot and the tinybird.access_enabled gate.
The Cloudflare integration harness writes
wrangler.integration.generated.toml at test time; it was swept into the
previous commit by accident. Ignore it so local CI=1 runs cannot commit
it again.
The first path segment is only a section name when the path has depth:
under a /%postname%/ permalink structure every article is a
single-segment path, so keeping those segments verbatim put full
article slugs into the 30-day dataset, against spec section 9. Depth
is now required for a named template; single-segment paths, root
landing pages included, bucket to /other/*. Route slicing keeps
route_class and multi-segment templates like /news/*.
The bucket-quantized sampler truncated rates below one in a million to
a zero threshold (silently emitting nothing) and quantized other low
rates downward while rows still carried the configured rate, biasing
the sum(1.0 / sample_rate) volume estimator. Its no-rand premise was
also wrong: rand::thread_rng() is WASI-backed on this target and the
EC generation path already relies on it. The sampler is now a direct
uniform-roll comparison, and the roll gates on the rate stored in the
snapshot itself, so emission probability and the row's sample_rate
column cannot diverge; the divergence guard and its tests are removed.

Also per review: the settings-reload fallback in the post-send path
could never emit (no snapshot exists when settings were absent) and is
removed; the dead_code allow on DeliveryOutcome narrows to the one
collected-but-unemitted field; and the post-send ordering test is
narrowed to the leg it actually proves, that request_elapsed is
stamped when send returns.
On origin failure with a dispatched auction, the origin span guard
stayed alive through the emit_abandoned_auction await, so ts-origin
and origin_ms absorbed Tinybird emission time. The span now closes
when the send resolves, before either branch, with an error-path
regression test.
- Pin HEADER_PHASES against Phase::header_name() in the phase-index
  test, closing the second hand-synced list.
- Add RouteClass::Asset to the snake_case rendering test; rename the
  lowercasing test to say what it does.
- Give the Axum adapter a named, fully configured construction path
  (TrustedServerApp::dev_server_service) so server_timing_enabled is
  never silently discarded; the tuple API is private now.
- Document that Server-Timing is client-visible when enabled, in the
  configuration guide's observability section.
- Replace stale event_date references in the spec, plan, and dashboard
  guidance with the toDate(event_ts) sorting-key expression, and state
  the single-segment rejection rule in spec section 9.
…ming

# Conflicts:
#	crates/trusted-server-adapter-fastly/src/app.rs
#	crates/trusted-server-adapter-fastly/src/main.rs
#	crates/trusted-server-adapter-fastly/src/middleware.rs
#	crates/trusted-server-core/src/publisher.rs
#	crates/trusted-server-core/src/settings.rs
#	docs/guide/configuration.md
#	trusted-server.example.toml
The access emitter carried the configured body limit without enforcing it, allowing oversized rows to bypass the intended transport safeguard.
aram356 and others added 15 commits October 8, 2026 08:39
Preserve upstream cache policy for rewritten JavaScript outside likely
static bundle paths. Log encoded-response bypasses at warning level only
when identity encoding was requested.

Repair eligibility coverage, add a path-aware cache regression, and
clarify assertion messages, collection diagnostics, and cache docs.
Always re-emit the validated value under the same name so an unvalidated ambient value never reaches option_env!, and treat an empty value as unknown.

Report x-ts-version on Fastly responses whose finalization is skipped because settings fail to load, drop an inherited x-ts-fastly-version when FASTLY_SERVICE_VERSION is unset or invalid, make the version_header test helpers private, and document the build input and header split for operators.

Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Signed-off-by: dhruv8sh <dhruv8sh@proton.me>

# Conflicts:
#	CHANGELOG.md
#	crates/trusted-server-adapter-fastly/src/main.rs
#	crates/trusted-server-core/build.rs
aram356 and others added 14 commits October 11, 2026 12:43
Document authenticated forwarding and the current dev proxy limitation, pin the Spin runtime checksum, and keep composition tests compatible with ES2020.

Refresh the stale trace input digest after verifying rebuilt JS and CSS exactly match the frozen assets.
Resolve documentation overlaps while preserving authenticated forwarding, browser authority validation, and Origin handling.

Update the configuration guide and example for the available forwarding credential option.
Replace the interim `rev =` pin on the unmerged upstream branch with
`tag = "v0.0.9"`, the release carrying the merged PR 381 that binds Fastly
stores per deployment environment. This closes issue #1195. Verified the
tag contains every API this branch depends on (`validate_fastly_config_key`,
`resolve_config_store_and_key`, `desired_resource_links`,
`store_name_checked`, `owns_managed_deploy`, `require_token`) and the
`package-application-release-fastly` action.

Review feedback:

- Warn that an unchanged `ts config push --adapter fastly --staging` runbook
  now writes the production entry when the `__NAME` selector is unset, since
  `--staging` no longer selects a separate key.
- Correct the `__KEY` test comment: the Fastly CLI rejects any value other
  than the logical ID, and the test exercises the Axum adapter, which is why
  the override applies there.
- Replace the sandbox key-shape test with one that captures the keys
  `collect_raw_limits` actually requests. The previous assertions only
  compared string constants and could not fail without an edit to the test
  itself; the sibling tests match on `ends_with`, so a service-scoped lookup
  slipped past them.
- Drop the unused `deploy` command from the Fastly adapter manifest. The
  schema has it optional and this app always takes the managed path, so
  leaving it invited a copy into a runbook.
…-381-local

# Conflicts:
#	crates/trusted-server-js/build.rs
Address two review follow-ups on the upgrade and deployment guides.

Managed deployment reads a nonempty `FASTLY_API_TOKEN` straight from the
process environment through EdgeZero's `require_token`, which a Fastly CLI
profile alone does not supply, so the deploy examples now name that
prerequisite.

The stale-entry cleanup said to delete `*_staging` config entries once no
active version reads them, but an older staged version keeps a version-linked
selector pointing at `<logical-store-id>_staging`. Deleting the entry while
that version is deployed makes its publisher routes return 500, so the
checklist now covers active, staged, and rollback versions.
Brings #1175 to 3add18d, which carries main through 5319594 and
repins EdgeZero to v0.0.9.

Conflict resolutions:
- Fastly and Axum entry points keep the RC's request-timing stack and
  adopt main's reusable sandbox (#1179) and RUST_LOG handling (#1227).
  Sandbox counters are threaded through send_edgezero_response alongside
  SendContext, following the shape used in #1261.
- tester_cookie.rs takes main's final #1137.
- #1175's own docs, CLI test and Viceroy fixture take its new revision.
- browser.rs drops the RC-only launch timeout const that main's #1256
  now defines.
Brings #1107 to b4a20f4, its first revision in this RC that carries
the trace implementation rather than only the spec.

Integration decisions:
- EdgeZero moves to 78439fd4 on spec/pre-dispatch-request-fidelity. It
  contains v0.0.9 (#1175) and the pre-dispatch ingress hooks #1107 and
  #1251 pin at 965d482f; no released tag carries both.
- scheduleInitialAdInit takes (bids, slots, auctionDiagnostics,
  traceAuctionTransport). One builder emits both payloads, so the RC's
  diagnostics-only scripts are unchanged and trace moves to the fourth
  argument. recordTrustedServerOpportunity likewise takes auctionFacts
  then traceIdentity; #1107's positional tests and the bootstrap
  fallback were shifted to match.
- The Fastly trace terminal path sends through the timed delivery
  function without Server-Timing, sandbox counters or access telemetry.
- build.rs embeds trace assets from #1214's private bundle directory.
  The viewer rebuilds byte-identical; the pinned source digest changes
  only because build-all.mjs gained --out-dir.
- The trace projection does not copy the RC's auction evidence fields,
  so the classification test marks them excluded.
- The retained diagnostics toolbar resyncs its filter select after
  selectRequest.
- Shim size guard raised to 55.5 KB for diagnostics plus trace.
Conflict resolutions:
- Fastly imports keep the RC's timing, telemetry and trace imports
  alongside the version-header imports.
- CHANGELOG keeps both sides' entries.
- getting-started keeps #1175's managed ts deploy command. ts deploy
  consumes a prebuilt release, so TRUSTED_SERVER__GIT_VERSION is
  documented as a build input for the release package rather than a
  prefix on the deploy command.

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