Skip to content

spec(tmp): add required seller_agent_url to context_match_request#5410

Merged
ohalushchak-exadel merged 3 commits into
mainfrom
ohalushchak-exadel/context-match-seller-agent-url
Jun 8, 2026
Merged

spec(tmp): add required seller_agent_url to context_match_request#5410
ohalushchak-exadel merged 3 commits into
mainfrom
ohalushchak-exadel/context-match-seller-agent-url

Conversation

@ohalushchak-exadel

Copy link
Copy Markdown
Collaborator

What

Adds a required seller_agent_url (string, uri) to context_match_request, mirroring the identity-match request (#3687). The provider uses it as the key to resolve the active package set it has synced for the asking seller. When package_ids is omitted, evaluation runs against that seller's full active set; a seller_agent_url the provider has not synced packages for MUST return an empty offer set rather than fall back to another seller's set.

Why this reverses a prior decision

PR #3063's seller-attribution section deliberately kept seller identity off context_match_request, on two grounds: (a) the provider already holds the sync-time seller_agent binding, so a request field is redundant; (b) putting seller on the context path opens a request-time filtering vector that could threaten package-set decorrelation.

In practice that doesn't hold up for a multi-seller provider:

  • A provider serves many sellers. Resolving "which seller's active set do I evaluate" from a deployment-pinned constant forces one provider deployment per seller. The buyer agent already gets seller_agent_url on the wire for exactly this reason on the identity path; the context path needs the same. Deriving seller from property_rid via the sync-time binding is possible but couples active-set resolution to an implicit lookup the request should make explicit — and is asymmetric with identity-match for no real gain.
  • It does not weaken decorrelation. The package-set decorrelation guarantee constrains per-user-varying data — chiefly package_ids, whose composition MUST be independent of placement. seller_agent_url is a single stable value identifying the asking seller: identical for every user on a placement, carrying no user identity, adding no per-user signal that context and identity requests could be correlated on. It is receiver-side active-set scoping, not a per-user filter. The package-side seller_agent binding remains attribution-only.

The normative §Seller Attribution prose (placement rationale, the Router participant row, the "What This Is Not" bullet) is rewritten so the spec is internally consistent with the new field.

Required, and why that's safe here

Required, consistent with identity-match. context_match_request is x-status: experimental, so adding a required field is permitted before the endpoint stabilizes.

Changes

  • static/schemas/source/tmp/context-match-request.jsonseller_agent_url added to properties and required.
  • docs/trusted-match/specification.mdx — §Seller Attribution rewritten (placement rationale, Router row, "What This Is Not").
  • docs/trusted-match/{index,buyer-guide,context-and-identity,ai-mediation}.mdx + docs/trusted-match/surfaces/{web,mobile,ctv,ai-assistants,retail-media}.mdx — request examples updated.
  • tests/example-validation-simple.test.cjs — both context-match request fixtures updated.
  • changeset (minor).

Tests

test:schemas (15/15), test:json-schema (282/282), and example-validation-simple (42/42) all pass.

🤖 Generated with Claude Code

The context-match request now carries seller_agent_url, mirroring the
identity-match request (#3687). The provider uses it to resolve the
active package set it has synced for the asking seller; when
package_ids is omitted, evaluation runs against that seller's full set,
and an unknown seller_agent_url MUST return empty rather than fall back
to another seller's set.

This reverses PR #3063's decision to keep seller identity off the
context request. A provider serves many sellers and needs the asking
seller on the wire to scope its active-set resolution without a
deployment-pinned constant — the same role seller_agent_url plays on
the identity path. It does not weaken package-set decorrelation:
seller_agent_url is a single stable value per placement, carries no
user identity, and adds no per-user signal; the decorrelation guarantee
constrains per-user-varying data (package_ids), which is unchanged. The
package-side seller_agent binding remains attribution-only.

Required, consistent with identity-match; context_match_request is
x-status experimental so the added required field is permitted
pre-stable. Normative seller-attribution prose, request examples across
the trusted-match docs, and the example-validation fixtures are updated
to match.

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

@aao-release-bot aao-release-bot 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.

One required field is missing from the one place that's normative for it. The schema now requires seller_agent_url on context_match_request, but the ContextMatchRequest field table — the human-normative listing an adopter builds the request from — never got the row. That's schema-vs-docs drift on the exact field this PR adds.

The block

docs/trusted-match/specification.mdx:55 — required field missing from the ContextMatchRequest field table. The PR makes seller_agent_url required in static/schemas/source/tmp/context-match-request.json:228 (added to required, schema is additionalProperties: false). The field table at L49-60 is exhaustive — it lists all twelve schema fields through package_ids. seller_agent_url is not among them. The IdentityMatchRequest table at L184 carries its row; the Context table does not.

What breaks for adopters: anyone who constructs context_match_request from the normative field table omits seller_agent_url, and the request fails schema validation (required + additionalProperties: false). The PR updated the §Seller Attribution prose and nine example JSON blocks but skipped the field table that actually defines the contract.

Fix is one row after placement_id (L55): | \seller_agent_url` | string (URI) | Yes | ... |, mirroring the IdentityMatchRequest row at L184. ad-tech-protocol-expert` flagged this as the primary spec-drift defect.

Things I checked

  • Schema edit is well-formed. seller_agent_url property block (string, format: uri) and the required array addition at context-match-request.json:56,228 are valid JSON; additionalProperties: false preserved.
  • Field parity with identity-match. Shape matches identity-match-request.json:39 (string/uri). The description correctly diverges on actor — provider resolves its synced set vs. buyer resolves its registered set — which is right per TMP roles, not a copy-paste error.
  • Decorrelation argument holds. seller_agent_url is a single per-placement constant, identical across users, carries no user identity. The Package-set decorrelation guarantee constrains per-user-varying data (package_ids), which is unchanged. The rewritten "Not a per-user filter" framing at the §Seller Attribution block is internally consistent.
  • Test fixtures pass. Both context-match fixtures (tests/example-validation-simple.test.cjs:760,826) validate against the source schema via AJV with required enforcement; both now carry seller_agent_url. code-reviewer: clean, 42/42 will pass.
  • Example JSON well-formed. All nine .mdx insertions sit after a comma-terminated placement_id line; no trailing-comma breakage.
  • No residual contradicting prose. Checked the surface guides and context-and-identity/buyer-guide — none still assert context_match_request omits seller identity. The old claim lived only in §Seller Attribution, which this PR rewrites.

Follow-ups (non-blocking — file after the table fix)

  • The surface examples using property_id instead of the schema's required property_rid/request_id (surfaces/{web,mobile,ctv,ai-assistants,retail-media}.mdx, context-and-identity.mdx) are illustrative, not schema-validated — pre-existing, out of scope here, but worth a sweep.
  • Changeset prose says "mirroring" / "same role" — the buyer-vs-provider resolution boundary is a real, intended difference, not a mirror. Wording only.

Minor nits (non-blocking)

  1. minor changeset is the right call. context-match-request.json:7 is x-status: experimental; adding a required field pre-stable is permitted and minor is correct. No change needed — noting it so the next reviewer doesn't re-litigate.

Add the table row and I'll flip to approve — everything else is clean. Required field, normative table, no entry: fail-closed for adopters who read the spec.

ohalushchak-exadel and others added 2 commits June 8, 2026 12:39
…table

The schema change made seller_agent_url required, but the normative
ContextMatchRequest field table in specification.mdx — what adopters
build the request from — was missing the row, so a request built from
the table would fail validation. Add the row after placement_id,
mirroring the IdentityMatchRequest table.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…or-specific

The buyer-vs-provider resolution boundary is an intended difference, not
a mirror: the field shape/placement matches identity-match, but the
context path resolves the provider's synced set while the identity path
resolves the buyer agent's registered set. Wording only.

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

@aao-release-bot aao-release-bot 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.

Approving. Symmetric placement of seller_agent_url across both match requests is the right shape — the provider needs the asking seller on the wire to scope active-set resolution, exactly as the buyer agent already does on the identity path.

Things I checked

  • Versioning is correct. context-match-request.json:7 is x-status: experimental, so adding a required field is permitted pre-stable. minor is the right changeset — major would be wrong here precisely because the stability contract doesn't yet apply. ad-tech-protocol-expert: sound.
  • Mirror holds. New field at context-match-request.json:56-60 (string, format: uri, canonicalization clause) matches identity-match-request.json:39-42 near-verbatim, and the required parity is real (both list seller_agent_url). Aligns with seller_agent.agent_url / agent_url conventions. additionalProperties: false preserved; no oneOf/discriminator interaction.
  • All examples updated. All 11 context_match_request examples across docs/trusted-match/** carry the now-required field (4 top-level + 7 surface examples), plus both fixtures in tests/example-validation-simple.test.cjs — which compile the schema through ajv and exit(1) on error, so they'd fail CI if the field were absent. code-reviewer: Approve.
  • Decorrelation argument holds. seller_agent_url is invariant per placement and carries no per-user signal, so it adds nothing to package-set correlation (which constrains per-user-varying package_ids). The rewritten §Seller Attribution (specification.mdx:349, Router row :378, "What This Is Not" :383) is internally consistent with the schema.

Follow-ups (non-blocking — file as issues)

  • Signed-fields gap. The Context Match signed-fields table (specification.mdx:456-463) was not updated. seller_agent_url is now a required, "static per placement" field that scopes which seller's active set the provider resolves, yet it sits outside the signed envelope — meaning the seller scope can be swapped without invalidating the cached per-epoch signature. Identity Match doesn't sign it either, so there's precedent, but a field that selects which seller's set gets evaluated is load-bearing enough to either add to the signed set or to explicitly document as intentionally-unsigned. State the intent.

Minor nits (non-blocking)

  1. Harmonize the decorrelation bullet. specification.mdx:400 still reads "No per-request package list is sent, so the publisher cannot accidentally leak identity through package filtering." Literally still true — package_ids isn't on Context Match — but it reads as residual from the pre-reversal model now that seller scoping lives on the path. A one-clause tie-back to the new §Seller Attribution would keep the two sections in step.

The reversal of #3063 is well-argued in both the PR body and the rewritten prose — the change documents its own parent, which is the right way to relitigate a deliberate prior decision.

LGTM. Follow-ups noted below.

@aao-release-bot aao-release-bot 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.

Approving. Mirrors the identity-match seller_agent_url field exactly, and a multi-seller provider needs the asking seller on the wire to scope active-set resolution — deriving it from a deployment-pinned constant forces one provider per seller, which is the wrong shape.

Things I checked

  • Field shape matches identity-match. string/format: uri/required, same URL-canonicalization comparison rule, same empty-set-on-unsynced-seller MUST. context-match-request.json:56-60 against identity-match-request.json:39-42. Right shape, and symmetric.
  • Changeset is the correct type. minor is right: context-match-request.json:7 is x-status: experimental, so a required field is permitted pre-stable. .changeset/tmp-context-match-seller-agent-url.md present and named well. ad-tech-protocol-expert: sound-with-caveats — no major bump needed.
  • No oneOf/discriminator impact. Both schemas use a const type discriminator with additionalProperties: false, untouched. audit-oneof gate unaffected.
  • Schema-vs-docs coherence. The rewritten §Seller Attribution prose (Placement rationale, Router row, "What This Is Not") is internally consistent with the new field. The rewrite also drops a latent false claim — the old "What This Is Not" bullet asserted package_ids "is not present on Context Match," but context-match-request.json:207 has had an optional package_ids all along. Good cleanup.
  • Required-field fallout is covered. Both inline context-match fixtures got the field (tests/example-validation-simple.test.cjs:763, :837) — those are the only two in the repo. All 9 doc files with a context_match_request block were updated, including all three blocks in surfaces/mobile.mdx. Doc JSON blocks carry no $schema so they aren't strict-validated; no hidden CI failure. code-reviewer: no blockers.

Follow-ups (non-blocking — file as issues)

  • Paired examples disagree with the PR's own thesis. The thesis is that seller_agent_url is "a single stable value identifying the asking seller" — but the same actor shows two different URLs across its paired Context/Identity examples: surfaces/retail-media.mdx:25 (https://grocery-retailer.example) vs :81 (https://retailer.example), and context-and-identity.mdx:35 (https://retailer.example) vs :127 (https://publisher.example). Examples aren't schema-validated so nothing breaks, but a reader pairing the two requests will trip on it. Make each scenario's context value match its identity value.

Minor nits (non-blocking)

  1. synced vs registered drift in the prose. The schema description and changeset deliberately say the provider resolves the set it has synced (context-match-request.json:60), but the rewritten "Placement rationale" in specification.mdx says the provider resolves the set it has registered. The actor-specific split (provider syncs, buyer registers) is the whole point of the rewrite — use "synced" for the provider path so the distinction survives.

LGTM. Follow-ups noted below.

@mintlify

mintlify Bot commented Jun 8, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
adcp 🟡 Building Jun 8, 2026, 10:31 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@ohalushchak-exadel ohalushchak-exadel merged commit 563eaf4 into main Jun 8, 2026
32 checks passed
@ohalushchak-exadel ohalushchak-exadel deleted the ohalushchak-exadel/context-match-seller-agent-url branch June 8, 2026 10:54
ohalushchak-exadel added a commit that referenced this pull request Jun 8, 2026
)

Backport of #5410 to the 3.0.x line. Adds seller_agent_url to
context_match_request so a provider can resolve the active package set
it synced for the asking seller, mirroring the identity-match request's
field shape (resolution actor differs: provider-side here, buyer-side on
identity). Required; context_match_request is x-status experimental, so
the additive required field is patch-eligible per the release playbook.

Changeset is patch (3.0.x is not in pre mode; minor would cut 3.1.0).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ohalushchak-exadel added a commit to adcontextprotocol/adcp-go that referenced this pull request Jun 8, 2026
The seller a context-match request is for now arrives per-request as
`seller_agent_url` (adcontextprotocol/adcp#5410), so a single deployment
serves every seller it has synced packages for. The engine passes
req.SellerAgentURL into Storage.ActivePackages instead of a fixed
deployment-wide value.

- tmproto: add SellerAgentURL to ContextMatchRequest and require it in
  ValidateContextRequest. The types_gen.go field is a manual ahead-of-bundle
  stub for adcp#5410; it regenerates identically once adcp/schemas/VERSION
  pins a bundle containing the field.
- targeting: drop SellerAgentURL from ContextEngine/ContextEngineConfig and
  resolve the active set against req.SellerAgentURL per request.
- contextagent: remove the SELLER_AGENT_URL env var, its config field, and
  validation; update the standalone example env.
- tmpclient: the Activate flow populates seller_agent_url on the context
  request (it already carried it on the identity request).

Co-Authored-By: Claude Opus 4.8 (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