July release candidate (DO NOT MERGE) - #919
Closed
ChristianPavilonis wants to merge 390 commits into
Closed
Conversation
Introduce query-activated diagnostic sessions, trace identities and telemetry, bounded GPT and Prebid render ownership, creative acknowledgements, and the browser timeline overlay. Add deterministic integration fixtures and coverage across edge adapters and browser render paths.
Introduce query-activated diagnostic sessions, trace identities and telemetry, bounded GPT and Prebid render ownership, creative acknowledgements, and the browser timeline overlay. Add deterministic integration fixtures and coverage across edge adapters and browser render paths.
# Conflicts: # crates/trusted-server-adapter-fastly/src/backend.rs # crates/trusted-server-adapter-fastly/src/platform.rs # crates/trusted-server-core/src/auction/orchestrator.rs
…ping APS bids are bid-by-reference: interpretResponse sets the renderer descriptor on the Prebid bid as the custom `trustedServerRenderer` field, and a bidResponse listener registers it in window.tsjs.apsPrebidRenderers keyed by Prebid's generated adId so the Universal Creative can later request it. Prebid normalizes each bid into its own object during addBidResponse and drops unknown top-level fields, so the custom field can be gone before the bidResponse listener runs (observed in production: absent as early as bidAccepted). The listener then saw renderer === undefined and returned without registering, leaving the registry empty; the Universal Creative's request found nothing and Prebid's default renderer threw "Missing ad markup or URL" (reason noAd) for every APS bid. Also stash the descriptor keyed by `requestId` (a first-class field Prebid preserves) when the bids are built, and have the bidResponse listener fall back to that stash when the custom field is absent. Additive: the existing field path is unchanged, so cases where the field survives behave exactly as before; the fallback engages only when Prebid has stripped it. Bounded map. Adds a unit test that registers via requestId with the custom field removed.
auction/orchestrator.rs:
- Combined imports (http::Request + std::collections::{HashMap, HashSet}).
- Kept main's post-launch backend-name collision defense and resolved-name
correlation on both parallel and sequential dispatch, while preserving #918's
per-provider effective_timeout in the backend_to_provider 4-tuple (declarations
and read sites already expect the 4th element).
- Took main's test provider fields (configured_timeout_ms / predicted_timeouts)
and its DivergentBackendProvider; updated a #918 test stub to the merged struct
shape (configured_timeout_ms: 125 to preserve its capped-launch-timeout assertion).
publisher.rs:
- Advertise the configured publisher_domain in the page URL (main's fix; the edge
Host must not leak into the bid request per the in-code comment) using #918's
request_path_and_query field (the field the merged MatchedSlotsContext exposes);
updated a stale test literal accordingly.
Verified: cargo check (axum) clean; orchestrator + build_auction_request tests pass.
…aps-renderer-requestid-registration
…ping APS bids are bid-by-reference: interpretResponse sets the renderer descriptor on the Prebid bid as the custom trustedServerRenderer field, and a bidResponse listener registers it in window.tsjs.apsPrebidRenderers keyed by Prebid's generated adId. Prebid drops unknown top-level fields when it normalizes bids during addBidResponse, so the custom field can be gone before the bidResponse listener runs (observed in production: absent as early as bidAccepted). The listener then saw renderer === undefined and returned without registering; the registry stayed empty, the Universal Creative's request found nothing, and Prebid's default renderer threw "Missing ad markup or URL" (reason noAd) for every APS bid. Also stash the descriptor keyed by requestId (a first-class field Prebid preserves) when the bids are built, and fall back to it in the bidResponse listener when the custom field is absent. Additive: the existing field path is unchanged; the fallback engages only when Prebid has stripped the field. Bounded map. Adds a unit test.
# Conflicts: # crates/trusted-server-core/src/integrations/datadome.rs # crates/trusted-server-core/src/integrations/datadome/protection.rs # crates/trusted-server-core/src/publisher.rs # docs/guide/integrations/datadome.md # docs/superpowers/plans/2026-08-03-datadome-ip-excluded-client-tag.md # docs/superpowers/specs/2026-08-03-datadome-ip-excluded-client-tag-design.md
# Conflicts: # crates/trusted-server-core/src/integrations/aps.rs # crates/trusted-server-js/lib/src/core/render.ts # docs/guide/integrations/aps.md
# Conflicts: # CHANGELOG.md # crates/trusted-server-core/src/auction/endpoints.rs
The winning-bid `hb_auction_id` carried `AuctionRequest.id`, which is
`ts-{ec_id}` whenever an Edge Cookie ID exists. That value reached
`window.tsjs.bids` and the page-bids JSON for every visitor, handing any
script on the page the identifier the `ts-ec` cookie keeps HttpOnly, and
it could not distinguish one auction from the next because it is stable
per visitor.
Mint an unrelated `ts-auc-{uuid}` per auction instead, and emit it only
when the GPT diagnostics integration is enabled, since nothing else
consumes it. `AuctionRequest.id` is unchanged for SSPs.
Keep the operator API read-only: `window.tsjs.gptDiagnostics` now exposes only snapshot, export, subscribe, show, and hide. The evidence writers Trusted Server's own modules use move to a separate internal channel, `window.tsjs.gptDiagnosticsRecorder`, so the documented contract matches what the object actually offers. Bound the store's deferred work by retained state rather than refresh rate. Request-intent evidence now expires lazily when the slot is next recorded or requested instead of owning a timer per source, which also removes the WeakRef-absent fallback that strongly retained every marked slot until expiry. Delivery-boundary notifications share one timer that re-arms from retained cycles. Stop reporting a source-agnostic GPT identifier as a reservation. Those IDs are populated for reservation and backfill alike, so they classify as `reservation` only alongside an explicit non-backfill fact. Evict a creative attempt whose cycle rendered empty, so a late markup response cannot claim a Trusted Server delivery against an empty render, and label badges from the derived delivery state instead of re-deriving the precedence rules from raw timestamps. Also: attribute `refresh(null)`, make the presentation switches exhaustive, hoist the snapshot out of the subscriber loop so every subscriber sees one capture, and make the export's attribution fields required. Type-check the export contract: the `expectTypeOf` assertions were never evaluated, and one of them was a genuine error. Scope `test.typecheck` to the type tests, since a package-wide `tsc --noEmit` still fails on pre-existing errors elsewhere. Fix the replacement-after-eviction test, which passed vacuously because ten open cycles made the final render ambiguous, and cover the paths the review identified: publisher-refresh malformed input, the association LRU trim, the out-of-order callback arms, a declined creative attempt, the Prebid dispatch-context restore arm, and wrapper install ordering. Correct the operator guide where it contradicted the implementation, and record the auction-token revision in the design spec.
Conflict in the Prebid refresh handler: main (#965) documented that the delegated refresh preserves the publisher's original bare form, while this branch replaced that call with the diagnostics recording plus the scoped dispatch context. Both hold — `dispatchPrebidRefresh` passes `slots` and `opts` through unchanged — so the resolution keeps the diagnostics calls and main's comment, extended to say the wrapper only scopes the shared context. Also add `bid_id` to the auction-ID test provider's `Bid` literal, a field main added in #996 after this branch introduced the provider.
Brings in the PR #997 review fixes: the read-only diagnostics facade split from the internal recorder channel, lazily expiring request-intent evidence with one shared delivery-boundary timer, source-agnostic IDs no longer reported as reservations, the empty-render attempt eviction, and the scoped type-check gate for the export contract. The branch also carries a merge of main, whose #965 and #996 arrive here as squashes of work rc/july already implements more fully. Where the two sides describe the same feature, rc/july's implementation is kept: - APS, adserver_mock, auction/types.rs, auction/formats.rs — rc/july's OpenRTB provider, renderer-aware bid_id precedence, and typed renderer envelope supersede main's versions, which drop fields rc/july needs. - prebid.rs — rc/july canonicalizes the excluded-suffix list at both the startup and build paths already, so main's `load_config` helper adds nothing. Main's test is taken instead of rc/july's: it builds from raw settings rather than reusing the config `validate_config_for_startup` already canonicalized, so it actually exercises the build path. - prebid/index.ts — a bare refresh that filtered slots must deliver the resolved target list, not stay bare, so rc/july's `deliveredSlots` behavior and its test expectation both stand. Three fixes are ported into rc/july's shapes rather than resolved away: - The EC-derived auction ID reached page JavaScript here too, through different plumbing: both collect paths inlined `request.id.as_str()` into `write_bids_to_state`, and page-bids passed it to `build_bid_map_with_auction_id`. All three now mint a per-auction token via `diagnostics_auction_id()`, gated on the diagnostics integration being enabled. - A blank Prebid Cache UUID no longer ships cache coordinates. It loses the hb_adid precedence to `adid` or the bid id, so the Universal Creative would fetch `?uuid=<non-cache-id>` and miss instead of using the inline adm. The gate moves from `is_some()` to `non_empty()`, and main's regression test comes along with rc/july's `Bid` fields added. - The browser-side excluded-suffix list is validated before use. The server only de-duplicates it, so an empty suffix matched every ad unit path and pulled every slot out of the refresh auction, and a non-array value threw inside the publisher's own `refresh()`. Also collapses a duplicated `hb_auction_id` write in `build_bid_map` down to one guarded insert, and points the Prebid refresh recorder at `gptDiagnosticsRecorder` to match the new channel.
# Conflicts: # crates/trusted-server-core/src/publisher.rs # crates/trusted-server-js/lib/src/core/types.ts # crates/trusted-server-js/lib/src/integrations/gpt/index.ts # crates/trusted-server-js/lib/src/integrations/gpt_diagnostics/api.ts # crates/trusted-server-js/lib/src/integrations/gpt_diagnostics/overlay.ts # 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/gpt_diagnostics/types.test.ts # crates/trusted-server-js/lib/test/integrations/prebid/index.test.ts # docs/guide/integrations/gpt-diagnostics.md
Resolves conflicts from the squash-merges of #918 (APS OpenRTB), #966 (duplicate GPT slot requests), and #956 (opt-in creative sanitization) against the rc/july copies of the same work plus rc-only follow-ups. Resolution decisions: - Adopt main's final versions wherever both sides carried the same PR content (markUsed lifecycle, load_config refactor, tiered slot-element resolver, sanitize-opt-in creative pipeline, canonical timeout tests). - Keep rc-only work main does not have: APS PUC collapsed-shell resize and reusable server APS descriptors (re-answering PUC requests), render tracing (#922), DataDome cache privacy, publisher cache-control (#1007), decoupled-shim spec loader (#988), query-aware SPA route identity for page bids. - Drop main's one-shot server-APS replay-guard test: rc's reusable descriptor behavior is asserted by the ported rc test instead. - Add the divToSlotId registry tier to slot-frame resolution so the adInit-resolved div wins for ambiguous responsive prefixes.
Absorbs the #963 squash (APS renderer meta carrier). rc/july already carried this work; keep the rc-only render-trace meta fields and adopt main's core-bundle load in the APS renderer spec helper.
The textual merges double-inserted blocks that compiled silently: - gpt_bootstrap.js carried two full copies of the slot-handoff helper section; JS shadowing made the stale rc copy dead code. The file now matches main exactly. - types.ts declared GptSlotHandoff twice (TS declaration merging hid it). - The #963 squash on main added its own copies of the APS registry tests that had been ported into prebid/index.test.ts and ad_init.test.ts, leaving seven tests duplicated under identical titles; the copies matching main are kept. - Restore main's comment wording in core/render.ts.
The requestId-strip APS registry test and the hb_adid omission test existed under rc names alongside main's renamed copies of the same bodies; keep main's versions.
- prebid/index.test.ts: drop duplicated vi.hoisted destructure keys, duplicated mockPbjs properties, and a doubled fixture import. - request.test.ts: type AddAdUnitsArg from the imported AdUnit instead of a Parameters<> lookup on a symbol that is only imported inside test bodies.
Absorbs the #998 squash (preserve APS renderer handshake behavior) and aligns rc/july with its landed form: - Adopt main's render bridge: slotIdForMessageSource source resolution, one-shot consumedServerApsBySlot guard, no renderer-path diagnostics, and the window-postMessage renderer handshake (dropping the rc-side MessagePort handshake, frame-based source resolution, and collapsed 1x1 shell resize that the landed PR did not take). - Keep rc-only work orthogonal to #998: render tracing (#922) in the slotRenderEnded and bridge inline/cache paths, the query-aware SPA route identity, and the renderer shell clipping fixes (overflow:hidden document styling and display:block on the renderer frame), re-ported onto main's handshake. - Take main's ad_init and APS renderer tests wholesale.
The PUC dynamic-renderer resize spec asserted the collapsed 1x1 shell resize that the landed #998 does not include; the spec, its prebid-universal-creative devDependency, and the lockfile entry now match main.
Collaborator
|
Replaced by #1019 |
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
mainMoved to August RC #1019