Repository navigation
Conversation
Spec and implementation plan for #1234: an [auction] rewrite_clicks switch that follows rewrite_creatives when unset, so click wrapping can be controlled independently of asset rewriting. Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
Describe the review fixes: the extended shared-step CHANGELOG entry and the sign status change, rollback in both directions, the reworded Auction Rewrite Control docs and renderGuard note, the fuller body-less matrix fixture, the exact default-output pin, and the stronger proxied-HTML test. Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
prk-Jr
left a comment
There was a problem hiding this comment.
Summary
Spec and plan for #1234's [auction] rewrite_clicks. The design holds up well: the plan was applied verbatim to main (d8937e1) and every Rust block compiled, passed fmt, clippy-fastly and clippy-cli; every claimed pass count matched exactly (16 / 15 / 554 — also under Viceroy 0.17.0 — / 2 / 2); the red steps fail where predicted; both MATRIX_DEFAULT_*_OUTPUT constants match main byte for byte; and the normalizer leaves tsurl/tstoken identical for edge inputs (uppercase host, :443, spaces, é, IDN, tabs). Cited files are unchanged between 7a0ecb4c and main. Two blocking items are doc-accuracy problems that would flow into operator docs.
13 of the inline comments below carry a one-click GitHub
suggestion— use Commit suggestion (or Add suggestion to batch) to apply them. The remaining comments describe the fix in prose because it spans several places. All suggestions were applied together and checked with the pinned docs prettier.
Blocking
🔧 wrench
- Doc-update list misses text that becomes false — see inline at
docs/superpowers/specs/2026-10-07-1234-creative-click-rewrite-switch-design.md:482 renderGuardcaveat is wrong for the sandboxed renderer — see inline atdocs/superpowers/specs/2026-10-07-1234-creative-click-rewrite-switch-design.md:344anddocs/superpowers/plans/2026-10-07-1234-creative-click-rewrite-switch.md:1712
Non-blocking
🤔 thinking
<base>removal in single-feature modes — see inline at spec:342- Public wrappers bypass both switches — see inline at spec
:305
♻️ refactor
- Task 1 red steps can't be observed — see inline at plan
:637
⛏ nitpick
- Step 5 grep can never pass — plan
:651 - "Unchanged output" vs the shared step's Fixed items — spec
:26, plan:22 - Task 0 has no one-match case — plan
:310 - Suffix-spoof case dropped from the policy test — plan
:352 - Private intra-doc link warning — plan
:92 - Step 8 wording replaces the wrong span — plan
:1363 - Click guard isn't fully inert — spec
:357 - "Without allocating" — spec
:176 - Commit instructions vs CONTRIBUTING.md — plan
:35
Cross-cutting / body-level findings
- ⛏ Smaller precision items
- Citations off by one or two: spec :38 (
proxy.rs:1898-1906), :229 (1672-1703, matching the plan), :486 (endpoints.rs:84-90), :487 (formats.rs:375-378). - The shared CHANGELOG Fixed entry (plan :290) leaves out that unparseable quoted URLs in
<style>/style=are no longer re-quoted viacssparser::serialize_string, and that/first-party/signerror text changes (invalid url/unsupported scheme→unsupported url). "Re-quoted" also understates the old fallback://input was emittedhttps:-prefixed (src=" //exa mple.example/x "→https://exa mple.example/x). - Because settings serialize normalized, the first
ts config pushafter upgrading shows a blob diff for configs with mixed-case/whitespace/""/*exclude entries — worth one line in Rollout. - Expected files (spec :491) omits
auction/orchestrator.rsandauction/endpoints.rs. - Spec :372's provenance sentence reads as if #1231's text lacks the four tests; #1248's plan already has them.
- Spec :107-115 vs plan :886-896 doc comments differ (plan adds the "rejected by binaries that predate this field" clause); spec :122 vs plan :902 likewise.
- Plan :39: Viceroy 0.21.1 vs pinned 0.17.0 (re-run under 0.17.0 gives the same counts).
- PR checklist: the
tracingbox should readlog.
- Citations off by one or two: spec :38 (
- 🌱 Staged / multi-service rollback — spec :467: a blob pushed with
--stagingthat carriesrewrite_clicksalso has to be re-pushed without it before rolling back a staged binary, once per service. - 📌 Trailing-dot hosts bypass
exclude_domains(pre-existing) —https://excluded.example.com./xis still proxied and wrapped in both old and new code (reproduced). Not for this PR; same follow-up as noted on #1248. - 👍 Praise
- The plan is executable as written, with exact counts and byte-exact pins.
- Gating is complete: the anchor handler is the only producer of click URLs, apart from rebuild of already-signed input.
- Keeping
rewrite_clickscommented out in the example TOML is the right call, sincets config initcopies it. Option<bool>with per-path resolution keeps both existing operator groups unchanged.
CI Status
- All 22 checks PASS: Analyze (actions / javascript-typescript / python / rust), CodeQL, CLAUDE.md symlink guard, browser integration tests, integration tests, integration tests (Fastly EC lifecycle), prepare integration artifacts, cargo fmt, cargo test, cargo test (axum native), cargo test (cross-adapter parity), cargo check (cloudflare native + wasm32-unknown-unknown), cargo check/build/test (spin native + wasm32-wasip1), cargo test (ts CLI, native) (macos-latest / ubuntu-latest), vitest, format-typescript, format-docs
Correct the renderGuard caveat for the sandboxed /auction renderer, list the operator docs that become false, keep a bidder <base target> while dropping its href, and warn on the public rewrite wrappers. Also fix citations, the shared CHANGELOG Fixed wording, red-step ordering, the Step 5 grep, rollout and staged rollback notes, and other precision items. Signed-off-by: dhruv8sh <dhruv8sh@proton.me>
|
Closing in favor of #1252 |
Summary
[auction] rewrite_creatives, controls both asset proxying and click wrapping, so an operator can't keep first-party click tracking while leaving assets direct, or the other way round.[auction] rewrite_clicksis anOption<bool>. When unset, it followsrewrite_creatives, so no existing config changes behavior on upgrade./first-party/proxy: an explicit value applies there too, while unset keeps today's always-wrap behavior.<base>removal and TSJS injection: both run when either switch is on.TsCreativeConfig.clickGuard: stays client-only.Changes
docs/superpowers/specs/2026-10-07-1234-creative-click-rewrite-switch-design.mddocs/superpowers/plans/2026-10-07-1234-creative-click-rewrite-switch.mdCloses
Part of #1234. This PR adds only the spec and plan. The implementation PR will link the approved spec and close the issue.
Test plan
cargo test-fastly && cargo test-axumcargo clippy-fastly && cargo clippy-axumcargo fmt --all -- --checkcd crates/trusted-server-js/lib && npx vitest runcd crates/trusted-server-js/lib && npm run formatcd docs && npm run formatcargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1fastly compute serveprettier --config docs/.prettierrc --checkon both files. This PR changes no code, so no Rust or JS gates were run. The plan was checked by implementing it in a local branch, where fmt, all clippy aliases,test-fastly,test-fastly-reuse,test-axum,test-cloudflare,test-spin, the CLI tests and the parity tests passed. That code is not included here.Checklist
unwrap()in production code — useexpect("should ...")tracingmacros (notprintln!)