Skip to content

fix(decisioning): post-#484 capabilities-projection polish (deferred from expert review)Β #485

Description

@bokelley

🚧 DO NOT TRIAGE β€” owned by @bokelley. Bundles 5 small follow-ups deferred from #484 expert review. None are blockers; bundling so they can land in one polish PR.

Context

#484 (capabilities projection) merged with two expert reviews (code-reviewer + ad-tech-protocol-expert) flagging items as deferred polish β€” none wire-incorrect, but worth tightening before downstream adopters lean heavily on the new declaration shape.

Items

P1 β€” Re-export gaps (code-reviewer finding)

Features2 and ContentStandards not in adcp.decisioning.capabilities.__all__.

Files: src/adcp/types/capabilities.py, src/adcp/decisioning/capabilities.py, tests/test_decisioning_capabilities_submodule.py

P2 β€” Deprecation warning stacklevel (code-reviewer finding)

src/adcp/decisioning/handler.py:992,1008,1027 β€” DeprecationWarning fires at stacklevel=2, which points to the caller of get_adcp_capabilities (the MCP dispatcher), not the adopter's DecisioningCapabilities(...) declaration site. Move the warnings into __post_init__ so stacklevel=2 lands on the adopter's declaration.

Trade-off documented: warning fires at construction whether or not projection runs (the right behavior β€” declaration mistakes shouldn't hide until first buyer query).

P3 β€” Hoist import warnings (code-reviewer nit)

Three local import warnings in get_adcp_capabilities. Hoist to module top.

P4 β€” Auto-derive direction warning (protocol-expert finding)

Auto-deriving supported_protocols from specialisms is semantically backwards per spec β€” specialisms roll up TO protocols, not the other way. Add a warn-on-derive emit when projection takes the derive path (no explicit supported_protocols set), pointing adopters at the override path. Doc note in docs/decisioning-capabilities.md.

P5 β€” Compliance-testing footgun (protocol-expert finding)

When caps.compliance_testing is not None and the platform doesn't expose a comply_test_controller method, the seller advertises a capability it can't honor β€” buyers will fail when they try to drive scenarios. Add boot-time hasattr(platform, "comply_test_controller") check; warn if missing.

Out of scope (separate issues if/when needed)

  • Top-level forward-compat fields (extensions_supported, experimental_features, last_updated, errors, context, ext) β€” adopters have no projection path. Defer until requested by a real adopter; opening this seam early risks shipping the wrong abstraction.
  • Empty supported_billing list ships invalid when adopter sets Account(supported_billing=[]) directly. Pydantic enforces min_length=1 on the wire model so construction fails β€” the issue only arises if adopters circumvent typed construction. Document, don't add a runtime guard.

Acceptance criteria

  • Features2 and ContentStandards re-exported from adcp.types.capabilities and adcp.decisioning.capabilities
  • DeprecationWarnings emitted from __post_init__ (or otherwise pointing at adopter declaration site)
  • import warnings hoisted to module top
  • Auto-derive of supported_protocols emits a warning + doc note
  • compliance_testing-without-method fires UserWarning at boot via validate_platform
  • tests/test_decisioning_capabilities_submodule.py regression coverage for each item

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions