Skip to content

feat(protocol): add agent configuration sync - #6966

Open
bokelley wants to merge 12 commits into
mainfrom
feat/agent-configuration
Open

feat(protocol): add agent configuration sync#6966
bokelley wants to merge 12 commits into
mainfrom
feat/agent-configuration

Conversation

@bokelley

@bokelley bokelley commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add experimental sync_agent_configuration for authenticated caller-to-agent relationship configuration
  • support both delegated human users and autonomous workloads as stable configuration owners; using Claude, ChatGPT, another MCP host, or a UI does not require buyer-agent registration
  • atomically sync capability webhooks and reusable S3, warehouse, and dataset-share reporting destinations
  • keep advertiser-account authorization separate and return seller-issued opaque destination_ref values
  • preserve sync_agent_notification_configs as a compatibility path over the same subscriber set
  • add capability negotiation, documentation, a compliance storyboard, contract tests, and a changeset
  • keep MCP prompt budgets safe by omitting arbitrary unnegotiated extensions and pruning unreachable definitions

Why

get_adcp_capabilities tells callers what a seller supports, but AdCP did not have a durable authenticated surface for a caller to declare connection-level resources it wants to reuse. This fills that relationship layer without self-asserted identities or per-account destination duplication.

For example, a user coming through Claude can register an S3 reporting destination under their delegated user principal. They do not register Claude or themselves as a buyer agent. If the client exposes only a shared service identity, it must first complete delegated authorization or account linking because the seller otherwise cannot isolate user-owned configuration.

It is intentionally separate from #6953. Reporting delivery consumes the seller-issued destination_ref only after a separate account/feed configuration authorizes disclosure.

Identity, safety, and lifecycle

  • caller identity comes from authenticated transport, never the request body
  • the OAuth user subject owns an interactive connection; the client application is actor context
  • an autonomous agent uses its stable workload identity
  • tokens, sessions, JWKS key IDs, bucket coordinates, and connection_id are not owner identities
  • credential rotation preserves configuration only when the new credential resolves to the same principal
  • cross-principal linking requires a separate explicitly authorized administrative operation
  • credentials and signed URLs are forbidden in destination configuration
  • destination references are neither bearer capabilities nor advertiser-account grants
  • one reference names one immutable proof-bound destination generation
  • exact replay of unchanged content returns the same reference; changing provider coordinates, recipient, accepted formats, access mode, or verification contract creates a new reference
  • retained configurations and reporting history continue to resolve old generations
  • failed and dry-run responses cannot leak durable connection state
  • exact idempotent replays are resolved before optimistic-concurrency checks
  • present sections replace atomically; omitted sections are unchanged; an empty section clears it

Validation

  • agent-configuration contract: 10/10 tests pass
  • MCP schema analysis/projection: 38/38 focused tests pass
  • npm run test:mcp-schema-projection
  • npm run test:oneof-discriminators
  • changeset protocol scope check

@gitguardian

gitguardian Bot commented Aug 28, 2026

Copy link
Copy Markdown

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Escalate to human review

Escalate — gated-path change requires human/CODEOWNERS review.

