Skip to content

Rename /__ts/page-bids to /_ts/page-bids#971

Open
prk-Jr wants to merge 2 commits into
mainfrom
942-page-bids-single-underscore
Open

Rename /__ts/page-bids to /_ts/page-bids#971
prk-Jr wants to merge 2 commits into
mainfrom
942-page-bids-single-underscore

Conversation

@prk-Jr

@prk-Jr prk-Jr commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • /__ts/page-bids was the only internal Trusted Server route using a double-underscore prefix; every other internal path lives under /_ts/. This moves the SPA re-auction endpoint to /_ts/page-bids and switches the tsjs client fetch to match.
  • A browser runs whichever tsjs bundle it was already served, so pages loaded before the rename — and cached bundles — keep requesting the old path. On a SPA that path is what delivers ads for in-session navigations, so /__ts/page-bids stays registered to the same handler as a transition alias. Removal is tracked by Remove the deprecated /__ts/page-bids transition alias #970.
  • Route coverage was missing for the page-bids GET registrations on Cloudflare and Spin. Mutation testing confirmed a broken registration previously passed every suite; that gap is now closed.

Changes

File Change
crates/trusted-server-core/src/publisher.rs Add PAGE_BIDS_PATH / PAGE_BIDS_LEGACY_PATH as the single source of truth; log an info line when the alias serves a gate-passed request; add deprecated_alias_response_matches_canonical_path; split make_page_bids_request_on out of make_page_bids_request; update doc comments
crates/trusted-server-adapter-fastly/src/app.rs Register both paths via NAMED_ROUTES; add page_bids_serves_canonical_path_and_deprecated_alias, pinning the consts to their literal values
crates/trusted-server-adapter-axum/src/app.rs Register both paths; named_routes() widens to [NamedRoute; 13]
crates/trusted-server-adapter-cloudflare/src/app.rs Collapse four near-identical registrations into a loop over both paths, matching the existing legacy_admin_deny pattern
crates/trusted-server-adapter-spin/src/app.rs Register both paths; named_fallback_paths() widens to 13 so non-primary methods still reach the publisher fallback
crates/trusted-server-adapter-axum/tests/routes.rs Pin GET/OPTIONS on both paths in all_explicit_routes_are_registered
crates/trusted-server-adapter-cloudflare/tests/routes.rs Same route-table assertions
crates/trusted-server-adapter-spin/tests/routes.rs Add page_bids_get_is_routed_on_canonical_path_and_alias (Spin has no route-list test)
crates/trusted-server-integration-tests/tests/parity.rs Preflight-denial parity now loops both paths
crates/trusted-server-js/lib/src/integrations/gpt/index.ts SPA hook fetches /_ts/page-bids
crates/trusted-server-js/lib/test/integrations/gpt/spa_hook.test.ts Update three fetch assertions
crates/trusted-server-core/src/auction/{endpoints,orchestrator,telemetry}.rs, integrations/gpt.rs Doc-comment path updates

Closes

Closes #942

Test plan

  • cargo test-fastly && cargo test-axum — also cargo test-cloudflare && cargo test-spin
  • cargo clippy-fastly && cargo clippy-axum — also clippy-cloudflare, clippy-cloudflare-wasm, clippy-spin-native, clippy-spin-wasm
  • cargo fmt --all -- --check
  • JS tests: cd crates/trusted-server-js/lib && npx vitest run (411 passed)
  • JS format: cd crates/trusted-server-js/lib && npm run format
  • Docs format: cd docs && npm run format
  • WASM build: cargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1
  • Manual testing via fastly compute serve
  • Other: parity suite (--test parity, 13 passed); mutation testing of all 8 registrations

Mutation testing

Because the alias exists precisely to avoid a silent ad-serving gap, each registration was deliberately broken to confirm a test fails. All 8 are caught (Fastly / Axum / Cloudflare / Spin × canonical / alias). Before this PR's added coverage, breaking the Cloudflare GET registration — canonical or alias — passed every suite.

Verified the built bundle rather than assuming: dist/ is gitignored and regenerated by build.rs; the rebuilt tsjs-gpt.js contains /_ts/page-bids once and /__ts/ zero times. The separately-shipped external Prebid bundle takes only prebid/index.ts and does not embed this path, so there is no half-ship risk.

Also confirmed the namespace move does not change behaviour: every handler regex in the repo is ^/_ts/admin, which does not match /_ts/page-bids, so the route is not pulled behind basic auth. No starts_with("/_ts") special-casing exists; integration path filters are all under /integrations/; cache and privacy logic key on headers, never path.

Notes

The docs/superpowers/ plan and spec files still reference /__ts/page-bids. They are dated point-in-time design records that also describe code shapes since changed, so they were left as history rather than rewritten. Happy to sweep them if reviewers prefer.

Not applicable: no config-derived regex or pattern compilation is touched.

Checklist

  • Changes follow CLAUDE.md conventions
  • No unwrap() in production code — use expect("should ...")
  • Uses log macros (not println!)
  • New code has tests
  • No secrets or credentials committed

The SPA re-auction endpoint was the only internal route using a
double-underscore prefix; every other internal path lives under /_ts/.
Move it to /_ts/page-bids and switch the tsjs client fetch to match.

A browser runs whichever tsjs bundle it was already served, so pages
loaded before the rename — and cached bundles — keep requesting the old
path. On a SPA that path delivers ads for in-session navigations, so
/__ts/page-bids stays registered to the same handler as a transition
alias until those bundles age out. Both paths are defined once in core
as PAGE_BIDS_PATH and PAGE_BIDS_LEGACY_PATH so removal touches one const
plus its four registrations.

handle_page_bids logs an info line when the alias serves a gate-passed
request. Without it nothing in the app distinguishes the two paths, so
the "no remaining legacy traffic" precondition for removing the alias
would only be answerable from edge access logs.

Route coverage was missing for the page-bids GET registrations on
Cloudflare and Spin, where GET and OPTIONS are registered separately and
the preflight-denial parity test does not imply the GET side is wired.
Mutation testing confirmed a broken registration previously passed every
suite. The route-table assertions pin literal paths rather than the
consts, since looking a route up by the same const it was registered
with still passes when the const's value changes.
@prk-Jr prk-Jr self-assigned this Jul 27, 2026
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.

Rename /__ts/page-bids to /_ts/page-bids for internal-route naming consistency

1 participant