Skip to content

fix(migrate): per-symbol replacement for generated_poc reach-ins#329

Merged
bokelley merged 1 commit intomainfrom
bokelley/migrate-codemod-ergonomics
Apr 30, 2026
Merged

fix(migrate): per-symbol replacement for generated_poc reach-ins#329
bokelley merged 1 commit intomainfrom
bokelley/migrate-codemod-ergonomics

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

Summary

Fixes the three round-5 adopter feedback items from the salesagent v3→v4 experiment (/.context/adcp-v4-migration-feedback.md). 82 of 156 codemod findings were generated_poc flag-only output that forced adopters to hand-grep the public-API module — this PR turns those into explicit "Symbol → adcp.types.Symbol" replacements.

  • Codemod: GENERATED_POC_SYMBOL_MAP covers 8 unambiguous reach-ins with per-symbol replacements (AccountReference, BrandReference, ContextObject, CreativeAsset, Error, MediaBuyStatus, ProductFilters, ReportingWebhook). Multi-symbol imports emit one Finding per known symbol. import X as Y aliases are handled. Text report prints "Symbol → replacement" on the header line.
  • Migration guide cascade callout: documents salesagent's pattern of centralizing SDK imports in a barrel module where one broken import crashes ~140 tests during pytest collect-only. Calls out the priority order: removed-type imports first, then generated_poc reach-ins, then numbered Assets<N>, then per-call-site shape changes.
  • Migration guide a2a-sdk callout: flags the a2a-sdk>=1.0.0 surprise migration for adopters with direct a2a.utils.errors / a2a.types imports.

Intentionally NOT mapped

CreditLimit, Setup, GovernanceAgent appear in 8+ generated files (per-schema variants like core/account.Setup vs account/sync_accounts_response.Setup); a blanket adcp.types.Setup hint would be ambiguous. Adopters reaching for these get the generic flag; landing them in the public API is a separate design decision (which canonical variant to expose / whether to expose schema-namespaced aliases).

Test plan

  • pytest tests/test_migrate_v3_to_v4.py — 33 passed (4 new tests covering per-symbol mapping, multi-symbol imports, alias handling, drift guard)
  • pytest tests/ — 2183 passed
  • ruff check clean
  • mypy clean
  • CLI smoke test on a fixture file confirms human-readable output shows "Symbol → adcp.types.Symbol" header per known reach-in
  • Drift test ensures every entry in GENERATED_POC_SYMBOL_MAP is on adcp.types.__all__

Release plan

This PR accumulates into the held release-please PR #328 alongside the v6.0 DecisioningPlatform foundation (#316). Both ship in the same 4.4.0 release once salesagent validates against the editable install.

🤖 Generated with Claude Code

Round-5 adopter feedback (salesagent v3→v4 experiment, 270 files /
161 collection failures): 82 of 156 codemod findings were
``adcp.types.generated_poc`` flag-only output that forced adopters
to hand-grep the public-API module to find each replacement.

Fixes:

- ``GENERATED_POC_SYMBOL_MAP`` covers the 8 unambiguous reach-ins
  with explicit "Symbol → adcp.types.Symbol" replacements:
  AccountReference, BrandReference, ContextObject, CreativeAsset,
  Error, MediaBuyStatus, ProductFilters, ReportingWebhook. The
  ``test_generated_poc_symbol_map_covers_publicly_exported_names``
  test guards drift between the codemod and the SDK's public surface.
- Multi-symbol single-line imports (``from … import A, B, C``) emit
  one Finding per known symbol; unknown symbols and multiline imports
  fall back to the generic "private module" flag.
- Text report shows per-symbol replacement on the header line so
  adopters fix without leaving the codemod output.
- ``import X as Y`` aliases are handled — the codemod keys off the
  canonical LHS name.

Intentionally NOT mapped: ``CreditLimit``, ``Setup``,
``GovernanceAgent``. These names appear in 8+ generated files
(per-schema variants like ``core/account.Setup`` vs.
``account/sync_accounts_response.Setup``); a blanket
``adcp.types.Setup`` hint would be ambiguous. Adopters reaching for
these get the generic flag; landing them in the public API is a
separate design decision.

Migration guide additions:

