Skip to content

feat(training-agent): wire BuyerAgentRegistry on all v6 tenants + sandbox-mode adaptation for SDK 6.8.0#4026

Merged
bokelley merged 1 commit into
mainfrom
bokelley/buyer-agent-registry
May 3, 2026
Merged

feat(training-agent): wire BuyerAgentRegistry on all v6 tenants + sandbox-mode adaptation for SDK 6.8.0#4026
bokelley merged 1 commit into
mainfrom
bokelley/buyer-agent-registry

Conversation

@bokelley

@bokelley bokelley commented May 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Phase 1 BuyerAgentRegistry adoption (per adcp-client#1269). Unblocked by SDK 6.8.0's extra-forwarding fix — issue #1484 (filed earlier in this session) → PR #1488 → shipped in 6.8.0.

Also bundles the SDK 6.8.0 sandbox-mode adaptation: 6.8.0 added a new comply_test_controller gate (isSandboxOrMockAccount) that requires resolved accounts to be in sandbox/mock mode. Training-agent operates as a public sandbox by design but didn't communicate that on the wire. Without this fix, the SDK bump alone would FORBIDDEN-reject every comply-controller storyboard. Pre-push storyboard floors confirm: all six tenants meet baselines after the fix.

What landed

  1. SDK pin bumped to ^6.8.0.
  2. Bearer authenticator stamps extra: { demo_token: token } on the AuthPrincipal returned for demo-* test bearers (server/src/training-agent/index.ts). The token doesn't survive AdcpCredential normalization (api_key.key_id is SHA-256 hashed); extra is the documented escape hatch for prefix-based test conventions.
  3. New buyer-agent-registry.tsBuyerAgentRegistry.bearerOnly resolver that reads extra.demo_token, delegates to commercial-relationships.ts for the principal → relationship lookup, and returns a BuyerAgent record with the appropriate billing_capabilities Set.
  4. All six v6 tenant platforms wire agentRegistry: trainingBuyerAgentRegistry. The framework calls agentRegistry.resolve(authInfo) once per request before accounts.resolve and threads the resolved record through ctx.agent to platform handlers — forward-compat for SDK Phase 2 framework-level enforcement.
  5. sandbox: true added to all accounts.resolve return values across the six v6 platforms (both ref == null synthetic-public-sandbox and brand/operator-resolved paths). Required by SDK 6.8.0's new comply_test_controller gate.

No gate-logic changes. commercial-relationships.ts remains the source of truth; legacy /mcp keeps consuming it via handleSyncAccounts. The v6 path now also has ctx.agent.billing_capabilities populated.

Tests

  • 6 new unit tests in buyer-agent-registry.test.ts covering all branches (passthrough/agent-billable prefix resolution, unrecognized prefix → null, missing extra → null, defensive type-checks, http_sig refusal).
  • Existing sync-accounts-gates.test.ts (11 tests) and account-handlers.test.ts (22 tests) all pass — proves gate logic still fires correctly.
  • Pre-push storyboard floors: all six tenants meet baselines (signals: 65 clean / 70 steps; sales: 65/74; governance: 64/70; creative: 65/83; creative-builder: 59/65; brand: 65/14).
  • Targeted suite: 39/39 pass.
  • Typecheck clean.

Phase 2 outlook

When SDK Phase 2 ships framework-level enforcement, the only remaining work is to delete the gate logic from account-handlers.ts and let the framework reject BILLING_NOT_PERMITTED_FOR_AGENT against ctx.agent.billing_capabilities directly. commercial-relationships.ts stays as the registry's data source.

Cross-links

🤖 Generated with Claude Code

Phase 1 BuyerAgentRegistry adoption per adcp-client#1269. Unblocked
by SDK 6.8.0's extra-forwarding fix (issue #1484 / PR #1488 — both
filed and reviewed in this session).

- SDK pin bumped to ^6.8.0.
- Bearer authenticator stamps extra: { demo_token: token } on the
  AuthPrincipal returned for demo-* test bearers. The token doesn't
  survive AdcpCredential normalization (api_key carries key_id:
  SHA-256(token)); extra is the documented escape hatch for
  prefix-based test conventions.
- New buyer-agent-registry.ts — BuyerAgentRegistry.bearerOnly
  resolver that reads extra.demo_token, delegates to
  commercial-relationships.ts for the principal → relationship
  lookup (single source of truth), and returns a BuyerAgent record
  with the appropriate billing_capabilities Set. Unrecognized
  credentials return null (uniform-response rule). Signed
  credentials are refused per the bearerOnly factory's posture.
- All six v6 tenant platforms wire agentRegistry:
  trainingBuyerAgentRegistry — sales, signals (v6-platform.ts),
  governance, creative, creative-builder, brand. Framework calls
  agentRegistry.resolve(authInfo) once per request before
  accounts.resolve and threads the resolved record through
  ctx.agent to platform handlers.

No gate-logic changes. commercial-relationships.ts remains the
source of truth and the legacy /mcp path keeps consuming it via
handleSyncAccounts. The v6 platforms now ALSO have
ctx.agent.billing_capabilities populated — forward-compat for SDK
Phase 2 (adcp-client#1292) framework-level enforcement of
BILLING_NOT_PERMITTED_FOR_AGENT.

Tests: 6 new unit tests on the registry resolver covering all
branches (prefix matching, missing extra, defensive type-checks,
http_sig refusal). Existing sync-accounts-gates integration test
(11 tests) and account-handlers unit test (22 tests) all pass —
proves the gate logic still fires correctly under the new wiring.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bokelley bokelley merged commit 0651046 into main May 3, 2026
21 of 22 checks passed
@bokelley bokelley deleted the bokelley/buyer-agent-registry branch May 3, 2026 20:50
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