Repository navigation
Extract lockr app IDs from audit page metadata - #1496
ChristianPavilonis wants to merge 5 commits into
Conversation
prk-Jr
left a comment
There was a problem hiding this comment.
Summary
Approving. Extracting the public lockr app ID from page metadata is well-scoped: the ID lands in the audit artifact, the draft config gets an escaped app_id with enabled = false, and missing/empty IDs stay on the manual-review path.
Non-blocking
👍 praise
- The generated
[integrations.lockr]section cannot collide with the starter template (its lockr section is fully commented), and subsequent slot tables keep the draft valid TOML. app_idgoes through the sharedtoml_stringescaping, and the offline tests cover quotes, backslashes, entity-decoded newlines, empty-first metadata, and deploy validation of the result.- The tests run the full
run_generatepath both with and without a concurrent lockr script, so they pin the metadata-evidence precedence and the "finding an ID does not enable lockr" contract.
CI Status
- All 29 checks pass on
a0a8d1367. - Audit-generate CLI tests also pass locally at the PR head (280 passed, 6 ignored).
dhruv8sh
left a comment
There was a problem hiding this comment.
Summary
Adds lockr app ID extraction from lockr-signin-app_id page metadata to ts audit generate, records it in the audit artifact, and drafts a disabled [integrations.lockr] section. Well-contained, keeps the integration disabled and on the manual-review path, and thoroughly covered by offline regressions. Only non-blocking observations below.
Non-blocking
- 🤔 Live lockr section appended separately from the template's commented block — inline at
generate/mod.rs:459 - 🤔 IDs containing control characters are accepted and asserted valid — inline at
analyzer.rs:76 - 📝 Metadata without
contentstill marks lockr detected — inline atanalyzer.rs:73 - ⛏ Selector could be parsed once via
LazyLock— inline atanalyzer.rs:70 - 👍 Thorough offline tests and safe
enabled = falsedefault — inline atgenerate/mod.rs:2380
CI Status
All 29 checks: PASS.
aram356
left a comment
There was a problem hiding this comment.
Summary
Extracting lockr's public app ID from page metadata is well scoped, and the extraction itself is thoroughly tested. The blocking problem is the generated draft: it appends a second [integrations.lockr] table while the template's commented example stays in place, and uncommenting that example, which is the template's documented workflow, makes the draft fail to load (repro inline). The docs also ask operators to complete checks before enabling lockr that only work after it is enabled.
5 of the 6 inline comments below carry a one-click GitHub
suggestion. Use Commit suggestion (or Add suggestion to batch for several at once) to apply them as commits on the PR branch. Themod.rs:459comment describes its fix in prose because it adds a helper outside the diff. Every suggestion was applied on its own and together on a scratch worktree atf1b5d4a6fand checked withcargo fmt --all -- --check,cargo clippy-cli, andcargo test -p trusted-server-cli --lib(767 passed); the docs ones with prettier andvitepress build.
Blocking
🔧 wrench
- Draft carries two lockr blocks; uncommenting the template one is a duplicate-table error — see inline at
crates/trusted-server-cli/src/commands/audit/generate/mod.rs:459 - CLI guide asks for verification checks that need lockr enabled — see inline at
docs/guide/cli.md:355 - Lockr guide has the same problem and no pointer to
origin_override— see inline atdocs/guide/integrations/lockr.md:20 - Conflicting page IDs are picked without a warning — see inline at
crates/trusted-server-cli/src/commands/audit/generate/analyzer.rs:76 - No test that the generated section can be enabled — see inline at
crates/trusted-server-cli/src/commands/audit/generate/mod.rs:2444 - Three loop asserts have no message — see inline at
crates/trusted-server-cli/src/commands/audit/generate/mod.rs:2420
Cross-cutting / body-level findings
- 🔧 Re-run the two failed CI jobs —
prepare integration artifactsandworker-deadlines (spin)failed onf1b5d4a6fwith HTTP 504 while downloading GitHub release assets (wasm-bindgen-0.2.126-x86_64-unknown-linux-musl.tar.gzandspin-v4.1.0-linux-amd64.tar.gz). That is infrastructure, unrelated to this diff, and neither check is required by branch protection; a re-run should clear both. - 🔧 Answer and resolve the five open review threads —
mainrequires review-thread resolution before merge, and the five threads from the earlier review (mod.rs:459,analyzer.rs:70,analyzer.rs:73,analyzer.rs:76,mod.rs:2380) have no reply, so the PR cannot merge as it stands regardless of approvals. - 🔧 File a follow-up for the unused
app_id—LockrConfig.app_idmust be nonempty when lockr is enabled, but nothing reads it after validation:crates/trusted-server-core/src/integrations/lockr.rsnever usesself.config.app_id. That is why the selection rules in this PR (trim, first nonempty, conflicting values) have no runtime effect today. Please open an issue to either consume the ID or drop the requirement, and link it here; the code change itself is out of scope for this PR.
CI Status
- cargo fmt: PASS (required)
- cargo test: PASS (required)
- format-typescript: PASS (required)
- format-docs: PASS (required)
- cargo test (ts CLI, native) (ubuntu-latest): PASS
- cargo test (ts CLI, native) (macos-latest): PASS
- cargo test (axum native): PASS
- cargo test (cross-adapter parity): PASS
- cargo check (cloudflare native + wasm32-unknown-unknown): PASS
- cargo check/build/test (spin native + wasm32-wasip1): PASS
- HTML EOF runtime (Fastly): PASS
- worker-deadlines (cloudflare): PASS
- worker-deadlines (spin): FAIL (HTTP 504 fetching the Spin release; see above)
- prepare integration artifacts: FAIL (HTTP 504 fetching the wasm-bindgen release; see above)
- vitest: PASS
- ts dev lint domains (changed lines): PASS
- docs-proposal scripts: PASS
- CI Node pin guard: PASS
- CLAUDE.md symlink guard: PASS
- Analyze (rust): PASS
- Analyze (javascript-typescript): PASS
- Analyze (python): PASS
- Analyze (actions): PASS
- CodeQL: PASS
- integration tests: SKIPPED
- integration tests (Fastly EC lifecycle): SKIPPED
- browser integration tests: SKIPPED
- trace runtime and browser acceptance: SKIPPED
Review follow-upPushed 41dcf1f.
All 11 inline review points have individual responses, including the no-change decisions, and their threads are resolved. Review summaries@prk-Jr, the guarantees noted in your approval remain covered. Although the original disabled draft parsed correctly, the later review identified a duplicate-table failure when operators followed the template's uncommenting instructions. In-place generation now removes that trap. @dhruv8sh, every point in your review has a thread response. Control-character filtering was declined because it would impose an unsupported ID-format restriction on the agreed nonempty extraction contract. The escaping regression remains, and does not claim upstream SDK acceptance. Selector caching was deferred because there is no demonstrated performance problem. Metadata-only detection and disabled generation are unchanged. @aram356, all six inline requests in your review are addressed in this commit. For the body-level requests:
VerificationThe two new behavioral regressions failed before the production fixes and passed afterward.
Live lockr SDK/API behavior, the ignored browser/platform fixtures, and separate adapter/JS suites were not exercised locally. Current-head CI is not yet complete. |
aram356
left a comment
There was a problem hiding this comment.
Summary
Round 2 at 41dcf1ffd. Every round-1 finding is addressed. The draft now fills the template's lockr block in place: I re-probed uncommenting every optional lockr key and enabling the section, and the result parses and passes check_candidate. A template edit that breaks the replacement also fails run_generate_extracts_lockr_app_id_from_page_metadata, so it can't drift silently. Both guides now route verification through staging and point at origin_override. Conflicting IDs warn, the enabled-config and single-table regressions are in, #1519 tracks the unused app_id, all 11 threads are resolved, and CI is green on this head.
One new blocker, which my own round-1 suggestion introduced: the conflicting-ID warning leaks into ts audit ad-templates generate with wording that only fits ts audit generate.
The inline comment describes its fix in prose because it spans
analyzer.rsandmod.rs. The fix and its regression test were scratch-verified at41dcf1ffd(cargo fmt --all -- --check,cargo clippy-cli,cargo test -p trusted-server-cli --lib: 769 passed), and the test fails without the fix.
Blocking
🔧 wrench
- Lockr conflict warning leaks into ad-template notes with wrong wording — see inline at
crates/trusted-server-cli/src/commands/audit/generate/analyzer.rs:84
Cross-cutting / body-level findings
- 📝 Merge in main before merging —
mainrequires branches to be up to date and this one is behind by #917 (6fbe64aa0, adds[publisher].public_origin). I mergedorigin/maininto this head locally: no conflicts, andcargo test -p trusted-server-clipasses on the merged tree (768 lib tests plus the integration targets).
CI Status
- cargo fmt: PASS (required)
- cargo test: PASS (required)
- format-typescript: PASS (required)
- format-docs: PASS (required)
- cargo test (ts CLI, native) (ubuntu-latest): PASS
- cargo test (ts CLI, native) (macos-latest): PASS
- cargo test (axum native): PASS
- cargo test (cross-adapter parity): PASS
- cargo check (cloudflare native + wasm32-unknown-unknown): PASS
- cargo check/build/test (spin native + wasm32-wasip1): PASS
- HTML EOF runtime (Fastly): PASS
- worker-deadlines (cloudflare): PASS
- worker-deadlines (spin): PASS
- prepare integration artifacts: PASS
- integration tests: PASS
- integration tests (Fastly EC lifecycle): PASS
- browser integration tests: PASS
- trace runtime and browser acceptance: PASS
- vitest: PASS
- ts dev lint domains (changed lines): PASS
- docs-proposal scripts: PASS
- CI Node pin guard: PASS
- CLAUDE.md symlink guard: PASS
- Analyze (rust): PASS
- Analyze (javascript-typescript): PASS
- Analyze (python): PASS
- Analyze (actions): PASS
- CodeQL: PASS
| warnings.push( | ||
| "page carries more than one distinct lockr app ID; the draft uses the first" | ||
| .to_string(), | ||
| ); |
There was a problem hiding this comment.
🔧 wrench — This warning now leaks into ts audit ad-templates generate, which writes no lockr config. It came from my round-1 suggestion: I missed that fold_collected turns every analyzer warning into a per-page note.
Repro at 41dcf1ffd: run_update_slots over a page with two distinct lockr-signin-app_id values, with desktop and mobile profiles, prints on stderr:
note: `/` on desktop: page carries more than one distinct lockr app ID; the draft uses the first
note: `/` on mobile: page carries more than one distinct lockr app ID; the draft uses the first
"the draft uses the first" is wrong for that command, which only rewrites [creative_opportunities] slots. And because the note is scoped per page and profile, a shared <head> repeats it for every crawled page (the default budget is 17 pages per profile). fold_collected already avoids that kind of repetition for CONSENT_STUB_WARNING.
Proposed fix (apply manually; it touches analyzer.rs and mod.rs): name the warning, and skip it in fold_collected the same way the consent stub is special-cased.
analyzer.rs, next to LOCKR_APP_ID_SELECTOR:
/// Recorded when page metadata carries more than one distinct lockr app ID.
pub(super) const LOCKR_APP_ID_CONFLICT_WARNING: &str =
"page carries more than one distinct lockr app ID; the draft uses the first";analyzer.rs, here:
warnings.push(LOCKR_APP_ID_CONFLICT_WARNING.to_string());mod.rs, at the top of the warning loop in fold_collected:
for warning in &artifact.warnings {
// Lockr app IDs only feed the `ts audit generate` draft. Slot generation
// writes no lockr settings, so the conflict is not actionable here.
if warning == analyzer::LOCKR_APP_ID_CONFLICT_WARNING {
continue;
}Regression test for the mod.rs tests module:
#[test]
fn update_slots_omits_lockr_app_id_conflicts_from_notes() {
let temp = TempDir::new().expect("should create temp dir");
let config_path = temp.path().join("trusted-server.toml");
fs::write(
&config_path,
"[creative_opportunities]\ngam_network_id = \"123456789\"\n",
)
.expect("should write config");
let mut page = collected_page_with_header_slot();
page.html = r#"<html><head><meta name="lockr-signin-app_id" content="first-app-id"><meta name="lockr-signin-app_id" content="second-app-id"></head></html>"#.to_string();
let collector = FakeCollector::new(page);
let mut err = Vec::new();
run_update_slots(
&UpdateSlotsRequest {
url: "https://publisher.example/",
config_path: &config_path,
existing_creative: None,
page_patterns: &[],
replace: false,
cookies: &[],
dry_run: true,
yes: false,
interactive: false,
scroll: false,
budget: CrawlBudget::default(),
},
&[("desktop", &collector)],
&mut Vec::new(),
&mut err,
&mut io::empty(),
)
.expect("should preview generated slots");
let notes = String::from_utf8(err).expect("should write UTF-8 notes");
assert!(
!notes.contains("lockr app ID"),
"should not report a generate-only lockr conflict during slot generation: {notes}"
);
}Scratch-verified at 41dcf1ffd: cargo fmt --all -- --check clean, cargo clippy-cli clean, cargo test -p trusted-server-cli --lib 769 passed / 0 failed. Removing the fold_collected filter makes the new test fail. Your analyze_collected_page_warns_only_on_distinct_lockr_app_ids test passes unchanged, and it can compare against the constant if you prefer.
Summary
Changes
crates/trusted-server-cli/src/commands/audit/generate/analyzer.rscrates/trusted-server-cli/src/commands/audit/generate/mod.rsenabled = false, and add offline file-output regressions.docs/guide/cli.mddocs/guide/integrations/lockr.mdCloses
Closes #1495
Test plan
New offline regression fails against the original behavior because the audit artifact lacks the discovered ID.
cargo +1.98.1 test -p trusted-server-cli --target x86_64-unknown-linux-gnu: 951 passed, 30 ignored, no failures on the combined state after merging currentmain.Offline regressions exercise metadata-only detection, concurrent script detection, whitespace normalization, empty-first metadata, HTML entity decoding, TOML escaping, missing/empty content, manual review, and deploy validation.
cargo +1.98.1 fmt --all -- --checkgit diff --checkcargo +1.98.1 clippy-cli --target x86_64-unknown-linux-gnucargo +1.98.1 run --package trusted-server-cli --target x86_64-unknown-linux-gnu --bin ts -- dev lint domains --changed-vs origin/mainDocs formatting:
cd docs && npx prettier --check guide/cli.md guide/integrations/lockr.mdDocs site build and link validation:
cd docs && npm run buildLive lockr SDK/API behavior and the existing ignored browser/platform fixtures were not exercised. Adapter and standalone JS suites were not run. The documentation-only follow-up leaves the previously tested Rust sources unchanged.
Review follow-up
main, preventing a merged-test compilation failure.cc11942bb. No remaining code findings. The later guide update passed docs formatting and site build checks.Checklist
unwrap()or new logging dependencies.