You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fourth in the rolling pagination conformance series (#3095 cursor↔has_more lint + list_creatives storyboard, #3100 total_count honesty, #3109 get_signals — all merged or in flight). This issue extends the same gates onto `get_media_buys`.
Why `get_media_buys` is the next clean target
Has `pagination` in both request and response schemas.
`comply_test_controller` already exposes `seed_media_buy` (analogous to `seed_creative`), so the storyboard can pre-populate a known fixture set and pin counts deterministically — same shape as `pagination_integrity.yaml`.
`handleGetMediaBuys` at `server/src/training-agent/task-handlers.ts:1642` currently emits no `pagination` block. With small fixture sets the bug is dormant but a real seller with hundreds of media buys would silently truncate.
What's needed
1. Training agent fix (`server/src/training-agent/task-handlers.ts:1642`)
Mirror the `handleListCreatives` pattern:
Read `req.pagination?.max_results` (default 50, cap 100 per the schema).
Step 1 (`first_page`): `get_media_buys` with `pagination.max_results: 2`. Capture `pagination.cursor` into `$context.next_cursor`. Assert `pagination.has_more = true`, `pagination.cursor` present, `pagination.total_count = 3` if volunteered (`field_value_or_absent allowed_values: [3]`), `query_summary` consistency where the schema declares it (check the response schema — get-media-buys-response may not have `query_summary`; if not, drop those assertions).
Step 2 (`terminal_page`): `get_media_buys` with `pagination.cursor: $context.next_cursor, max_results: 2`. Assert `pagination.has_more = false`, `pagination.cursor` absent or null, `pagination.total_count = 3` if volunteered.
3. Wiring
Add a changeset (empty, descriptive name like `get-media-buys-pagination-integrity.md`).
Confirm `build:compliance` picks up the new storyboard (count goes 14 → 15 universal).
Run `pagination_integrity` filter against the training agent: should be 3/3 storyboards clean (list_creatives, get_signals, get_media_buys).
Acceptance criteria
`npm run build:compliance` clean.
`npm run test:pagination-invariant` clean.
`pagination_integrity` filter run against the training agent: all storyboards clean.
Negative test: flipping `has_more` to false on the first page (or stripping the pagination block) trips the storyboard with the expected diagnostic.
Existing `get_media_buys` unit tests still pass (`server/tests/unit/training-agent.test.ts`).
Pre-existing `get_media_buys` callers in storyboards (`media-buy-lifecycle`, `sales-*` specialisms) keep working — they don't pass pagination today and shouldn't be affected by the addition.
Pointers
Pattern: `pagination-integrity.yaml` and `get-signals-pagination-integrity.yaml`
Cursor codec: `encodeOffsetCursor` / `decodeOffsetCursor` at `server/src/training-agent/task-handlers.ts:2087-2127`
Handler to modify: `handleGetMediaBuys` at `server/src/training-agent/task-handlers.ts:1642`
Goal
Fourth in the rolling pagination conformance series (#3095 cursor↔has_more lint + list_creatives storyboard, #3100 total_count honesty, #3109 get_signals — all merged or in flight). This issue extends the same gates onto `get_media_buys`.
Why `get_media_buys` is the next clean target
What's needed
1. Training agent fix (`server/src/training-agent/task-handlers.ts:1642`)
Mirror the `handleListCreatives` pattern:
2. Storyboard (`static/compliance/source/universal/get-media-buys-pagination-integrity.yaml`)
Mirror `pagination-integrity.yaml` (the seeded list_creatives one):
3. Wiring
Acceptance criteria
Pointers
Out of scope