Repository navigation
fix(ci): validate external smoke capabilities against the served release - #8208
Merged
Merged
Conversation
The daily external smoke job has failed every run since #7511. It pins the default hosted line (3.0). A 3.0 pin cannot carry adcp_version, so @adcp/sdk sends get_adcp_capabilities with only adcp_major_version: 3. Per docs/reference/versioning.mdx the agent serves its highest 3.x release and echoes adcp_version "3.2", but testCapabilityDiscovery validates the response against the 3.0 pin, so 3.2-only shapes (features.bidding_policy, newer compliance_testing scenarios) are reported as schema errors. The spec says buyers validate against the echoed release, not their pin. When the echo differs from the pin, the check now requires the echo to be in adcp.supported_versions, discovers again pinned to that release (the SDK then validates strictly against it), requires the agent to keep serving it, and resolves storyboards from that release's hosted bundle. Two more failures were hidden behind the schema error: - SDK 15.8.1 keys comply_test_controller as protocol "compliance" in its tool cross-check but parses the compliance_testing block as "compliance_testing", so every compliance-capable agent fails that step. Waive only that exact message, and only when the response carries the block. - The anonymous probe now gets a 401 Bearer challenge. Classify the SDK's "requires OAuth authorization" message as auth evidence. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — tooling-only fix to scripts/external-smoke/** plus its unit test.
Checked:
- No findings at any severity (Critical/High/Medium/Low all empty).
- No author no-auto-approve team match.
gated_paths: false, so the row-2 hard gate does not apply despitereview_decision: REVIEW_REQUIRED.high_risk: false; no deleted/modified high-risk files.- No protocol surface touched (
static/schemas/source/**,docs/reference/**,dist/**, task/compliance assets untouched), so the omitted changeset is correct and no schema↔docs, oneOf, immutability, or 3.1.x patch-eligibility rules are triggered. - The new load-bearing path in
check.ts(negotiateServedRelease, cross-check waiver, releasePrecision) is fail-closed, bounded by existing discovery timeouts, and fully covered by the new tests.
No blocking or escalation triggers fired; falls through to row 9.
This was referenced Oct 15, 2026
bokelley
added a commit
that referenced
this pull request
Oct 16, 2026
…orkarounds (#8231) SDK 15.9.2 fixes the two bugs that #8208 worked around in the external smoke check (adcp-client#3278, #3279). Capability discovery now validates get_adcp_capabilities against the echoed adcp_version when it is in the pin's major and bundled. The protocol/tool cross-check now keys comply_test_controller under compliance_testing. Removed from scripts/external-smoke: the compliance cross-check waiver, and the served-release re-pin with its second discovery (ReleaseProbe, RepinProbe, releasePrecision, servedRelease, negotiateServedRelease, repinFor). Kept on top of the single 15.9.2 discovery: OAuth 401 classification, the echoed release must share the pin's major and be listed in supported_versions, and storyboards resolve from the served release's hosted bundle (new resolverFor option). The "same release when re-pinned" check needed the second probe and is dropped. SDK 15.9.0 adds pattern/transport to adcp_reporting_destination_ authorizations. PostgresReportingManagedDeliveryStore uses them in authorizeDestination, installBinding and claimRevocation (every worker pass), and its probe does not check them. Migration 624 adds them verbatim from REPORTING_MANAGED_DELIVERY_MIGRATION, plus the 15.9 tombstone retry columns for ledger parity. The disposable-PostgreSQL suite passes 8/8 with it and fails 6/8 without it. Moves the exact current-version pins to 15.9.2 (SDK doc, Addie certification text with a CODE_VERSION bump, buyer evidence, provenance tests). Re-records the TypeScript conformance baseline: all 125 cases, same 3.2.1 digest, counts and finding; only the SDK version changed. Removes the two request-signing SDK_KNOWN_GAPS todos, which now pass. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The daily External smoke schedule workflow has failed on all 21 runs since #7511. The smoke check validated the deployed agent's capabilities against the release the client pinned, but it should validate against the release the agent actually served. The deployed agent is behaving as the spec requires. No agent change and no deploy are needed.
Root cause
withHostedTestOptions(..., hostedComplianceTarget())pinsadcpVersion: "3.0.27"(the default hosted line, 3.0). It sets nowireAdcpVersion.@adcp/sdk15.8.1,buildVersionEnvelope(dist/lib/protocols/index.js, about line 125) checksbundleSupportsAdcpVersionField("3.0"). That returns false, so the client sends only the major version. This is the request captured against the public agent:{"method":"tools/call","params":{"name":"get_adcp_capabilities","arguments":{"adcp_major_version":3}}}docs/reference/versioning.mdx("Server resolves") says that when onlyadcp_major_versionis sent, the server uses its highest supported release in that major. The agent does this: it answersadcp_version: "3.2",supported_versionsincludes"3.2", and the response carries the 3.2features.bidding_policyobject and 24 scenarios.testCapabilityDiscoveryinstead validates against the pin. It callsvalidateIncomingResponse(..., schemaAdcpVersion ?? client.getAdcpVersion())indist/lib/testing/client.jsat line 416.TaskExecutor.validateResponseSchema(dist/lib/core/TaskExecutor.js, line 4400) does the same. This produces the/media_buy/features/bidding_policyand/compliance_testing/scenarios/4..Nissues.adcp_version: "3.0", the agent echoes"3.0"and leaves outbidding_policy. The smoke probe never asked for 3.0.This is case (b): the smoke check validated against the wrong version.
Fix (
scripts/external-smoke/)When the echoed
adcp_versiondiffers from the pin, the check now:adcp.supported_versions;adcp_version: "3.2"and validates strictly against 3.2;sales-doohspecialism the agent declares at 3.2.The check still fails on any schema issue. If the echo matches the pin, or there is no echo, it still validates against the pin, as the spec says for legacy sellers.
Two more failures were hidden behind the schema error. Each would have failed the job on the next run:
crossValidateProtocolsAndTools(dist/lib/testing/scenarios/capabilities.js, line 242) listscomply_test_controllerunder the protocolcompliance. ButparseCapabilitiesResponsereports thecompliance_testingblock as the protocolcompliance_testing. As a result, every agent that declares the block correctly fails withTools suggest unreported protocols: compliance (has: [comply_test_controller]). The check now ignores only that exact message, and only when the response actually carries thecompliance_testingblock. Any other cross-check problem still fails./sales/mcpgets a 401 Bearer challenge. The SDK turns it intoNeedsAuthorizationError("... requires OAuth authorization ..."), which reaches the check only as a step string. The check now treats that message as auth evidence, so the anonymous probe reportsauth-required.No changeset: this changes only tooling and tests, not the protocol surface.
SDK follow-up (adcp-client, not patched here)
The bugs are unchanged in 15.9.1 (latest).
dist/lib/testing/client.js:416(discoverAgentProfile) anddist/lib/core/TaskExecutor.js:4400(validateResponseSchema): validate against the release the server echoed (data.adcp_version) when it is a release in the same major that has a bundled schema. Fall back to the pin only when the echo is absent. This matchesversioning.mdxstep 4.dist/lib/testing/scenarios/capabilities.js:242: change the keycompliance:tocompliance_testing:to matchTOOL_PROTOCOL_MAPandparseCapabilitiesResponse.Once both are fixed, the re-pin and the cross-check exception in
check.tscan be removed.Not fixed here (separate, low priority)
With an explicit
adcp_version: "3.0",/sales/mcpstill lists the newercompliance_testing.scenarios, becausesalesCapabilityScenariosonly uses the 3.0 list understoryboardCompat. The spec's "serving an older pin" guidance says new enum values fall under the unknown-value tolerance rule, and the smoke probe never sends that pin. I left it out of this PR.Test plan
npx vitest run server/tests/unit/external-smoke.test.ts: 45 passed. 9 of the new tests fail against the oldcheck.ts, including the main case, "validates and resolves against the echoed release instead of the 3.0 pin".npm run test:external-smokeagainst the deployed public agent (read-only discovery, the same calls the daily job makes):Authenticated discovery and storyboard resolution passed./Anonymous discovery: auth-required.createTrainingAgentRouteron 127.0.0.1): it passes. The old check reproduces the exact CI failure against that local agent.npm run typecheck, plus an ad-hoctsc --noEmitoverscripts/external-smoke/*.tsand the test file, which the server tsconfig doesn't includenpm run test:unit: 1113 passednpm run test:server-unit -- --shard=N/3: 4612, 3311 (+31 skipped), and 4688 passedThe workflow runs the script from the checkout, so the next scheduled run after merge should pass without a deploy.
🤖 Generated with Claude Code