Skip to content

feat(adcp): add force_create_media_buy_arm + force_task_completion controller scenarios#282

Draft
bokelley wants to merge 2 commits intomainfrom
claude/issue-281-force-create-media-buy-arm-force-task-completion
Draft

feat(adcp): add force_create_media_buy_arm + force_task_completion controller scenarios#282
bokelley wants to merge 2 commits intomainfrom
claude/issue-281-force-create-media-buy-arm-force-task-completion

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

Closes #281

Adds two new TestControllerStore scenarios for storyboard parity with the Node training-agent (adcp#3115, adcp#3194). Sellers running the create_media_buy_async.yaml storyboard suite against a Python reference seller will now grade passing rather than not_applicable on the submitted-arm phase.

Changes

  • src/adcp/server/test_controller.py — adds force_create_media_buy_arm and force_task_completion to SCENARIOS, adds abstract base stubs with full docstrings (including idempotency/isolation contract examples), adds dispatcher branches with centralized input validation (arm enum, conditional task_id-when-submitted, char limits, non-empty result dict, whitespace-strip on task_id for both scenarios), and derives register_test_controller's inline enum from SCENARIOS so it can't drift.
  • src/adcp/server/mcp_tools.py — adds both new scenario names to ADCP_TOOL_DEFINITIONS comply_test_controller enum (the static stub; the Pydantic-generated path also now carries them).
  • src/adcp/types/generated_poc/compliance/comply_test_controller_request.py — adds force_create_media_buy_arm and force_task_completion to the Scenario enum and arm/task_id/result fields to Params, so _apply_pydantic_schemas() generates the correct live MCP tool schema rather than clobbering the new names with the stale generated enum.
  • schemas/cache/compliance/comply-test-controller-request.json — adds both scenario names to the request schema enum, arm/task_id/result param properties, and allOf conditional constraints.
  • schemas/cache/compliance/comply-test-controller-response.json — adds ForcedDirectiveSuccess as a new oneOf variant (required: success, arm; discrimination via not: required:[previous_state|scenarios|simulated|error]), and adds both new names to ListScenariosSuccess.scenarios.items.enum.
  • tests/test_force_create_media_buy_arm_and_force_task_completion.py — 19 new tests at parity with the Node training-agent nine-test pattern: valid registration (submitted + input-required arms), overwrite-pending, INVALID_PARAMS for missing/bad arm, task_id conditional requirement, char limits, whitespace task_id rejection, force_task_completion valid/idempotent/diverging/cross-account, INVALID_PARAMS for missing task_id/empty result/long task_id, list_scenarios advertisement (both implemented, neither implemented, partial).

What was tested

  • pytest tests/ (excluding slow integration + ip_pinned_transport): 2181 passed, 21 skipped, 0 failures
  • ruff check src/: clean
  • mypy src/adcp/server/test_controller.py: no errors
  • Verified ADCP_TOOL_DEFINITIONS["comply_test_controller"] enum at import time includes both new names after the Pydantic schema generation pipeline runs

Pre-PR review

  • code-reviewer: approved — all blockers addressed (Pydantic enum clobber fixed via generated model update; whitespace task_id stripped in both dispatchers); 4 nits noted below
  • ad-tech-protocol-expert: approved — ForcedDirectiveSuccess oneOf discrimination is airtight across all four sibling variants; NOT_FOUND cross-account isolation matches AdCP caller-isolation semantics; both original blockers resolved; one nit (whitespace task_id also absent from force_task_completion) fixed in follow-up commit

Nits surfaced (not fixed — follow-up candidates)

  • arm="" produces "Missing required parameter: 'arm'" rather than the more accurate "arm must be 'submitted' or 'input-required'" — misleading wording, correct error code
  • Non-string task_id (e.g. integer from JSON) passes the not-check and hits len() with TypeError, landing in INTERNAL_ERROR instead of INVALID_PARAMS — pre-existing pattern in other dispatchers; low-severity since MCP clients are typed
  • _BothStore in tests has a redundant explicit TestControllerStore base (already inherited via both parents)
  • Test store overrides use **kwargs rather than the documented *, context=None opt-in pattern

Triage-managed PR. This bot does not currently iterate on
review comments or PR conversation threads (only on the source
issue). To unblock:

  • Push fixup commits directly: gh pr checkout <num>
    fix → push.
  • Or re-trigger: comment /triage execute on the source
    issue.

See adcp#3121
for context.

Session: https://claude.ai/code/session_01HcWEyL1xWQtFTmDEaMme8Q


Generated by Claude Code

claude added 2 commits April 25, 2026 20:44
…ntroller scenarios

Adds two new TestControllerStore scenarios for storyboard parity with the
Node training-agent (adcp#3115, adcp#3194). Sellers running the
create_media_buy_async.yaml storyboard suite will now grade `passing`
rather than `not_applicable` on the submitted-arm phase.

https://claude.ai/code/session_01HcWEyL1xWQtFTmDEaMme8Q
…chema, whitespace task_id

- Add force_create_media_buy_arm + force_task_completion to the
  generated Scenario enum so _apply_pydantic_schemas() doesn't clobber
  the live ADCP_TOOL_DEFINITIONS enum at import time
- Add arm/task_id/result fields to the generated Params model to match
  the updated request schema cache
- Add ForcedDirectiveSuccess oneOf variant to comply-test-controller-
  response.json so spec-compliant validators accept the new response shape
- Strip whitespace from task_id in both force_create_media_buy_arm and
  force_task_completion dispatchers to prevent empty-string bypass
- Add force_create_media_buy_arm + force_task_completion to
  ListScenariosSuccess.scenarios.items.enum in the response schema

https://claude.ai/code/session_01HcWEyL1xWQtFTmDEaMme8Q
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement force_create_media_buy_arm + force_task_completion controller scenarios for AdCP storyboard parity

2 participants