- "Fix removed-type imports first — they cascade" section documents
  salesagent's pattern of centralizing SDK imports in a barrel
  module (``_base.py`` re-export) where one broken import crashes
  ~140 tests during pytest collect-only. Calls out the priority
  order: barrel modules first, then generated_poc reach-ins, then
  numbered Assets, then per-call-site shape changes.
- "a2a-sdk transitive bump" section flags the ``a2a-sdk>=1.0.0``
  surprise migration for adopters with direct ``a2a.utils.errors`` /
  ``a2a.types`` imports.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit 100680b into main Apr 30, 2026
12 checks passed
bokelley added a commit that referenced this pull request May 1, 2026
…ionLists Protocols (breadth sprint Batch 4 — FINAL) (#335)

Final batch of the breadth-sprint per the parity audit. Ports the
remaining four specialism Protocols from JS reference. With this
PR, every spec specialism slug except ``governance-aware-seller``
has a Protocol class + REQUIRED_METHODS coverage.

New Protocols:

* ``BrandRightsPlatform`` — covers ``brand-rights``. Identity
  discovery + licensing. Required (3, sync): ``get_brand_identity``,
  ``get_rights``, ``acquire_rights``. ``acquire_rights`` returns a
  3-arm discriminated success union (acquired / pending / rejected)
  — rejection-as-data for spec-defined GRANT rejection, AdcpError
  only for buyer-fixable REQUEST rejection. Async outcomes for the
  ``pending`` arm flow via ``push_notification_config`` webhook
  (NOT a polling tool).

* ``ContentStandardsPlatform`` — covers ``content-standards``.
  Brand safety policies, content adjacency rules, per-creative
  compliance verification. Required (6): list/get/create/update,
  ``calibrate_content``, ``validate_content_delivery``. Optional
  (2, analyzer reads): ``get_media_buy_artifacts``,
  ``get_creative_features``.

* ``PropertyListsPlatform`` + ``CollectionListsPlatform``
  (specialisms/lists.py) — covers ``property-lists`` and
  ``collection-lists``. Parallel CRUD shapes (5 methods each, all
  required) with token-issuance semantics: ``create_*`` returns a
  per-seller-scoped ``fetch_token``, ``delete_*`` revokes it.
  Compromise-driven revocation MUST trigger the delete path.

Required-method coverage in ``REQUIRED_METHODS_PER_SPECIALISM``:
``brand-rights`` (3), ``content-standards`` (6),
``property-lists`` (5), ``collection-lists`` (5).

Public re-exports added at ``adcp.decisioning.__all__``:
``BrandRightsPlatform``, ``ContentStandardsPlatform``,
``PropertyListsPlatform``, ``CollectionListsPlatform``.

Test coverage in ``tests/test_decisioning_specialisms.py`` (13 new
tests, 43 total in the file):

* ``runtime_checkable`` conformance per Protocol.
* ``validate_platform`` enforcement per slug — including a
  security-relevant test that ``property-lists`` REQUIRES
  ``delete_property_list`` (revocation path) so adopters can't ship
  list-publishing without revocation primitives.
* Contract pins per slug.
* **Breadth-sprint completeness pin**:
  ``test_every_spec_slug_except_governance_aware_seller_is_enforced``
  asserts that ``SPEC_SPECIALISM_ENUM - REQUIRED_METHODS.keys()``
  yields exactly ``{governance-aware-seller, signed-requests}`` —
  the two slugs unenforced by design (composition claim and
  deprecated-moved-to-universal respectively).

One existing dispatch test updated:
``test_validate_platform_warns_on_unenforced_spec_specialism``
swapped its canonical "spec-recognized but unenforced" example
from ``brand-rights`` (now enforced) to ``governance-aware-seller``
(the only remaining unenforced spec slug — by design).

**Breadth sprint COMPLETE.** All 8 missing specialism Protocols
from the parity audit are now ported. 9 PRs total accumulating in
the held release PR #328:

* #316 foundation
* #329 codemod ergonomics
* #330 parity rename + Tier 1 docs
* #331 F12 auto-emit
* #332 Signals + Audience (Batch 1)
* #333 Creative Builder + AdServer (Batch 2)
* #334 Campaign Governance (Batch 3)
* #335 Brand + Content + Lists (Batch 4 — this PR)

Ready for salesagent validation against editable install before
tagging 4.4.0.

2252 tests pass (up from 2239).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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