Context
PR #4702 lands the universal version_negotiation storyboard exercising both halves of the release-precision negotiation contract introduced by spec PR #3493:
- Seller advertises
adcp.supported_versions on get_adcp_capabilities.
- Seller echoes
adcp_version at the envelope root on every response.
Both validations ship severity: advisory at 3.1 per docs/reference/versioning.mdx § Migration timeline and promote to required at 3.2.
The training agent — the reference implementation everyone copies — currently emits neither. It passes the storyboard solely because the validations are advisory. To feed the 3.2 cutover with a reference implementation that passes the (then-required) checks, both emissions need to land in the 3.1 window.
What's missing
adcp.supported_versions advertisement
server/src/training-agent/task-handlers.ts:3053-3068 returns:
adcp: {
major_versions: [...SUPPORTED_MAJOR_VERSIONS], // present
idempotency: { supported: true, replay_ttl_seconds: 86400 },
// no supported_versions
// no build_version
}
Add supported_versions: [...SUPPORTED_RELEASE_VERSIONS] (release-precision strings, e.g. ["3.0"] initially; ["3.0", "3.1"] once the agent's pinned SDK ships 3.1.x schemas). Pattern: ^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$ per /schemas/protocol/get-adcp-capabilities-response.json.
build_version (full semver, e.g. "3.0.6+training-agent.42") is optional advisory metadata — nice-to-have but not required.
adcp_version envelope echo
grep -rn adcp_version server/src/ returns only badge/registry surfaces — there is no envelope-level emission anywhere on the response path. The envelope echo lives at the framework-server response-wrapping layer, not the task-handler layer.
Spec posture (versioning.mdx § Bidirectional negotiation, step 4):
Server echoes: adcp_version on every response tells the buyer which release the seller actually served. The echoed value is the release served, never the seller's own latest release — a 3.1 seller serving a 3.0 buyer at 3.0 echoes "3.0". Buyers SHOULD validate the response against that release's schema, not against their pin.
Implementation:
- Read incoming request's
adcp_version (release-precision) and adcp_major_version (legacy integer fallback).
- Resolve against
SUPPORTED_RELEASE_VERSIONS per the algorithm in versioning.mdx (exact match → downshift within major → VERSION_UNSUPPORTED if no release ≤ pin in same major or different major).
- On normal responses, echo the resolved release on the envelope. When the request omitted both fields, echo the default release (highest supported).
- On
VERSION_UNSUPPORTED errors, populate error.data per /schemas/error-details/version-unsupported.json — supported_versions array is authoritative.
The core/version-envelope.json allOf composition already covers the field on every request/response schema after spec PR #3493 — this is a runtime emission change, not a schema change.
Acceptance
Refs
Context
PR #4702 lands the universal
version_negotiationstoryboard exercising both halves of the release-precision negotiation contract introduced by spec PR #3493:adcp.supported_versionsonget_adcp_capabilities.adcp_versionat the envelope root on every response.Both validations ship
severity: advisoryat 3.1 perdocs/reference/versioning.mdx§ Migration timeline and promote to required at 3.2.The training agent — the reference implementation everyone copies — currently emits neither. It passes the storyboard solely because the validations are advisory. To feed the 3.2 cutover with a reference implementation that passes the (then-required) checks, both emissions need to land in the 3.1 window.
What's missing
adcp.supported_versionsadvertisementserver/src/training-agent/task-handlers.ts:3053-3068returns:Add
supported_versions: [...SUPPORTED_RELEASE_VERSIONS](release-precision strings, e.g.["3.0"]initially;["3.0", "3.1"]once the agent's pinned SDK ships 3.1.x schemas). Pattern:^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$per/schemas/protocol/get-adcp-capabilities-response.json.build_version(full semver, e.g."3.0.6+training-agent.42") is optional advisory metadata — nice-to-have but not required.adcp_versionenvelope echogrep -rn adcp_version server/src/returns only badge/registry surfaces — there is no envelope-level emission anywhere on the response path. The envelope echo lives at the framework-server response-wrapping layer, not the task-handler layer.Spec posture (versioning.mdx § Bidirectional negotiation, step 4):
Implementation:
adcp_version(release-precision) andadcp_major_version(legacy integer fallback).SUPPORTED_RELEASE_VERSIONSper the algorithm in versioning.mdx (exact match → downshift within major →VERSION_UNSUPPORTEDif no release ≤ pin in same major or different major).VERSION_UNSUPPORTEDerrors, populateerror.dataper/schemas/error-details/version-unsupported.json—supported_versionsarray is authoritative.The
core/version-envelope.jsonallOf composition already covers the field on every request/response schema after spec PR #3493 — this is a runtime emission change, not a schema change.Acceptance
adcp.supported_versionspresent onget_adcp_capabilitiesresponse (release-precision strings)adcp_versionecho on every response envelope (or all responses on the public surface)VERSION_UNSUPPORTEDreturned with structurederror.datawhen the buyer's pin can't be honoredversion_negotiationstoryboard passes with both advisory validations now satisfiedpermanent_advisorymarkers can be removed when the 3.2 cut promotes them to requiredRefs
specs/version-negotiation.md