Skip to content

fix(training-agent): refuse installment_refs with UNSUPPORTED_FEATURE - #8986

Open
bokelley wants to merge 1 commit into
mainfrom
fix/8968-training-agent-reject-installment-refs
Open

bokelley wants to merge 1 commit into
mainfrom
fix/8968-training-agent-reject-installment-refs

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

This is a follow-up to #8972 (#8968). The training agent doesn't list the experimental media_buy.installment_creative_assignment. #8972 says a seller without the feature MUST reject installment_refs with UNSUPPORTED_FEATURE, and this PR makes the training agent do that.

Change

server/src/training-agent/assignment-operations.ts gets one check, beside the existing trackers and landing_page_url capability checks. It refuses installment_refs on any assignment operation with UNSUPPORTED_FEATURE, and field is assignment_operations[i].installment_refs. Because the request is atomic, nothing is applied.

Until now the training agent ignored the field:

  • an assign or replace applied to every installment;
  • an unassign carrying the field got past the agent's request handling and removed the creative from every installment, even though the schema rejects installment_refs on unassign.

Test

A new case in server/tests/unit/assignment-operations.test.ts covers assign, replace and unassign with installment_refs. Each must return UNSUPPORTED_FEATURE on that field, the existing assignment must be unchanged afterwards with no installment_refs in readback, and get_adcp_capabilities must not list the feature. The file passes 22/22.

There's no changeset: this is training-agent code, and check-changeset-protocol-scope finds no protocol-scoped changes.

Local hook notes (CI is the gate)

Release Planning approved both skips for this commit.

  • Committed with HUSKY=0. Staging server/src runs the full precommit:server-unit suite, which exceeds its 1500s budget at host load ~185. I ran these instead:
    • test:unit: one 10s load timeout in tests/ipr-check-and-record.test.mjs, which passes alone (23/23); its other steps pass, including test:auction-only-compliance (182/182).
    • The test:test-dynamic-imports, test:format-identity-boundaries and test:callapi-state-change guards, and typecheck: all pass.
    • The server unit files nearest the change: assignment-operations (22/22; the only server unit test that touches assignment operations), training-agent-served-release-fields, training-agent-creative33-buyer and tenant-smoke. That's 102/104. The two tenant-smoke cases with a fixed 15s timeout pass once the timeout is raised locally; that edit wasn't committed.
  • Pushed with ADCP_SKIP_STORYBOARD_MATRIX=1. The local matrix is advisory, and training-agent-storyboards.yml is the gate.

🤖 Generated with Claude Code

…#8968)

The training agent does not list media_buy.installment_creative_assignment,
so it refuses installment_refs on any assignment operation with
UNSUPPORTED_FEATURE (field assignment_operations[i].installment_refs), as
#8972 requires of a seller without the feature. Before this, the field was
ignored: an assign or replace applied to every installment, and an unassign
carrying it removed the creative from every installment.

Committed with HUSKY=0 (approved by Release Planning for this commit):
precommit:server-unit exceeds its 1500s budget at host load ~185. Run by
hand instead: test:unit (one 10s load timeout in ipr-check-and-record,
which passes alone), the dynamic-import, format-identity and callApi guards,
typecheck, and the server unit files nearest the change
(assignment-operations 22/22, served-release-fields, creative33-buyer,
tenant-smoke; two tenant-smoke cases with a fixed 15s timeout pass once the
timeout is raised locally, not committed).

Refs #8968

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bokelley
bokelley marked this pull request as ready for review November 13, 2026 17:54

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Approve

Approve.

Clean implementation of #8972's UNSUPPORTED_FEATURE refusal for installment_refs. The change adds one unconditional capability check at assignment-operations.ts:102, placed alongside the existing trackers/landing_page refusals and returning before locate() so the atomic request applies nothing — correct behavior with no kind guard since installment_refs can ride assign/replace/unassign. New test covers all three operation kinds plus unchanged-readback and capabilities-absent.

Non-protocol scope (static/schemas/source/** untouched), so no changeset is required — consistent with check-changeset-protocol-scope. No high-risk paths, no gated paths, no author-team gate, no prior decision. No medium-or-worse findings reported.

Decision table: rows 1-8 do not fire (no findings, gated_paths false, high_risk false, no team gate). Falls through to row 9 — approve. Note: review_decision is REVIEW_REQUIRED but gated_paths is false, so row 2 does not apply.

This branch has not been deployed

No deployments
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.

1 participant