diff --git a/.changeset/align-submitted-branches.md b/.changeset/align-submitted-branches.md new file mode 100644 index 00000000000..86eeee56485 --- /dev/null +++ b/.changeset/align-submitted-branches.md @@ -0,0 +1,5 @@ +--- +"adcontextprotocol": patch +--- + +Align the inline `submitted` branches with their published async status files (adcp#8856). Eight tasks defined their submitted response twice, and the copies disagreed: the inline branch in `-response.json` rejected fields the published `-async-response-submitted.json` accepts, so the same response validated differently depending on which schema a validator used. The inline branches for `sync_creatives` (creatives, merges, warnings), `build_creative` (creative_manifest, creative_manifests, creatives, estimate), `control_media_buy` (media_buy_id, warnings), `create_media_buy` (media_buy_id, packages, warnings), `sync_catalogs` (catalogs, item_availability_states, item_availability_updates), and `update_media_buy` (media_buy_id, warnings) — plus the shared `media-buy-commitment-response.json` submitted branch behind `accept_proposal` and `buy_products` (media_buy_id, warnings) — no longer forbid those fields. Each fix is a recorded correction under DR-0036: the published status file already states the shape, and every value the inline branch accepted before still validates. To keep each response `oneOf` exclusive after that loosening, the success branches of `create_media_buy`, `update_media_buy` and `build_creative` also exclude a `core/task-submitted.json` body, so a submitted body carrying result fields matches the submitted branch only (the other tools' success branches already exclude it, by `task_id`/`status` or a fixed `status: "completed"`). The canonical warnings test (`tests/relationship-scoped-indicators.test.cjs`) follows the published files: its submitted-arm assertions now accept warnings on the submitted envelope (warnings stay excluded from error arms and from `sync_creatives`' success arm). No restructure: the bodies-only layout and generated unions stay in #8565 for 4.0. diff --git a/static/schemas/source/creative/sync-creatives-response.json b/static/schemas/source/creative/sync-creatives-response.json index c7a5027be80..24b6e5238fa 100644 --- a/static/schemas/source/creative/sync-creatives-response.json +++ b/static/schemas/source/creative/sync-creatives-response.json @@ -361,20 +361,7 @@ "$ref": "/schemas/core/ext.json" } }, - "additionalProperties": true, - "not": { - "anyOf": [ - { - "required": ["creatives"] - }, - { - "required": ["merges"] - }, - { - "required": ["warnings"] - } - ] - } + "additionalProperties": true } ], "properties": {} diff --git a/static/schemas/source/media-buy/build-creative-response.json b/static/schemas/source/media-buy/build-creative-response.json index 1a4769c3097..50ec9459d71 100644 --- a/static/schemas/source/media-buy/build-creative-response.json +++ b/static/schemas/source/media-buy/build-creative-response.json @@ -163,7 +163,10 @@ "required": [ "creative_manifest" ], - "additionalProperties": true + "additionalProperties": true, + "not": { + "$ref": "/schemas/core/task-submitted.json" + } }, { "title": "BuildCreativeMultiSuccess", @@ -308,7 +311,10 @@ "required": [ "creative_manifests" ], - "additionalProperties": true + "additionalProperties": true, + "not": { + "$ref": "/schemas/core/task-submitted.json" + } }, { "title": "BuildCreativeVariantSuccess", @@ -547,7 +553,10 @@ } } }, - "additionalProperties": true + "additionalProperties": true, + "not": { + "$ref": "/schemas/core/task-submitted.json" + } }, { "title": "BuildCreativeEstimate", @@ -613,7 +622,10 @@ "mode", "estimate" ], - "additionalProperties": true + "additionalProperties": true, + "not": { + "$ref": "/schemas/core/task-submitted.json" + } }, { "title": "BuildCreativeError", @@ -694,31 +706,7 @@ "$ref": "/schemas/core/ext.json" } }, - "additionalProperties": true, - "not": { - "anyOf": [ - { - "required": [ - "creative_manifest" - ] - }, - { - "required": [ - "creative_manifests" - ] - }, - { - "required": [ - "creatives" - ] - }, - { - "required": [ - "estimate" - ] - } - ] - } + "additionalProperties": true } ], "properties": {} diff --git a/static/schemas/source/media-buy/control-media-buy-response.json b/static/schemas/source/media-buy/control-media-buy-response.json index e3d6b5b973d..1d8afd98471 100644 --- a/static/schemas/source/media-buy/control-media-buy-response.json +++ b/static/schemas/source/media-buy/control-media-buy-response.json @@ -81,13 +81,7 @@ "ext": { "$ref": "/schemas/core/ext.json" } }, "required": ["status"], - "additionalProperties": true, - "not": { - "anyOf": [ - { "required": ["media_buy_id"] }, - { "required": ["warnings"] } - ] - } + "additionalProperties": true } ] } diff --git a/static/schemas/source/media-buy/create-media-buy-response.json b/static/schemas/source/media-buy/create-media-buy-response.json index 69c8efee2bb..16766aa660b 100644 --- a/static/schemas/source/media-buy/create-media-buy-response.json +++ b/static/schemas/source/media-buy/create-media-buy-response.json @@ -188,8 +188,15 @@ ], "additionalProperties": true, "not": { - "required": [ - "errors" + "anyOf": [ + { + "required": [ + "errors" + ] + }, + { + "$ref": "/schemas/core/task-submitted.json" + } ] } }, @@ -280,26 +287,7 @@ "$ref": "/schemas/core/ext.json" } }, - "additionalProperties": true, - "not": { - "anyOf": [ - { - "required": [ - "media_buy_id" - ] - }, - { - "required": [ - "packages" - ] - }, - { - "required": [ - "warnings" - ] - } - ] - } + "additionalProperties": true } ], "properties": {} diff --git a/static/schemas/source/media-buy/media-buy-commitment-response.json b/static/schemas/source/media-buy/media-buy-commitment-response.json index 0867bb2d594..1491de33a86 100644 --- a/static/schemas/source/media-buy/media-buy-commitment-response.json +++ b/static/schemas/source/media-buy/media-buy-commitment-response.json @@ -160,13 +160,7 @@ "ext": { "$ref": "/schemas/core/ext.json" } }, "required": ["status"], - "additionalProperties": true, - "not": { - "anyOf": [ - { "required": ["media_buy_id"] }, - { "required": ["warnings"] } - ] - } + "additionalProperties": true } ] } diff --git a/static/schemas/source/media-buy/sync-catalogs-response.json b/static/schemas/source/media-buy/sync-catalogs-response.json index ca47f32dd42..52d2af6875b 100644 --- a/static/schemas/source/media-buy/sync-catalogs-response.json +++ b/static/schemas/source/media-buy/sync-catalogs-response.json @@ -331,14 +331,7 @@ "$ref": "/schemas/core/ext.json" } }, - "additionalProperties": true, - "not": { - "anyOf": [ - { "required": ["catalogs"] }, - { "required": ["item_availability_updates"] }, - { "required": ["item_availability_states"] } - ] - } + "additionalProperties": true } ], "properties": {} diff --git a/static/schemas/source/media-buy/update-media-buy-response.json b/static/schemas/source/media-buy/update-media-buy-response.json index 4df311029de..cd5ee170635 100644 --- a/static/schemas/source/media-buy/update-media-buy-response.json +++ b/static/schemas/source/media-buy/update-media-buy-response.json @@ -139,8 +139,15 @@ ], "additionalProperties": true, "not": { - "required": [ - "errors" + "anyOf": [ + { + "required": [ + "errors" + ] + }, + { + "$ref": "/schemas/core/task-submitted.json" + } ] } }, @@ -225,17 +232,7 @@ "$ref": "/schemas/core/ext.json" } }, - "additionalProperties": true, - "not": { - "anyOf": [ - { - "required": ["media_buy_id"] - }, - { - "required": ["warnings"] - } - ] - } + "additionalProperties": true } ], "properties": {} diff --git a/tests/relationship-scoped-indicators.test.cjs b/tests/relationship-scoped-indicators.test.cjs index a0579cada9f..667e3918ca5 100644 --- a/tests/relationship-scoped-indicators.test.cjs +++ b/tests/relationship-scoped-indicators.test.cjs @@ -843,7 +843,7 @@ describe('relationship-scoped indicators', () => { assert.equal(validateGetMediaBuys(payload), false); }); - it('returns structured warnings only on completed media-buy success arms', () => { + it('returns structured warnings only on completed media-buy success arms and aligned submitted arms', () => { const warning = { code: 'inventory_shortfall_forecast', message: 'Forecast delivery is below the requested goal.', @@ -968,11 +968,15 @@ describe('relationship-scoped indicators', () => { assertValid(validateCreateResponse, submitted); assertValid(validateUpdateResponse, submitted); assertValid(validateSyncResponse, submitted); - assert.equal(validateCreateResponse({ ...submitted, warnings: [warning] }), false); - assert.equal(validateUpdateResponse({ ...submitted, warnings: [warning] }), false); - assert.equal(validateCommitmentResponse({ ...submitted, warnings: [warning] }), false); - assert.equal(validateControlResponse({ ...submitted, warnings: [warning] }), false); - assert.equal(validateSyncResponse({ ...submitted, warnings: [warning] }), false); + // #8856 (DR-0036 correction): the published *-async-response-submitted.json + // files accept warnings on the submitted envelope, so the aligned inline + // submitted branches accept them too. Warnings stay excluded from the + // error arms above and from sync_creatives' success arm. + assertValid(validateCreateResponse, { ...submitted, warnings: [warning] }); + assertValid(validateUpdateResponse, { ...submitted, warnings: [warning] }); + assertValid(validateCommitmentResponse, { ...submitted, warnings: [warning] }); + assertValid(validateControlResponse, { ...submitted, warnings: [warning] }); + assertValid(validateSyncResponse, { ...submitted, warnings: [warning] }); }); it('defines account-level invalidation webhooks for indicators and assignments', () => {