Implement APS render fix and TSJS resilience - #1002
Draft
aram356 wants to merge 609 commits into
Draft
Conversation
Carry bid_id through adserver_mock mediation. The reconstruction restored
nurl, burl, ad_id and the cache fields from the original SSP bid but
hard-coded bid_id to None, so a mediated bid whose only hb_adid source is
the OpenRTB bid id lost it and never rendered — the exact failure this
branch fixes, re-opened on the mediated path. Mediated APS bids were
worse off still: they carry no ad_id or cache_id for the restore to
recover, so they reached the page with no hb_adid at all. The mediation
response is itself OpenRTB, so prefer the mediated bid's own id and fall
back to the original SSP bid's.
Reject blank identity strings before applying the cache_id -> ad_id ->
bid_id precedence. Option::or treats Some("") as present, so a blank
cacheId or adid outranked a valid bid id and emitted an empty hb_adid —
falsey on the page, so GPT skips the targeting key and the render bridge
has nothing to match. Prebid's parse_bid likewise treats an empty
OpenRTB id as absent.
Emit hb_cache_host and hb_cache_path only alongside a real Prebid Cache
UUID. PBS reports the cache url and cacheId independently, so a bid with
coordinates but no UUID pointed the Universal Creative at
?uuid=<non-cache-id>, a guaranteed miss, instead of letting it fall
through to the inline adm.
Warn when the chosen hb_adid exceeds GAM's 40-character targeting value
limit. GAM drops an over-long value, so the creative echoes nothing and
the bridge's equality check never matches. Log rather than truncate: a
truncated id is no longer unique per bid, which is what lets one slot's
render claim another slot's creative.
Brings the PR #996 review fixes onto rc/july. The original fallback commit was already merged; this adds the follow-ups plus two conflict resolutions where rc/july had since moved. hb_adid precedence keeps rc/july's renderer tier and gains blank rejection on every tier, so a bidder emitting an empty cacheId or adid no longer outranks a usable identifier: non_empty(cache_id) -> non_empty(renderer_bid_id) -> non_empty(ad_id) -> non_empty(bid_id) Cache coordinates keep rc/july's placement inside the processed_adm match and gain the cache_id requirement as a second, independent condition: absent a UUID the coordinates would send the Universal Creative to ?uuid=<non-cache-id>. Mediation bid_id precedence is inverted relative to the main-targeted branch, deliberately. On main, APS bids carry no bid_id, so preferring the mediation response's own id was the only way to give them an hb_adid. On rc/july, aps.rs populates bid_id and a typed renderer envelope is minted against it, and build_bid_map derives hb_adid from that pairing — so substituting the mediator's id would key targeting to an id the renderer does not know. The original SSP bid's id therefore wins here, with the mediated id as the fallback for an upstream bid that carried none.
Bring the GPT delivery-evidence and refresh-attribution diagnostics onto the July release branch. rc/july already carried a later evolution of the auction-ID plumbing (PR #922 render tracing, the delivered-winner-slot telemetry, and the APS renderer bridge), so the overlapping Rust and JS changes keep the rc/july implementation and layer the new diagnostics on top of it. Conflict resolutions: - publisher.rs: keep the rc/july `write_bids_to_state` -> delivered winner slots contract and prebuilt page-bids bid map; keep both new tests; update the incoming test provider to the current `ProviderRequestOutcome` trait. - gpt/index.ts: keep the render-trace and APS renderer paths and add the creative request/response/failure diagnostics around them. The attempt is recorded after the APS branch, which is served by the APS universal creative and has no Trusted Server creative response to resolve. - prebid/index.ts: keep the resolved bare-refresh slot list and dispatch it through the diagnostics-aware refresh wrapper. - store.ts: adopt the incoming response-based `slotOnload` correlation. - Drop the pre-squash `gpt_diagnostics_bootstrap.js` and its test, which the upstream #974 squash removed as superseded by server-recognized activation. Verified: cargo fmt, clippy (fastly/axum/cloudflare/cloudflare-wasm/spin-native/ spin-wasm), test-fastly, test-axum, test-cloudflare, test-spin, parity, vitest (812 tests), JS and docs format.
Log whether protection_test_bypass is enabled when registering the DataDome integration and include configured header name when enabled. Keep credential secret out of logs.,
# 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
aram356
marked this pull request as ready for review
August 12, 2026 17:45
aram356
marked this pull request as draft
August 13, 2026 16:24
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
Implements the APS render fix and TSJS resilience design as a coordinated hard cutover, with no backward-compatibility runtime or legacy API aliases.
core + render_runtime + creativeboot artifact, including authenticated opaque-origin handlingrc/julyTSJS behavior through the executable adoption ledger and hard-cutover gatesScope boundaries
Current remediation checkpoint
5b12c161daeed3e6f9e64a7a7012d8a6f5153f12da6237db414516d27426d1ae0be03c024274dd0e869a335fb3c00bbc52afc0bdmainVerification
Local verification at the current implementation checkpoint:
Open merge blocker: first-display load time
The automatic production-shaped candidate-versus-current-
maingate is intentionally strict and remains red. The completed paired run measured:mainp90: approximately 473.3 msPerformance run 31657180720
This is an architecture blocker, not an accepted budget reset. The current parser-blocking release carries roughly 395 KB raw for the production
core + render_runtime + creative + gptshape versus roughly 81 KB on currentmain. The next implementation checkpoint must introduce a lean first-display owner and move the full resilient lifecycle behind the protected first display while preserving APS/ADM/GPT correctness. The 1.10 threshold and actual-byte network measurement will not be weakened or relabeled.The timeout/head-attestation defect exposed by the failing run is fixed at the current head, so subsequent failing runs retain complete schema-5 evidence and bind PR evidence to the source head SHA rather than GitHub's synthetic merge SHA.
Protected cutover prerequisites
This PR is not merge-ready until the first-display performance gate passes. Production activation also requires release coordination to supply the active Fastly service/version identity and the protected real-GAM environment. No production deployment or protected real-GAM run was performed from this worktree.