This PR touches static/schemas/source/** (16 files: 8 added, 8 modified), which sits under a hard, deterministic approval gate (gated_paths: true). Because review_decision is REVIEW_REQUIRED (not APPROVED), decision-table row 2 fires and the outcome must be escalate regardless of how clean the diff is.

The reviewer found no blocking or Medium findings — the change is a well-formed, additive experimental surface: the sync_agent_configuration task, request/response schemas, five new core schemas, a capability block, compliance storyboard, docs, and a projection-script change. Changeset is a correct minor for a non-breaking additive surface. oneOf discrimination, schema↔docs coherence, changeset scope, and credential-leak posture were all checked and are safe. This escalation is purely the mechanical gated-path gate, not a quality concern.

Escalation reasons

  • Modifies protocol source schemas under static/schemas/source/** (e.g. agent-notification-config.json, index.json, get-adcp-capabilities-response.json, plus new core/protocol schemas) — a gated path; review_decision is REVIEW_REQUIRED, so human/CODEOWNERS approval is required before merge.

Why human review

  • Touches gated path static/schemas/source/** (16 files) while review_decision is REVIEW_REQUIRED — human/CODEOWNERS approval required (decision rule row 2).
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/agent-configuration-state.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-notification-config-state.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-notification-config.json (modified) matches static/schemas/source/**; static/schemas/source/core/agent-reporting-destination-state.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-reporting-destination.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-webhook-challenge.json (modified) matches static/schemas/source/**; static/schemas/source/core/capabilities-changed-webhook.json (modified) matches static/schemas/source/**; static/schemas/source/core/delivery-provider.json (added) matches static/schemas/source/**; static/schemas/source/core/delivery-recipient.json (added) matches static/schemas/source/**; static/schemas/source/core/reporting-verification-profile-set.json (added) matches static/schemas/source/**; static/schemas/source/enums/notification-type.json (modified) matches static/schemas/source/**; static/schemas/source/enums/task-type.json (modified) matches static/schemas/source/**; static/schemas/source/index.json (modified) matches static/schemas/source/**; static/schemas/source/protocol/get-adcp-capabilities-response.json (modified) matches static/schemas/source/**; static/schemas/source/protocol/sync-agent-configuration-request.json (added) matches static/schemas/source/**; static/schemas/source/protocol/sync-agent-configuration-response.json (added) matches static/schemas/source/**) and the current GitHub review decision is 'REVIEW_REQUIRED', not APPROVED. This is a hard gate enforced in code — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.

@aao-secretariat aao-secretariat Bot added the ladon/needs-human-review Ladon has escalated this PR for human review. label Aug 28, 2026
@bokelley
bokelley force-pushed the feat/agent-configuration branch from 14ae164 to b3bf4cb Compare August 28, 2026 06:55

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Escalate to human review

Escalate — gated schema paths require human/CODEOWNERS approval.

This PR touches 16 files under static/schemas/source/**, a hard, non-overridable approval gate (gated_paths: true). The current review_decision is REVIEW_REQUIRED, not APPROVED, so decision-rule row 2 fires: Ladon cannot auto-approve regardless of how clean the diff is.

The reviewer's delta pass is clean — no critical/high/medium findings. Two files changed since the prior review: idempotency.ts correctly adds sync_agent_configuration to MUTATING_TOOLS (matching the new request schema's required idempotency_key derivation), and the contract test strengthens its secret-rejection assertion to credentials:{} (valid against additionalProperties:false). Prior pass was also clean. This is a net-positive iteration; the escalation is purely a governance gate, not a reflection of code quality.

Escalation reasons

  • Touches gated path static/schemas/source/** (16 files: agent-configuration-state.json, agent-notification-config-state.json, agent-notification-config.json, agent-reporting-destination-state.json, agent-reporting-destination.json, agent-webhook-challenge.json, capabilities-changed-webhook.json, delivery-provider.json, delivery-recipient.json, reporting-verification-profile-set.json, notification-type.json, task-type.json, index.json, get-adcp-capabilities-response.json, sync-agent-configuration-request.json, sync-agent-configuration-response.json) while review_decision is REVIEW_REQUIRED. Human/CODEOWNERS approval required before merge (decision rule row 2). The gate lifts once a real approval is recorded.

Why human review

  • Touches gated path static/schemas/source/** (16 files) while review_decision is REVIEW_REQUIRED — human/CODEOWNERS approval required before merge (decision rule row 2). The gate lifts once a real GitHub/CODEOWNERS approval is recorded.
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/agent-configuration-state.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-notification-config-state.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-notification-config.json (modified) matches static/schemas/source/**; static/schemas/source/core/agent-reporting-destination-state.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-reporting-destination.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-webhook-challenge.json (modified) matches static/schemas/source/**; static/schemas/source/core/capabilities-changed-webhook.json (modified) matches static/schemas/source/**; static/schemas/source/core/delivery-provider.json (added) matches static/schemas/source/**; static/schemas/source/core/delivery-recipient.json (added) matches static/schemas/source/**; static/schemas/source/core/reporting-verification-profile-set.json (added) matches static/schemas/source/**; static/schemas/source/enums/notification-type.json (modified) matches static/schemas/source/**; static/schemas/source/enums/task-type.json (modified) matches static/schemas/source/**; static/schemas/source/index.json (modified) matches static/schemas/source/**; static/schemas/source/protocol/get-adcp-capabilities-response.json (modified) matches static/schemas/source/**; static/schemas/source/protocol/sync-agent-configuration-request.json (added) matches static/schemas/source/**; static/schemas/source/protocol/sync-agent-configuration-response.json (added) matches static/schemas/source/**) and the current GitHub review decision is 'REVIEW_REQUIRED', not APPROVED. This is a hard gate enforced in code — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Escalate to human review

Escalate — gated-path approval gate not yet satisfied.

This PR touches files under the hard, deterministic approval gate static/schemas/source/** (16 files: new sync_agent_configuration schemas, agent-configuration/notification/reporting-destination schemas, capabilities-changed-webhook, enums, index, and get-adcp-capabilities/sync-agent-configuration request+response). Per decision rule row 2, gated_paths: true AND review_decision: REVIEW_REQUIRED (not APPROVED) forces escalation regardless of how clean the diff is. Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded.

The reviewer found no Critical/High/Medium findings: changeset scope/type verified (minor, correct for an additive experimental Normative change; registration_task const→enum widening is non-breaking), schema↔docs coherence checked both directions, discriminated oneOfs on new destination/result schemas confirmed, dist immutability preserved (source-only edits), and the contract test's security coverage validated. Classification is Normative/experimental, not Breaking. Absent the gate, this diff would approve — the escalation is purely the pending human review on the protocol-source surface.

Escalation reasons

  • Touches gated path static/schemas/source/** (16 files) while review_decision is REVIEW_REQUIRED — human/CODEOWNERS approval required (decision rule row 2).

Why human review

  • Touches gated path static/schemas/source/** (16 files) while review_decision is REVIEW_REQUIRED, not APPROVED — human/CODEOWNERS approval required before merge (decision rule row 2).
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/agent-configuration-state.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-notification-config-state.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-notification-config.json (modified) matches static/schemas/source/**; static/schemas/source/core/agent-reporting-destination-state.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-reporting-destination.json (added) matches static/schemas/source/**; static/schemas/source/core/agent-webhook-challenge.json (modified) matches static/schemas/source/**; static/schemas/source/core/capabilities-changed-webhook.json (modified) matches static/schemas/source/**; static/schemas/source/core/delivery-provider.json (added) matches static/schemas/source/**; static/schemas/source/core/delivery-recipient.json (added) matches static/schemas/source/**; static/schemas/source/core/reporting-verification-profile-set.json (added) matches static/schemas/source/**; static/schemas/source/enums/notification-type.json (modified) matches static/schemas/source/**; static/schemas/source/enums/task-type.json (modified) matches static/schemas/source/**; static/schemas/source/index.json (modified) matches static/schemas/source/**; static/schemas/source/protocol/get-adcp-capabilities-response.json (modified) matches static/schemas/source/**; static/schemas/source/protocol/sync-agent-configuration-request.json (added) matches static/schemas/source/**; static/schemas/source/protocol/sync-agent-configuration-response.json (added) matches static/schemas/source/**) and the current GitHub review decision is 'REVIEW_REQUIRED', not APPROVED. This is a hard gate enforced in code — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.

@aao-secretariat

Copy link
Copy Markdown
Contributor

Ladon cannot review this PR until merge conflicts are resolved.

# Conflicts:
#	scripts/mcp-schema-projection.cjs
#	static/schemas/source/enums/notification-type.json
#	tests/mcp-schema-analysis.test.cjs
@bokelley

Copy link
Copy Markdown
Contributor Author

The reusable destination boundary is now exercised by the seller reporting vertical slice in scope3data/embedded-sales-agent#456. The implementation keeps destination references principal-owned and reusable, while the reporting obligation/account configuration remains the disclosure authorization. It intentionally does not advertise managed reporting until proof-bound destination generations and persisted account configuration are connected.

…eat/agent-configuration

# Conflicts:
#	.changeset/add-agent-configuration-sync.md
#	docs/protocol/sync_agent_configuration.mdx
#	scripts/mcp-schema-projection.cjs
#	static/compliance/source/universal/agent-configuration.yaml
#	static/schemas/source/enums/notification-type.json
#	static/schemas/source/protocol/sync-agent-configuration-request.json
#	tests/agent-configuration-contract.test.cjs
…eview

Add the get_agent_configuration read task so callers can bootstrap the
version fence, recover from local-state loss, and poll destination setup
without blind writes. Make destination suspension and revocation
delivery-halting controls with an advertised interval, retain superseded
and revoked generations in readback, and require per-pattern proof before
ready (file write-probe, warehouse commit verification, dataset-share
recipient acceptance with observed readability). Advertise the seller's
per-pattern delivery offering in capabilities so buyers negotiate instead
of probing by rejection. Replace lookahead location/setup_url patterns
with RE2-safe positive classes that admit ABFSS authority locators and
move credential screening to normative canonicalization rules. Restructure
the destination union into self-contained discriminated branches, scope
idempotency records to the principal, define cross-task version coherence,
and extend the conformance storyboard with graded apply, readback,
idempotent replay, and section-clear phases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bokelley

Copy link
Copy Markdown
Contributor Author

Red-team review applied — commit 5d9622f

Four adversarial reviews (protocol semantics, security/identity, implementor DX, product/ops) ran against this PR. They converged on the same diagnosis: the write path was well hardened, but the lifecycle around it was incomplete. This commit closes the blockers:

New read task — get_agent_configuration. Declarative full-replace sync had no GET: a caller that lost local state could only recover by blind-writing, and the expected_configuration_version fence was unobtainable cold. The read task returns connection_id, the version, full credential-free state, and retained superseded/revoked destination generations. It is also the poll mechanism for destination setup progress. Advertised via read_task in capabilities.

Suspension and revocation are now delivery controls. active: false previously only gated new bindings — cutting delivery to a compromised bucket bound to N accounts meant N account-level unwinds. Now suspension halts new deliveries to every generation of the destination within an advertised suspension_interval_seconds, and omitting a destination revokes it (retained under retired_destinations for audit). One call, connection-scoped.

Per-pattern proof and readiness are normative. ready was one advisory prose line. Now: file_transfer requires proven caller control plus a seller write-and-read-back probe; warehouse_materialization requires verified create/commit access; dataset_share requires recipient-side acceptance with provider-observed readability — grant creation alone can never produce ready (this encodes the live Databricks finding from #6911 that grants precede recipient readability). Coordinate canonicalization before proof binding is specified.

Two-sided negotiation. Capabilities now advertise reporting_destination_offerings (per-pattern transports, formats, access modes, verification profiles), so buyers select compatible destinations instead of probing by rejection. The boundary is defined: out-of-offering fails the request atomically with UNSUPPORTED_FEATURE; in-offering provider-side setup failures surface as destination states.

Portable, correct locator patterns. The lookahead regexes rejected Azure's canonical abfss://container@account... locator and don't compile in RE2 validators (adcp-go), while missing percent-encoded and fragment-embedded credential shapes. Replaced with RE2-safe positive classes (reject ? # % and whitespace structurally) plus normative canonicalization+screening rules for what no regex can express.

Hardening sweep. Idempotency records are normatively principal-scoped (the replay payload discloses full connection state); configuration_version coherence across both sync tasks is specified (mutations advance it, seller state transitions don't); dry-run outcomes can't act as a cross-principal oracle; the destination union is restructured into self-contained discriminated branches so TS/Python codegen produces a real tagged union; action precedence is defined; failed responses are pinned to failed/rejected status.

Conformance now exercises the heart. The storyboard previously graded only capability discovery, NO_AUTH, and dry-run — a dry-run-only stub could pass. Added graded phases: non-dry-run apply → get_agent_configuration readback → exact idempotent replay (same key/body, version unchanged, destination_ref preserved) → [] clear with readback.

Merge precondition vs #6953: the two PRs currently duplicate vocabulary by hand (this PR's reporting-verification-profile-set.json vs #6953's reporting-verification-profile.json; divergent provider-domain regexes). Whichever merges second must consume the first's $refs.

All gates green locally: 14/14 contract tests, 28/28 MCP projection/analysis, full server suite 7334 passed, schema build, storyboard lints, compliance symbol check, typecheck.

Deferred (fixture-dependent conformance: version-fence conflict, ref-generation rotation, cross-principal isolation; and agent-level delivery-ready webhooks, which need #6953's event types) — will be tracked in follow-up issues.

🤖 Generated with Claude Code

@bokelley

Copy link
Copy Markdown
Contributor Author

Issue #7010 proposes controller-backed conformance coverage for the agent configuration lifecycle (optimistic-concurrency conflict, destination generation rotation, cross-principal isolation, suspension halt timing, per-pattern proof completion, out-of-offering rejection) — same surface (universal/agent-configuration.yaml) as this PR; consider folding before merge or confirm follow-up.


Triaged by Claude Code. Session: https://claude.ai/code/session_013DBtVqNEgTqMBiLBTbBYcj


Generated by Claude Code

The configuration owner is a party — a buyer agent or an operator-side
identity — and principal is the term the normative text already uses
throughout. Rename sync_agent_configuration/get_agent_configuration to
sync_principal/get_principal, the adcp.agent_configuration capability
block to adcp.principal, the protocol.agent_configuration experimental
feature to protocol.principal, connection_id to principal_id, and the
storyboard to universal/principal. Rewrite the identity documentation in
party vocabulary: two principal kinds, agent-scoped operator labels with
a normative cross-principal non-alignment rule, shared-credential
refusal, and per-hop principal composition for chained
buyer-agent/intermediary/seller deployments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bokelley

Copy link
Copy Markdown
Contributor Author

Renamed the surface to the principal layer in commit a27fee9dc9, following design review on RFC #7015: the configuration owner is a party — a buyer agent or an operator-side identity — and principal is the term the normative text already used throughout. sync_agent_configurationsync_principal, get_agent_configurationget_principal, adcp.agent_configurationadcp.principal, protocol.agent_configurationprotocol.principal, connection_idprincipal_id, storyboard → universal/principal. The identity documentation is rewritten in party vocabulary: two principal kinds, agent-scoped operator labels with a cross-principal non-alignment MUST, shared-credential refusal, and per-hop composition for chained buyer-agent/intermediary/seller deployments. All surfaces renamed are experimental and unreleased, so this is free now and impossible later. sync_agent_notification_configs keeps its name as the shipped 3.2 compatibility task.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ladon/needs-human-review Ladon has escalated this PR for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant