Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/sdk-shim-ledger.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"status": "temporary",
"owner": "training-agent",
"upstream": "adcontextprotocol/adcp-client#2495, adcontextprotocol/adcp-client#2527",
"problem": "The rc.17 storyboard task map forces get_products onto a legacy-only wire, and scoped transports discover capabilities without carrying them into request adaptation. The latter makes 3.1 sellers look pre-3.1 and strips filters.pricing_currencies.",
"problem": "The rc.18 storyboard task map forces get_products onto a legacy-only wire, and scoped transports discover capabilities without carrying them into request adaptation. The latter makes 3.1 sellers look pre-3.1 and strips filters.pricing_currencies.",
"localBehavior": "Patch both compiled SDK module formats after installation so the storyboard runner leaves get_products wire selection unspecified and request-local capabilities drive version adaptation without cross-tenant caching.",
"removalCondition": "Remove the patch script, Docker invocations, and ledger entry after an SDK release fixes storyboard get_products routing and carries scoped capabilities into request adaptation, and both current and released-3.0 storyboard matrices pass without the patch.",
"paths": [
Expand Down
5 changes: 5 additions & 0 deletions .changeset/fix-input-schema-strip-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"adcontextprotocol": patch
---

Correct the `input_schema_field_stripped` compliance notice so it identifies request payload drift without blaming agents for omitting fields that are not part of the canonical task schema, and consume the SDK release that keeps broad `list_accounts` discovery requests unscoped.
6 changes: 3 additions & 3 deletions docs/building/verification/validate-your-agent.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,16 @@ Add `--json` for structured output.

### Select a compliance cache and test kit

`--compliance-version` selects a cache bundled with the SDK. For an extracted cache, pass its versioned directory to `--compliance-dir`; `--test-kit` takes a YAML file from the `test-kits/` directory below that same cache root. After extracting the `@adcp/sdk` 13.0.0-rc.17 npm tarball in the current directory, use its versioned cache root like this:
`--compliance-version` selects a cache bundled with the SDK. For an extracted cache, pass its versioned directory to `--compliance-dir`; `--test-kit` takes a YAML file from the `test-kits/` directory below that same cache root. After extracting the `@adcp/sdk` 13.0.0-rc.18 npm tarball in the current directory, use its versioned cache root like this:

```bash
npx @adcp/sdk@13.0.0-rc.17 storyboard run my-agent \
npx @adcp/sdk@13.0.0-rc.18 storyboard run my-agent \
--compliance-dir ./package/compliance/cache/3.1.13 \
--test-kit ./package/compliance/cache/3.1.13/test-kits/acme-outdoor.yaml
```

<Note>
`@adcp/sdk` 13.0.0-rc.17 infers the compliance line from test-kit metadata and rejects mixed or ambiguous `--test-kit`, `--compliance-version`, and `--compliance-dir` selections before contacting the agent. Keep the test kit and storyboard files under the same versioned cache root.
`@adcp/sdk` 13.0.0-rc.18 infers the compliance line from test-kit metadata and rejects mixed or ambiguous `--test-kit`, `--compliance-version`, and `--compliance-dir` selections before contacting the agent. Keep the test kit and storyboard files under the same versioned cache root.
</Note>

The storyboard runner operates in two modes depending on whether your agent implements the optional [compliance test controller](/docs/building/by-layer/L3/comply-test-controller):
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
"docs:json-field-audit": "node scripts/docs-json-field-audit.cjs"
},
"dependencies": {
"@adcp/sdk": "13.0.0-rc.17",
"@adcp/sdk": "13.0.0-rc.18",
"@anthropic-ai/sdk": "^0.115.0",
"@asteasolutions/zod-to-openapi": "^8.5.0",
"@contentauth/c2pa-node": "^0.8.3",
Expand Down
2 changes: 1 addition & 1 deletion scripts/patch-sdk-rc15.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import path from 'node:path';
// This temporary patch remains version-locked even though its filename dates
// from the release where it was introduced. Remove it when the upstream
// get_products routing and scoped capability propagation fixes ship.
const EXPECTED_VERSION = '13.0.0-rc.17';
const EXPECTED_VERSION = '13.0.0-rc.18';
const packageJson = JSON.parse(fs.readFileSync(path.resolve('node_modules/@adcp/sdk/package.json'), 'utf8'));

if (packageJson.version !== EXPECTED_VERSION) {
Expand Down
15 changes: 7 additions & 8 deletions static/compliance/source/universal/runner-output-contract.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# --- Schema definition ---

id: runner_output_contract
version: "2.9.0"
version: "2.9.1"
title: "Runner output contract"
summary: "Required failure-detail shape that AdCP storyboard runners MUST emit so implementors can self-diagnose validation failures."

Expand Down Expand Up @@ -1232,14 +1232,13 @@ notice:
receivers SHOULD migrate to RFC 9421 signatures only.
input_schema_field_stripped:
severity: info
spec_source: creative/list-creative-formats-request.json
message_template: |
Runner stripped spec-defined request field(s) {stripped_fields}
from {task} because the agent's MCP inputSchema does not declare
them. The step's validations may pass vacuously if the stripped
field was material to the scenario's intent. Agents should
declare all spec-defined fields they support in their
inputSchema.
Runner stripped request field(s) {stripped_fields} from {task}
because neither the agent's MCP inputSchema nor the canonical
AdCP request schema for the negotiated version declares them.
The step's validations may pass vacuously if a stripped field was
material to the scenario's intent. Check the caller or runner
payload and version adaptation before changing the agent schema.
capabilities_response_schema_invalid:
severity: info
spec_source: protocol/get-adcp-capabilities-response.json
Expand Down
23 changes: 23 additions & 0 deletions tests/lint-storyboard-check-enum.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const os = require('node:os');
const path = require('node:path');
const test = require('node:test');
const assert = require('node:assert/strict');
const yaml = require('js-yaml');

const {
lint,
Expand Down Expand Up @@ -51,6 +52,28 @@ test('authored_check_kinds enum loads from runner-output-contract.yaml', () => {
}
});

test('field-strip notice attributes noncanonical fields to the request payload', () => {
const contractPath = path.join(
__dirname,
'..',
'static',
'compliance',
'source',
'universal',
'runner-output-contract.yaml',
);
const contract = yaml.load(fs.readFileSync(contractPath, 'utf8'));
const notice = contract.notice.canonical_codes.input_schema_field_stripped;

assert.equal(contract.version, '2.9.1');
assert.equal(notice.severity, 'info');
assert.equal('spec_source' in notice, false, 'the notice is task-neutral and must not cite one creative schema');
assert.match(notice.message_template, /neither the agent's MCP inputSchema nor the canonical/);
assert.match(notice.message_template, /Check the caller or runner\s+payload/);
assert.doesNotMatch(notice.message_template, /spec-defined/);
assert.doesNotMatch(notice.message_template, /Agents should declare/);
});

function withTempStoryboardDir(name, doc, fn) {
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'check-enum-lint-'));
const file = path.join(tmp, name);
Expand Down
16 changes: 8 additions & 8 deletions tests/patch-sdk-rc15.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class SingleAgentClient {
module.exports = { SingleAgentClient };
`;

function writeFixture(version = '13.0.0-rc.17') {
function writeFixture(version = '13.0.0-rc.18') {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'sdk-rc15-patch-'));
const sdkRoot = path.join(root, 'node_modules', '@adcp', 'sdk');
fs.mkdirSync(sdkRoot, { recursive: true });
Expand Down Expand Up @@ -134,11 +134,11 @@ test('hosted SDK patch fixes get_products routing in CJS and ESM idempotently',
});

test('hosted SDK patch refuses an unreviewed SDK version before modifying artifacts', (t) => {
const root = writeFixture('13.0.0-rc.18');
const root = writeFixture('13.0.0-rc.19');
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
const result = runPatcher(root);
assert.notEqual(result.status, 0);
assert.match(result.stderr, /Refusing to patch @adcp\/sdk 13\.0\.0-rc\.18/);
assert.match(result.stderr, /Refusing to patch @adcp\/sdk 13\.0\.0-rc\.19/);
});

test('hosted SDK patch rejects an unexpected task-map source shape', (t) => {
Expand All @@ -155,7 +155,7 @@ test('hosted SDK patch rejects an unexpected task-map source shape', (t) => {

const result = runPatcher(root);
assert.notEqual(result.status, 0);
assert.match(result.stderr, /Unexpected 13\.0\.0-rc\.17 SDK shape/);
assert.match(result.stderr, /Unexpected 13\.0\.0-rc\.18 SDK shape/);
});

test('hosted SDK patch rejects mixed original and patched call sites before writing either format', (t) => {
Expand All @@ -170,7 +170,7 @@ test('hosted SDK patch rejects mixed original and patched call sites before writ

const result = runPatcher(root);
assert.notEqual(result.status, 0);
assert.match(result.stderr, /Unexpected 13\.0\.0-rc\.17 SDK shape/);
assert.match(result.stderr, /Unexpected 13\.0\.0-rc\.18 SDK shape/);
assert.equal(fs.readFileSync(cjsFile, 'utf8'), cjsBefore);
});

Expand All @@ -185,7 +185,7 @@ test('hosted SDK patch rejects duplicate original call sites before writing eith

const result = runPatcher(root);
assert.notEqual(result.status, 0);
assert.match(result.stderr, /Unexpected 13\.0\.0-rc\.17 SDK shape/);
assert.match(result.stderr, /Unexpected 13\.0\.0-rc\.18 SDK shape/);
assert.equal(fs.readFileSync(cjsFile, 'utf8'), cjsBefore);
});

Expand All @@ -205,7 +205,7 @@ test('hosted SDK patch preflights both module formats before writing either one'

const result = runPatcher(root);
assert.notEqual(result.status, 0);
assert.match(result.stderr, /Unexpected 13\.0\.0-rc\.17 SDK shape/);
assert.match(result.stderr, /Unexpected 13\.0\.0-rc\.18 SDK shape/);
assert.equal(fs.readFileSync(cjsFile, 'utf8'), cjsBefore);
});

Expand All @@ -225,7 +225,7 @@ test('hosted SDK patch preflights core clients before writing any artifact', (t)

const result = runPatcher(root);
assert.notEqual(result.status, 0);
assert.match(result.stderr, /Unexpected 13\.0\.0-rc\.17 SDK shape/);
assert.match(result.stderr, /Unexpected 13\.0\.0-rc\.18 SDK shape/);
assert.equal(fs.readFileSync(taskMapFile, 'utf8'), taskMapBefore);
});

Expand Down
Loading