July release candidate (DO NOT MERGE) - #919
Draft
ChristianPavilonis wants to merge 260 commits into
Draft
Conversation
Address PR review of the SSAT debug-dump change:
- The PBS non-2xx response body was attached to AuctionResponse.metadata,
which ProviderSummary clones verbatim into ext.orchestrator.provider_details
on the public /auction response — violating the documented invariant in
auction/orchestrator.rs. Drop the body from metadata, keep only the numeric
status, and log the snippet server-side at warn.
- Register ERROR_TYPE_HTTP_STATUS and match it in provider_status so PBS HTTP
errors get their own telemetry bucket instead of the transport_error
fallback.
- Bound the ts-debug dump: compact serialization capped at 256 KiB, and skip
the mediator_response line when no mediator ran.
- Correct the auction_html_comment and prepend_auction_debug_comment docs to
state the comment now embeds raw SSP creative markup (never enable in prod).
- Keep the targeted two-replace terminator neutralisation: a single
replace("--", ...) re-forms -->/--!> at odd dash-run junctions and is not
equivalent. Add a table-driven test over the comment-terminator vectors.
- Hoist test-local imports to module scope per CLAUDE.md.
…debug' into feat/ssat-write-prebid-response-debug
- Drop render_adm param: always include adm when creative present
- Gate GAM-bypass on per-bid debug_bid instead of a global window.tsjs flag
(removes SPA-staleness edge case, TsjsApi change, and whole flag-emit task)
- Correct fallback scope: cache fallback only when adm absent; render failure
after adm is supplied is not detectable
- Qualify sandbox claim: TS guarantees script-context escaping; bridge frame
isolation depends on the Prebid Universal Creative
- Reconcile with existing ad_init.test.ts coverage (rename, no duplicates)
- Fix test assertion messages to expect("should ..."); list exact clippy gates
- Task 3: assert observable DOM (GAM iframe src) instead of spying on the module-private injectAdmIntoSlot - Use existing make_bid helper + set .creative (make_test_bid_with_creative does not exist on this branch) - Hostile-adm regression test covers both U+2028 and U+2029 - Add 'cd docs && npm run format' to verification
build_bid_map now always inserts the winning creative as adm so the pbRender bridge can render it locally (no PBS Cache round trip); the verbose debug_bid blob and the GAM-bypass gate stay behind inject_adm_for_testing. Rename the param include_adm -> include_debug_bid and thread it through write_bids_to_state. Reconcile the by-default test to the new behavior, drop the now-redundant debug-only-adm test, and pin script-context escaping for a hostile adm (</script> + U+2028/U+2029).
The direct GAM-replace path (injectAdmIntoSlot) now fires only when the bid carries debug_bid, which is present only under inject_adm_for_testing. In production the always-present adm is rendered by the pbRender bridge and GAM stays in the loop. Add observable-DOM tests (GAM iframe src unchanged without debug_bid, rewritten with it), strengthen the bridge test to prove inline adm is preferred even when cache coords are present, and rename debug-adm terminology to inline adm.
Resolve five correctness and resource-safety findings from the PR #867 review of the end-to-end Fastly publisher streaming path. - Drive the deflate decoder to StreamEnd at finalization so a valid stream that exactly fills the internal output buffer is no longer rejected as truncated; the inflater is also drained after all input is consumed within a chunk. - Decode concatenated (multi-member) gzip bodies via MultiGzDecoder on both the streaming decoder and the buffered read pipeline so adapters agree. - Enforce the decoded-body cap during decompression through a bounded sink shared by the gzip and brotli codecs, so a compression bomb errors before its expanded bytes are buffered instead of after a full chunk expands; the deflate codec charges each produced block as it is emitted. - Drop the body of bodiless responses (HEAD, 204, 205, 304) in both the streaming and buffered finalizer Buffered arms, and add RESET_CONTENT to response_carries_body, so a buffered-unmodified stream body is never streamed to the client for a response that must be bodiless. - Keep the dispatched-auction guard armed across the collection await and disarm it only once collection reaches a terminal result, so a body dropped while collection is pending still logs the discarded SSP work. Add regression tests for the deflate output-buffer boundary, multi-member gzip, bodiless buffered stream bodies, and the auction guard sentinel.
Resolve the PR review by making transport-timeout canonicalization a platform capability and hardening auction backend-name correlation. - Move quantization behind PlatformBackend::canonicalize_transport_timeout_ms. Fastly floors budget-derived timeouts to a 250ms quantum with a bounded sub-quantum ladder [200,150,100,50]; other adapters use the exact remaining budget so bidder deadlines (Prebid tmax, APS timeout) are not shortened where no connection-pooling benefit exists. - Bound sub-quantum backend-name cardinality: exact 1-249ms values no longer pass through, capping the budget-derived names a single origin can mint toward the per-service dynamic backend limit. - Add a provider discriminator to PlatformBackendSpec, folded into every adapter's backend name, so two providers sharing one origin no longer collide on the response-correlation key. Reject a duplicate backend_to_provider insertion with an attributed launch failure instead of silently overwriting and misattributing a response. - Make the orchestrator call-site tests deterministic: record predicted and registered transport timeouts separately and assert exact equality via a controllable platform backend, and enumerate the sub-quantum ladder to assert a bounded name cardinality. - Correct the timeout-semantics comments that overstated absolute-deadline enforcement; the Fastly connect/first-byte/between-bytes timeouts bound connection, first-byte, and inactivity, not total response time. A true absolute deadline carried through the platform HTTP API remains follow-up work (#849).
Prebid non-2xx responses were reduced to bare provider errors, making intermittent failures difficult to diagnose. Surface safe HTTP metadata and bounded debug details while correlating server logs with the auction ID.
A configured bidder with no inline params and no matching override
expanded to `"bidder": {}`, which PBS rejects. After applying overrides,
drop fabricated empty bidders, preserve an explicitly supplied empty
object so genuine misconfiguration stays visible, and fall back to the
stored-request path when no eligible bidders remain.
…debug' into merge/pr-890-893-899-910-912
…to merge/pr-890-893-899-910-912
…' into merge/pr-890-893-899-910-912
…-params' into merge/pr-890-893-899-910-912
…o merge/pr-890-893-899-910-912
Allow operators to retain sanitizer-accepted external URLs in POST /auction adm while preserving mandatory server-side sanitization and the existing default behavior.
…ing' into merge/pr-890-893-899-910-912
This reverts commit 653ae8a.
This reverts commit 423e6c5.
This reverts commit fd1cbd8.
This reverts commit 050ad9c.
# Conflicts: # crates/trusted-server-js/lib/src/core/types.ts
…iants Address review feedback on the opt-in creative-processing change: - Register GET /first-party/proxy-rebuild in every adapter. The creative iframe sandbox no longer grants allow-same-origin, so the click guard's JSON POST preflights with Origin: null and fails; the guard now recovers by navigating to the GET endpoint, which the core handler answers with a 302 chain that CORS does not apply to. - Make the click guard detect an opaque origin up front and skip the doomed POST, going straight to the GET navigation fallback. Dynamic resource signing likewise bails out early instead of issuing a request that cannot succeed; a same-origin parent postMessage broker for opaque-origin signing is tracked as a follow-up. - Enforce the 1 MiB per-creative cap independently of the sanitize/rewrite flags so pass-through and rewrite-only modes cannot ship oversized markup. - Cover the remaining processing modes: rewrite-without-sanitize at both the helper and response-converter level, a byte-for-byte pass-through assertion, and oversized-creative rejection in all four modes. - Update stale documentation that still promised mandatory sanitization and default-on rewriting; describe the client sanitizeCreativeHtml helper as validation-only and add a breaking-change changelog entry with the upgrade and rollback sequences.
…sanitization-optional
Publishers may call googletag.display with a slot or element before the initial request gate is released. Treating that argument as a string can abort the request, while first-prefix slot resolution can target a hidden responsive sibling. Preserve the GPT display contract and resolve stable prefixes only when one active element can be identified.
# Conflicts: # crates/trusted-server-js/lib/src/integrations/prebid/index.ts # crates/trusted-server-js/lib/test/integrations/prebid/index.test.ts
# Conflicts: # crates/trusted-server-js/lib/src/integrations/prebid/index.ts # crates/trusted-server-js/lib/test/integrations/gpt/ad_init.test.ts # crates/trusted-server-js/lib/test/integrations/prebid/index.test.ts
ChristianPavilonis
force-pushed
the
rc/july
branch
from
July 30, 2026 13:05
0325868 to
5d36b2d
Compare
# Conflicts: # CHANGELOG.md # crates/trusted-server-cli/tests/config_env_overlay.rs # crates/trusted-server-core/src/auction/README.md # crates/trusted-server-core/src/auction/formats.rs # crates/trusted-server-core/src/auction/orchestrator.rs # crates/trusted-server-core/src/auction_config_types.rs # crates/trusted-server-core/src/config_payload.rs # crates/trusted-server-core/src/creative.rs # crates/trusted-server-core/src/publisher.rs # crates/trusted-server-core/src/settings.rs # docs/guide/auction-orchestration.md # docs/guide/configuration.md # docs/guide/creative-processing.md # trusted-server.example.toml
# Conflicts: # crates/trusted-server-core/src/integrations/gpt_bootstrap.js # crates/trusted-server-js/lib/src/integrations/gpt/index.ts # crates/trusted-server-js/lib/test/integrations/gpt/ad_init.test.ts
Reconciles the squash-merged #945 (deferred initial adInit) with the RC's own evolution of the same files: - build_bids_script, the bundle scheduler, and the gpt_bootstrap.js fallback take main's final form: the SSR bids payload is handed to scheduleInitialAdInit, which applies it and runs adInit only on navigation generation 0; adInit rechecks its generation inside the queued googletag.cmd callback; the head bootstrap keeps the bundle-failure fallback scheduler. - The RC's pathname-plus-query route identity is kept: docblocks and the query-change tests follow the RC semantics (a query change requests fresh page bids and cancels the pending initial pass), and the RC's slot-handoff/initial-request-gate machinery is preserved alongside the new scheduler. - gpt_bootstrap.test.ts is adapted to the RC bootstrap: assertions target the pre-patch spies (the handoff patcher wraps defineSlot/display/ refresh) and expect the TS fallback slot on the publisher's actual inner div per the RC handoff design.
Both branches fixed oversized HEAD response metadata independently with mirrored parameter designs. Adopt main's implementation wholesale — the request_is_head parameter plus response_carries_body(), which also covers 1xx/204/205/304 bodiless statuses — and keep the RC's cache-bypass feature intact: send() retains its bypass_cache read alongside the new request_is_head, and the RC's apply_fastly_cache_bypass tests are restored next to main's bodiless-metadata tests.
…covery Address the second review round: - Keep rewrite_creatives defaulting to true. The measurement behind this PR justifies making sanitization opt-in; flipping rewriting too would silently disable first-party proxying for every existing deployment and invert the rollback serialization contract. Only sanitize_creatives (default false) is new behavior. - Suppress the PBS Cache fallback when a supplied creative is rejected by processing (script-only after sanitize, malformed, or over the 1 MiB cap). The GPT bridge renders the cached bid's original adm, so retaining the hb_cache_* coordinates would deliver exactly the markup processing refused. Cache coordinates now ship only for bids that supplied no creative. - Parse the GET /first-party/proxy-rebuild query from uri().query() instead of the full URI: browsers via the Axum and Spin adapters deliver origin-form URIs, which url::Url::parse rejected before the 302 could be issued. - Strip bidder <base> elements in the rewrite pass itself. Rewriting emits root-relative first-party URLs, and a bidder base href would rebase them onto a third-party origin; sanitization also removes <base> but is independently optional. - Resolve click-guard URLs against a pinned document.baseURI instead of location.href, which is about:srcdoc inside the sandboxed creative iframe and rejects root-relative signed click URLs as a base. Navigation URLs are absolutized the same way. - Never write the GET rebuild fallback into data-tsclick: it is the canonical signed click used to diff later mutation waves. href updates, the canonical source persists, and a second mutation wave still rebuilds. - Share one hasOpaqueOrigin predicate between the click guard and dynamic signing; reference issue #982 (parent postMessage broker) from the code and the creative-processing guide's new runtime-protections note. - Document upgrade sequencing (binary first, then config: old binaries reject blobs carrying sanitize_creatives), the per-mode 1 MiB cap, and the requirement to add both TOML leaves before environment overlays apply; add CLI coverage for the sanitize overlay.
Aligns the rc/july copy with the cleaned version on the responsive-slot display gating branch: the function early-returns when divId is absent, so the per-candidate re-check always evaluated to true.
Adopts the gating revert and the hardened GPT slot handoff from #978: - Removes the publisher initial-request gate (initialRequestGate, heldPublisherRequests, GptInitialRequestGate) that #978 reverted - Takes matchingHandoff/displayTargetElementId and the responsive-slot helpers with ambiguous-hydration protection - Keeps rc-only content intact: gpt_diagnostics types, the #948 disableInitialLoad sync (syncInitialLoadDisabled wired into the refresh-selection path), and the #945 scheduleInitialAdInit coverage - Drops the obsolete held-display test from schedule_initial_ad_init and ports the two #948 setConfig tests to the new zero-arg runGptBootstrap harness
The APS adapter spec loads the external Prebid bundle and assumed it carries the tsjs shim (and the trustedServer adapter) inside it. Once the shim is decoupled (PR #967) the external bundle is pure Prebid.js, no adapter ever registers, and the in-page auction times out. Detect the decoupled world through the window.__tsjs_prebid_bundle manifest stamp and load dist/tsjs-prebid.js after the external bundle, matching the script order the server actually serves. On a coupled bundle the stamp is absent and the spec behaves exactly as before.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Consolidates the July release-candidate changes for review and integration testing before the individual changes merge to
main.Included pull requests
Already included through
mainPending Review / Merge