Skip to content

refactor(adagents): extract shared authorized_agents[*] fields into core/authorized-agent-base.json (closes #4510)#4610

Merged
bokelley merged 2 commits into
mainfrom
bokelley/authorized-agent-base
May 17, 2026
Merged

refactor(adagents): extract shared authorized_agents[*] fields into core/authorized-agent-base.json (closes #4510)#4610
bokelley merged 2 commits into
mainfrom
bokelley/authorized-agent-base

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

Closes #4510. Deferred earlier because adcp-client TS codegen produced broken union types on `allOf+$ref` patterns. Unblocked by adcp-client#1756 — PRs #1777 / #1783 shipped a pre-merge pass that flattens `allOf+$ref` siblings before json-schema-to-typescript codegen.

What changes

Five fields shared across all six `authorized_agents[*]` variants (`url`, `authorized_for`, `signing_keys`, `encryption_keys`, `last_updated`) move into a new `static/schemas/source/core/authorized-agent-base.json`. Each variant `allOf`s the base alongside its variant-specific properties.

Discriminator-specific fields (`authorization_type` const + the variant's selector) and property-variant qualifiers (`collections`, `placement_ids`, `placement_tags`, `delegation_type`, `exclusive`, `countries`, `effective_from`, `effective_until`) stay at the variant root so audit-oneof's discriminator detection keeps working.

No semantic change

JSON Schema `allOf` merges the base's properties into each variant's instance shape — validators see the same required-field semantics. Existing files validate unchanged.

Drift prevention

Adding a new shared field now requires one schema edit instead of six. The `last_updated` field that landed in PR #4504 had to be added six times; that's the recurrence this refactor prevents.

Codegen verified

  • Python (`datamodel-codegen`, used by adcp-client-python): clean inheritance — `class AuthorizedAgents{1..6}(AuthorizedAgentBase)`. Field duplication across the six variants eliminated.
  • TypeScript (`json-schema-to-typescript`, used by adcp-client): adcp-client#1756's pre-merge pass handles this shape. End-to-end verification after adcp-client regenerates against this schema; if regression surfaces, file back upstream.

Test plan

  • `audit-oneof.mjs --check` ok (discriminator still resolves; 37 → 39 discriminated thanks to the new base classification)
  • `composed-schema-validation.test.cjs` 43/43 pass
  • `example-validation.test.cjs` 14/14 adagents-relevant pass (7 pre-existing unrelated failures unchanged)
  • Bundled schemas include the new base file (`dist/schemas/latest/core/authorized-agent-base.json`)
  • Python codegen spike: 6/6 variants inherit `AuthorizedAgentBase`

🤖 Generated with Claude Code

bokelley and others added 2 commits May 16, 2026 13:28
…ore/authorized-agent-base.json

Closes #4510. Previously deferred because adcp-client TS codegen
(json-schema-to-typescript) produced broken union types on `allOf+$ref`
patterns. Unblocked by adcp-client#1756 (PRs #1777 / #1783 — pre-merge
pass that flattens `allOf+$ref` siblings before codegen).

Five fields shared across all six authorized_agents[*] variants — url,
authorized_for, signing_keys, encryption_keys, last_updated — move into
core/authorized-agent-base.json. Each variant now allOfs the base
alongside its variant-specific properties.

Discriminator-specific fields (authorization_type const + the variant
selector) and property-variant qualifiers (collections, placement_ids,
placement_tags, delegation_type, exclusive, countries, effective_*)
stay at the variant root so audit-oneof's discriminator detection keeps
working.

No semantic change — the bundled schema permits the same inputs.
Existing files validate unchanged.

Codegen verified:
- Python (datamodel-codegen): clean inheritance,
  AuthorizedAgents1..6(AuthorizedAgentBase). Field duplication across
  six variants eliminated.
- TS (json-schema-to-typescript): adcp-client's just-shipped pre-merge
  pass handles allOf+$ref. End-to-end verification after they regen.

Drift prevention: adding a new shared field requires one schema edit
instead of six (cf. last_updated in PR #4504, which had to be added
six times).

Tests:
- audit-oneof --check: ok (37 -> 39 discriminated; new base classified
  cleanly).
- composed-schema-validation: 43/43 pass.
- example-validation: 14/14 adagents-relevant pass.
- Bundled schemas include the new base file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expert review on PR #4610. Protocol expert's only should-fix:

Pre-refactor, signal_ids/signal_tags variants had distinct prose for
url + authorized_for ("authorized signals agent's API endpoint URL" /
"what signals this agent is authorized to resell"). The first-cut base
collapsed those into property-flavored descriptions, leaving signal-side
codegen docstrings reading wrong.

Neutralized the base-level descriptions to fit both audiences:
- url: refer to registries generically ("sales-agent list, signal-
  provider registry, TMP provider lookup") instead of just TMP/property.
- authorized_for: name both inflections (sells / provides) and pin the
  variant choice as the discriminator.

Plus code-reviewer's nit: dropped "(4 property + 2 signal)" count from
the base description — phrasing was prone to staleness if a 7th
variant lands.

audit-oneof, composed-schema-validation, build all unchanged (39
discriminated; 43/43 tests pass).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley

Copy link
Copy Markdown
Contributor Author

Expert review pass

Two reviews (code-reviewer-deep + ad-tech-protocol-expert). Code-reviewer cleared zero must/should-fix — ships it. Protocol expert's only should-fix addressed in commit 24dcf4a:

  • Description neutralization. Pre-refactor, signal_ids/signal_tags variants had distinct prose ("authorized signals agent's API endpoint URL" / "what signals this agent is authorized to resell"). The base collapsed those into property-flavored descriptions, leaving signal-side codegen docstrings reading wrong. Neutralized the `url` description to name both audiences (sales-agent list, signal-provider registry, TMP provider lookup) and rephrased `authorized_for` to cover both inflections (sells vs provides).
  • Nit: dropped "(4 property + 2 signal)" count from base description — phrasing was prone to staleness if a 7th variant lands.

Build/audit/tests unchanged: 39 discriminated, 43/43 composed-schema-validation pass.

@bokelley bokelley merged commit f0f5abd into main May 17, 2026
13 checks passed
@bokelley bokelley deleted the bokelley/authorized-agent-base branch May 17, 2026 12:44
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.

Refactor authorized_agents[*] shared fields into a base schema (drift prevention)

1 participant