feat(media-buy): add cursor pagination for bounded delivery breakdowns - #7298
Conversation
There was a problem hiding this comment.
Ladon verdict: Request changes
Request changes — 1 blocking finding.
Blocking findings
- docs/media-buy/task-reference/get_media_buy_delivery.mdx:965 — Schema↔docs coherence drift: the schema adds a mandatory
by_<dim>_paginationcursor contract ("Sellers MUST return") for device_type/device_platform/audience/placement in get-media-buy-delivery-response.json, but the docs Truncation section still states the contract provides no cursor. The docs assert a wire shape the schema no longer encodes — mandatory schema↔docs coherence drift, classifiedhighper repo rules.
The additive cursor-pagination change otherwise checks out: changeset type/scope (minor, additive), pagination-response reuse, oneOf discriminator, released-artifact immutability, and the deliberate geo exclusion are all sound. The docs page under docs/media-buy/task-reference/ must be updated to reflect the new mandatory cursor contract before this can merge.
Note: this PR also touches gated paths (static/schemas/source/**) with review_decision REVIEW_REQUIRED; human/CODEOWNERS review is required regardless.
Blocking findings
- docs/media-buy/task-reference/get_media_buy_delivery.mdx:965 — Schema adds mandatory by__pagination cursor contract but docs Truncation section still states no cursor is provided; schema↔docs coherence drift (high)
|
Fixed in 78674ce — updated the Truncation section in `docs/media-buy/task-reference/get_media_buy_delivery.mdx`, which flatly stated the truncated-flag contract "does not provide a cursor." Now documents the new retrieval path for `device_type`/`device_platform`/`audience`/`placement` while keeping the existing "analytical ranking only, no cursor" framing accurate for every other dimension (`geo` included, per its deliberate exclusion). Generated by Claude Code |
get_media_buy_delivery's by_<dim>_truncated flags told a buyer that a breakdown was clipped but gave no way to retrieve the dropped rows — re-requesting with a higher limit isn't a defined retrieval path. Adds reporting_dimensions.<dim>.cursor on the request and by_<dim>_pagination (reusing the existing pagination-response.json shape already used by get_products) on the response, for the four bounded-enum dimensions: device_type, device_platform, audience, placement. geo is deliberately excluded. At postal_area granularity it can reach tens of thousands of rows — closer to a bulk-export shape than per-package cursor pagination — and is deferred to the bulk-export/ security work tracked in adcontextprotocol#5669/adcontextprotocol#5666 rather than shipping a second retrieval mechanism here, per this issue's own maintainer triage. Verified against the current schema (not just the issue's description): the sort/limit negotiation echo contract (by_<dim>_sorted_by / by_<dim>_sort_direction, PR adcontextprotocol#6627) already covers these same five dimensions but explicitly left this exact gap as "the complement." Added 20 new test cases to sort-contract-delivery-reporting.test.cjs covering request/response schema shape and validation for all four dimensions, confirmed real by temporarily reverting the schema changes and observing the new tests fail, then restoring and confirming green. Full npm run test:schemas suite (183 tests) and npm run build:schemas both pass. Closes adcontextprotocol#5671. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VPVi4oM4fC7MLRfcFW7KzE
…ery truncation docs The Truncation section stated flatly that the truncated-flag contract "does not provide a cursor" — no longer accurate for device_type, device_platform, audience, and placement now that by_<dim>_pagination exists for them. Documents the new retrieval path for those four dimensions and keeps the existing "no cursor, analytical ranking only" framing accurate for every other dimension (geo included). Addresses the schema/docs coherence finding from this PR's automated review. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VPVi4oM4fC7MLRfcFW7KzE
There was a problem hiding this comment.
Ladon verdict: Escalate to human review
Escalate — gated schema paths modified without required approval.
This PR adds new bounded-enum pagination fields to two protocol schemas under static/schemas/source/** (get-media-buy-delivery-request.json and -response.json), with matching docs, a minor changeset, and a test. The reviewer's pass was clean: schema↔docs coherence holds (device_type, device_platform, audience, placement gain cursor request fields + by__pagination response fields, geo excluded), the changeset is a correct minor, and the get_products cross-reference is accurate. No Critical/High/Medium findings, so no blocking issues on content.
However, both modified files fall under a hard, deterministic approval gate (gated_paths: true) and review_decision is CHANGES_REQUESTED — not APPROVED. Per decision rule row 2, this PR cannot be approved until a human/CODEOWNERS review clears it.
Escalation reasons
static/schemas/source/media-buy/get-media-buy-delivery-request.json(modified) — gated protocol-schema path; requires human/CODEOWNERS approval.static/schemas/source/media-buy/get-media-buy-delivery-response.json(modified) — gated protocol-schema path; requires human/CODEOWNERS approval.review_decisionisCHANGES_REQUESTED; the gate is not satisfied.
Why human review
- Gated path static/schemas/source/media-buy/get-media-buy-delivery-request.json (modified) requires human/CODEOWNERS approval; review_decision is CHANGES_REQUESTED, not APPROVED
- Gated path static/schemas/source/media-buy/get-media-buy-delivery-response.json (modified) requires human/CODEOWNERS approval; review_decision is CHANGES_REQUESTED, not APPROVED
- This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/media-buy/get-media-buy-delivery-request.json (modified) matches
static/schemas/source/**; static/schemas/source/media-buy/get-media-buy-delivery-response.json (modified) matchesstatic/schemas/source/**) and the current GitHub review decision is 'CHANGES_REQUESTED', not APPROVED. This is a hard gate enforced in code — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.
…n pagination
The four new reporting_dimensions.<dim>.cursor request fields (added in
this PR) push the media-buy profile's model-context prompt-view input
size past the existing 412 KiB ceiling by ~50 bytes. Bumped to 413 KiB,
following this test file's own established practice of raising the
ceiling by the measured amount a specific, deliberate schema addition
needs (see the preceding history in the comment above the constant) —
the same view only strips descriptions, so this is pure additive
structural cost from four small { type: string } fields, not something
reducible by trimming prose.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VPVi4oM4fC7MLRfcFW7KzE
78674ce to
d2a3d95
Compare
Dismissed after the follow-up commit aligned the documentation with the pagination schema; current head has a human approval and green CI.
bokelley
left a comment
There was a problem hiding this comment.
Re-approving current head after dismissal of the superseded automated change request.
Closes #5671.
Summary
get_media_buy_delivery'sby_<dim>_truncatedflags told a buyer that a breakdown was clipped but gave no way to retrieve the dropped rows — re-requesting with a higherlimitisn't a defined retrieval path. Addsreporting_dimensions.<dim>.cursoron the request andby_<dim>_pagination(reusing the existingpagination-response.jsonshape already used byget_products) on the response, for the four bounded-enum dimensions:device_type,device_platform,audience,placement.geois deliberately excluded — atpostal_areagranularity it can reach tens of thousands of rows, closer to a bulk-export shape than per-package cursor pagination, and is deferred to the bulk-export/security work tracked in #5669/#5666 rather than shipping a second retrieval mechanism here. This follows the most recent of three triage passes on this issue, which converged on exactly this split.Verification
Checked the current schema directly rather than trusting the issue description: the sort/limit negotiation echo contract (
by_<dim>_sorted_by/by_<dim>_sort_direction, PR #6627) already covers these same five dimensions, but its own description explicitly names #5671 (breakdown continuation) as "the complement" — confirming the gap this issue names is still live.Tests
Added 20 new test cases to
tests/sort-contract-delivery-reporting.test.cjscovering request/response schema shape and validation for all four dimensions (plus a case provinggeodeliberately does not get these fields). Confirmed the tests are real: temporarily reverted the schema changes, watched the new tests fail, restored, confirmed green again.npm run build:schemassucceedsnpm run test:schemas(183 tests) passesnode scripts/check-changeset-protocol-scope.cjs origin/mainpassesnpx @changesets/cli status --since=origin/mainshows the expected minor bumpnode scripts/check-pr-title.cjspasses on this title🤖 Generated with Claude Code
https://claude.ai/code/session_01VPVi4oM4fC7MLRfcFW7KzE