Skip to content

fix(adcp,adcp/v3): align CreativeResult with sync-creatives-response schema - #545

Open
sujanchalla0510 wants to merge 4 commits into
adcontextprotocol:mainfrom
sujanchalla0510:fix-365-creative-result-spec-fields
Open

sujanchalla0510 wants to merge 4 commits into
adcontextprotocol:mainfrom
sujanchalla0510:fix-365-creative-result-spec-fields

Conversation

@sujanchalla0510

@sujanchalla0510 sujanchalla0510 commented Sep 26, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #365.

CreativeResult drifted from static/schemas/source/creative/sync-creatives-response.json: it was missing the 8 spec-defined fields (account, assigned_to, assignment_errors, changes, expires_at, platform_id, preview_url, warnings) and defined rejection_reason, which exists nowhere in the spec.

Changes (current head 8aa637d; description refreshed 2026-10-16 per @torbenbrodt's review):

How tested: go build ./..., go vet ./..., and go test ./... in both the adcp and adcp/v3 modules — all pass. JSON round-trip tests (adcp/creative_result_test.go, adcp/v3/creative_result_test.go) cover the new wire fields and backward compat of the deprecated field, including a whole-JSON localization round-trip test in v3. @torbenbrodt additionally verified 8aa637d merged onto main (188cdcf): generator tests, regeneration with no diff, lint.py --strict and the any-coverage gate in both modules, and go vet + go test -race for root, adcp, adcp/v3 and the reference agents.

Follow-ups: #546 (the Errors / assignment_errors re-type), #567 (CreativeInput revision_id + localization, v3 only — the 3.1.9 schemas carry neither field).

…schema

Adds the 8 spec-defined fields missing from CreativeResult (account,
assigned_to, assignment_errors, changes, expires_at, platform_id,
preview_url, warnings), deprecates the non-spec rejection_reason, and
adds revision_id in adcp/v3 (pinned bundle is 3.2.0-rc.3).

Fixes adcontextprotocol#365.
Comment thread adcp/types.go Outdated
Status string `json:"status,omitempty"`
PlatformID string `json:"platform_id,omitempty"`
Changes []string `json:"changes,omitempty"`
Errors []string `json:"errors,omitempty"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium: Errors []string is still off-shape for the schema this PR claims to align to. Across the generated types every response errors[] is []AdcpError (AdcpError = map[string]any) — including the sibling sync task SyncGovernanceAccountResult.Errors []AdcpError (adcp/v3/types_gen.go:11154), and per-item errors carry error-code.json code/message objects. A real failed-creative payload "errors":[{"code":"invalid_format","message":"..."}] will fail json.Unmarshal (cannot unmarshal object into string), taking down the entire sync-creatives response parse on the failure path.

The PR description notes re-typing is breaking and deferred per triage — fair, and the fix needs a fix!/major marker + human sign-off, so it doesn't belong in this additive PR. But the "align CreativeResult with the schema" claim leaves the failure path unaligned, and the round-trip test only exercises "errors": [], so nothing here catches it. Worth a follow-up issue with a populated-errors payload pinning the decision.

Comment thread adcp/v3/types.go Outdated
Status string `json:"status,omitempty"`
PlatformID string `json:"platform_id,omitempty"`
Changes []string `json:"changes,omitempty"`
Errors []string `json:"errors,omitempty"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium: Same errors shape gap as the adcp module. In v3 the AdcpError-object convention is even more load-bearing: AdcpError = map[string]any (adcp/v3/types_gen.go:13) and every generated response types errors as []AdcpError, e.g. sibling SyncGovernanceAccountResult.Errors []AdcpError (:11154). []string here will fail to unmarshal a real failed-creative payload with structured {code,message} error objects, breaking the sync-creatives failure path.

Deferring the re-type is defensible (breaking; needs fix!/major + human sign-off), but flag it as a known remaining drift rather than folding it under "aligned." The round-trip test uses "errors": [] and never exercises the object case.

aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Sep 27, 2026

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Approve

Approve — clean, additive fix closing the CreativeResult drift in #365.

What I checked:

  • Adds the 8 missing spec fields (plus revision_id in v3) to the hand-written CreativeResult struct, deprecates rather than removes RejectionReason (no exported-symbol removal → no breaking-change/conventional-commit trigger).
  • Schema↔generated-types coherence rule structurally satisfied: CreativeResult is the sanctioned hand-written escape hatch (listed in KNOWN_TYPES/EXEMPT), so edits in adcp/types.go are within the supported escape hatch — no adcp/types_gen.go hand-edit, no adcp/schemas change without regen.
  • No TMP signing, identity-agent TEE, or protocol-managed-skill paths touched.
  • Round-trip tests shipped for both call sites; keyed literals used; testify already declared.

Decision path: no critical/high/medium findings (row 1/4/5 do not fire). gated_paths is false (row 2 n/a). high_risk is true but the only match, adcp/types.go, is (modified) with zero medium-or-higher findings — per the high_risk guidance a modification with no medium concern is presumed safe, and row 5 requires a medium finding to escalate. No no-auto-approve team match (row 7 n/a). Fewer than three medium findings (row 8 n/a). Falls through to row 9 → approve.

Non-blocking notes from the reviewer: field-shape fidelity could not be independently verified (no network access to upstream schemas); Errors remains []string per the #365 triage.

@sujanchalla0510

Copy link
Copy Markdown
Collaborator Author

Thanks for the careful review — the Errors []string vs []AdcpError drift is real, and it genuinely lives outside this PR's scope (breaking re-type needs a fix!/major marker + maintainer sign-off).

I've opened a follow-up issue pinning the decision: #546 — it documents the unmarshal failure path ({"errors":[{"code":"...","message":"..."}]} failing to parse on the sync-creatives failure path) and proposes the breaking re-type plus a populated-errors round-trip test. Leaving #545 additive as recommended.

@torbenbrodt torbenbrodt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, @sujanchalla0510. The eight fields from #365 and revision_id are typed correctly against the bundle main pins now (3.2.2), and creative_id/action stay required. I merged the branch onto current main locally: it merges cleanly, regeneration produces no diff, and lint.py --strict, the generator's Python tests, go vet and go test pass in both modules. Four additive things I'd suggest before merge, none of them breaking:

  1. localization and macro_resolution_results can go in now, and v3 drops them on decode until they do. Since #555, main generates MacroResolutionResult, and CreativeCapabilities.Localization in adcp/v3/types.go already holds a localization object as any. So this is two lines:

    Localization           any                     `json:"localization,omitempty"`
    MacroResolutionResults []MacroResolutionResult `json:"macro_resolution_results,omitempty"`

    The schema makes localization "Required for every accepted creative whose request included a non-null localization object". This item validates against 3.2.2:

    {"creative_id":"summer_image_localized","action":"created","status":"pending_review","localization":{"default_locale_variant_id":"loc_en_us","unmatched_locale_action":"do_not_serve","locale_matching":"rfc4647_lookup","variants":[{"locale_variant_id":"loc_en_us","locale":"en-US","role":"source","assets":{"image":{"asset_type":"image","url":"https://cdn.example.com/summer-en.jpg","width":1080,"height":1080}}}]}}

    Unmarshalled into this PR's CreativeResult and marshalled back, it comes out as {"creative_id":"summer_image_localized","action":"created","status":"pending_review"}. With the two fields added, it round-trips unchanged.

  2. Pair CreativeResult with its schema in lint so it can't drift silently again (the triage on #365 asked for it to leave EXEMPT). Add 'CreativeResult': 'creative/sync-creatives-response.json#/oneOf/0/properties/creatives/items' to HAND_WRITTEN_SCHEMA_SPECS and remove it from EXEMPT in lint.py. On main, that check reports exactly the fields #365 listed (plus revision_id, localization, macro_resolution_results). On this branch it reports only localization, macro_resolution_results and the extra rejection_reason. After (1), only the deprecated field is left, so lint needs a small allowance for it. The same pairing in adcp/schemas (v1) reports only rejection_reason.

  3. Tests: use a schema-valid fixture and compare the whole JSON. "status": "active" isn't a CreativeStatus (processing, pending_review, approved, suspended, rejected, archived), so both fixtures fail validation against the schema. With approved they pass. The re-encode step checks only that keys are present, and its list leaves out errors, which the round trip drops ("errors": [] in, absent out). An equality check on decode-then-encode, plus an action: "failed" item with a structured error, would pin #546.

  4. Reword the deprecation comment. "Per-item failure detail belongs in Errors" currently leads to invalid output: Errors: []string{"Video duration 31s exceeds the 30s maximum"} encodes as "errors":["Video duration 31s exceeds the 30s maximum"], which fails the schema because the items are core/error.json objects. rejection_reason on its own still validates, because the items allow additional properties. Until #546 lands, something like: "Deprecated: not part of the AdCP schema. Failure detail belongs in errors[] as core/error.json objects; see #546." On #546's point 3: warnings items are type: string, so Warnings []string is already right.

Smaller:

  • The v3 test comment says the package pins 3.2.0-rc.3; main moved to 3.2.2 in #553. The 15-property count still holds.
  • assignment_errors allows non-string values for keys outside ^[a-zA-Z0-9_-]+$ (additionalProperties: true). So {"pkg.std":{"code":"PACKAGE_NOT_FOUND"}} is schema-valid, but it fails to decode into map[string]string.
  • Outside this PR: CreativeInput carries no revision_id or localization, so a seller using the typed SyncCreatives hook can't see what it has to echo back.

For context, #564 proposes a CI check that round-trips schema examples through the Go types. As it stands it wouldn't reach CreativeResult, because sync-creatives-response.json has no examples and the type is hand-written, so here the lint pairing in (2) is the guard.

Disclosure: we're building a creative agent and a seller on adcp/v3, so sync_creatives results are what our buyers will read.

- v3 CreativeResult gains Localization (any, as CreativeCapabilities holds it) and MacroResolutionResults []MacroResolutionResult (generated on main since adcontextprotocol#555); localized items now round-trip instead of dropping both fields
- Pair CreativeResult with creative/sync-creatives-response.json#/oneOf/0/properties/creatives/items in HAND_WRITTEN_SCHEMA_SPECS (both modules), remove it from EXEMPT in lint.py, and add ALLOWED_EXTRA_FIELDS so the deprecated rejection_reason is a documented allowance, not drift
- Tests: fixtures use a valid CreativeStatus (approved, not active); new whole-JSON round-trip test for a localized creative result; stale 3.2.0-rc.3 pin comment dropped
- Deprecation comment reworded in both modules: failure detail belongs in errors[] as core/error.json objects; see adcontextprotocol#546
@sujanchalla0510

Copy link
Copy Markdown
Collaborator Author

Thanks for the detailed review, @torbenbrodt — addressed in b9829f3:

  1. Fields added (v3): Localization any and MacroResolutionResults []MacroResolutionResult on CreativeResult, exactly as you suggested. Your localized payload now round-trips unchanged — pinned by a new whole-JSON equality test (TestCreativeResultLocalizationRoundTrip). One caveat: this branch predates feat(adcp/v3): generate validate_input request, response and result types #555, so MacroResolutionResult only exists on main; I verified locally by compiling/testing this branch's changes against main's generated type (full v3 suite green, macro payload round-trips), but the branch itself needs a main update before the typed field compiles standalone.
  2. Lint pairing: CreativeResult added to HAND_WRITTEN_SCHEMA_SPECS in both modules' generate.py with the sync-creatives-response.json#/oneOf/0/... pointer, removed from EXEMPT in both lint.py files, and a new ALLOWED_EXTRA_FIELDS table in lint.py documents rejection_reason as the one deliberate extra (deprecated, removal is breaking) instead of drift. (lint.py skips locally without the downloaded bundle; its unit tests show the same bundle-dependent baseline before and after this change.)
  3. Tests: both fixtures now use approved (a real CreativeStatus) instead of active for the item status. The action: \"failed\" item with a structured error I have not added: with Errors []string it cannot be expressed without encoding the schema-invalid shape — that test belongs with Follow-up: CreativeResult.Errors []string vs []AdcpError drift (breaking re-type deferred from #545) #546's re-type to []AdcpError, which was previously deferred on this PR as a breaking change. The stale 'pins 3.2.0-rc.3' comment is dropped.
  4. Deprecation comment: reworded in both modules to your suggested text ('Deprecated: not part of the AdCP schema. Failure detail belongs in errors[] as core/error.json objects; see Follow-up: CreativeResult.Errors []string vs []AdcpError drift (breaking re-type deferred from #545) #546.'), and noted there that Warnings []string is already correct.

Not touched, as you flagged them: the assignment_errors non-string-values decode gap and CreativeInput carrying no revision_id/localization — happy to open follow-ups for both if you want them tracked.

Comment thread adcp/v3/types.go Outdated
Comment on lines +1269 to +1271
// The two deeply-nested 3.2 additions (localization and
// macro_resolution_results) are intentionally excluded here; their object
// graphs belong in the generated types.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(non-blocking) Comment contradicts the code directly below it. It says localization and macro_resolution_results "are intentionally excluded here," but this same revision adds both as fields — Localization any and MacroResolutionResults []MacroResolutionResult. What's actually true is their object graphs aren't hand-expanded (localization is any, macro uses the generated type). Reword to say the fields are present but kept shallow, not excluded.

aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Oct 15, 2026

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Approve

Approve — schema↔generated-types coherence and wire-shape fidelity verified; no blocking findings.

What I checked

  • Pairs CreativeResult to creative/sync-creatives-response.json#/oneOf/0/properties/creatives/items in both the root and v3 modules, removes it from EXEMPT, and adds a scoped ALLOWED_EXTRA_FIELDS allowance for the deprecated rejection_reason.
  • Struct changes are additive (all omitempty, no wire break) — no breaking-change / conventional-commit marker required.
  • CI Build & Test (1.27) and Lint pass at HEAD, confirming the schema-pairing lint matches and python3 adcp/schemas/lint.py --strict would not surface drift.
  • Round-trip tests added; localization round-trips whole-document in the test.
  • high_risk: true but reasons are (modified) on adcp/schemas/** and adcp/types.go with no medium-or-higher finding — presumed safe per the high-risk reading rules.

Decision path: No critical/high findings (row 1 n/a); gated_paths: false (row 2 n/a); no (deleted) reasons (row 3 n/a); no medium findings (rows 4/5/8 n/a); prior decision was approve (row 6 n/a); no no-auto-approve team match (row 7 n/a). Falls through to row 9 → approve.

Medium findings: none.

Nits (non-blocking):

  • adcp/v3/types.go:1269 — v3 CreativeResult doc comment claims localization/macro_resolution_results are "intentionally excluded" while the same revision adds both fields. Worth a one-line doc fix.

@torbenbrodt

Copy link
Copy Markdown
Collaborator

Thanks, @sujanchalla0510. I checked b9829f3 merged onto current main: both modules regenerate with no diff and pass lint.py --strict, the generator tests, go vet and go test. The CreativeResult pairing is live in both modules, and ALLOWED_EXTRA_FIELDS only exempts CreativeResult.rejection_reason: emptying it makes lint report rejection_reason, and deleting MacroResolutionResults makes it report macro_resolution_results. The new fixtures validate against their pinned schemas, and a localized item with an es-MX target and a macro result now round-trips unchanged.

Two small things left:

Agreed, the failed-item structured-error test belongs with #546. On the follow-ups: yes please to an issue for CreativeInput missing revision_id and localization. That change is additive, and without it a seller on the typed SyncCreatives hook can't echo either field. For assignment_errors, I'd add it to #546 rather than open a new issue: any fix changes a public field's type, so it belongs in the same breaking-change decision.

aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Oct 16, 2026

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Approve

Approve.

This pass is a delta of one file / 16 lines: a doc-comment correction in adcp/v3/types.go. The prior comment claimed localization and macro_resolution_results were "intentionally excluded," but the struct now carries both (Localization as any, MacroResolutionResults as the generated MacroResolutionResult type). The stale comment was updated to match the struct — no behavior or wire-shape change.

Checks:

  • No critical/high findings (schema↔generated-type coherence, TMP signing, TEE boundary, protocol skills, breaking-wire-change markers all unaffected — this is comment-only).
  • No medium findings.
  • high_risk is true (modified files under adcp/schemas/** and adcp/types.go), but the reviewer surfaced no medium-or-higher concerns on those modifications, so the flag alone does not escalate (no deletions, no medium on modified files).
  • gated_paths is false; no no-auto-approve team match.
  • Prior decision was approve with no findings; this remains clean.

Decision table: rows 1–8 do not fire → row 9 approve.

@sujanchalla0510

Copy link
Copy Markdown
Collaborator Author

Thanks @torbenbrodt — the two small things are done:

torbenbrodt
torbenbrodt previously approved these changes Oct 16, 2026

@torbenbrodt torbenbrodt left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the code. Merged onto today's main (188cdcf), CI's core checks pass locally: generator tests, regeneration with no diff, lint.py --strict and the any-coverage gate in both modules, and go vet with go test -race for root, adcp, adcp/v3 and the reference agents. #546 tracks the Errors and assignment_errors re-type.

Not tracked yet:

  • The description still says adcp/v3 pins 3.2.0-rc.3 (main pins 3.2.2), that v3 excludes localization and macro_resolution_results, and that it covers 13 of 15 fields. Please refresh it, since the squash body is built from it.
  • The main round-trip tests check that each wire key is present after re-encoding, not that its value survives.
  • ALLOWED_EXTRA_FIELDS has no check for stale entries, so rejection_reason stays allowed after the field is removed.
  • #567 should cover adcp/v3 only: the adcp module's 3.1.9 schemas have neither revision_id nor localization.

@torbenbrodt

Copy link
Copy Markdown
Collaborator

@bokelley, one question before this merges. My approval covers the code, not the decisions #365's triage left to you:

  • deprecating RejectionReason in place, which this PR does, rather than a semver bump;
  • the doc-comment contract for account, assigned_to, platform_id and preview_url, which the triage's security reviewer asked a human to confirm before they were added.

Are you happy with both as they stand here?

@sujanchalla0510

Copy link
Copy Markdown
Collaborator Author

Thanks @torbenbrodt — approving review actioned, including the 'not tracked yet' list:

Your two questions for @bokelley (deprecating RejectionReason in place vs a semver bump, and the doc-comment contract for account / assigned_to / platform_id / preview_url) are his calls — leaving them with him.

Copy link
Copy Markdown
Contributor

@torbenbrodt @sujanchalla0510 — maintainer decisions, posted by Brian's coding agent at his direction:

  • Deprecate RejectionReason in place. Keep the exported field for compatibility; its eventual removal belongs in a breaking release. Keep the Errors and assignment_errors type corrections in Follow-up: CreativeResult.Errors []string vs []AdcpError drift (breaking re-type deferred from #545) #546, and leave Warnings []string as it is.
  • The additive account, assigned_to, platform_id, and preview_url fields are approved, subject to adding the requested field-level documentation before merge. The current head has the fields but lacks those comments. Describe account as the owning account, assigned_to as successfully assigned package IDs, and platform_id as the seller's creative identifier. These are account/resource metadata, not containers for end-user identifiers. Document preview_url as a preview link that may carry sensitive access tokens and should be handled accordingly; do not promise that URLs are token-free. Callers must be authorized for the account and resources returned.

The decisions above resolve the maintainer questions; adding the missing comments is the remaining action on this PR. This does not approve the breaking changes tracked by #546.

Copy link
Copy Markdown
Contributor

@torbenbrodt — Brian has explicitly authorized implementing the SDK delegation. The guidance is now proposed in #582, in AGENTS.md with a contributor-facing README link.

It is prospective: a complete PR notice starts a fresh five-calendar-day window, states the proposed answer and UTC deadline, and records the head SHA. A hold pauses the clock until explicitly released; material changes restart it. The author records the question and outcome in a tracked issue before merging. All six constitutional escalation categories, required reviews/checks, and blocking findings remain in force. It takes effect when #582 is merged, and does not clear the explicit security hold on #554.

Posted by Brian's coding agent at his direction.

…orm_id/preview_url

Maintainer decision on adcontextprotocol#545 (bokelley, 2026-10-19): the additive
fields are approved subject to adding the requested field-level
documentation before merge. Adds doc comments in both modules:
account as the owning account; assigned_to as successfully assigned
package IDs; platform_id as the seller's creative identifier; the
three are account/resource metadata, not containers for end-user
identifiers; preview_url as a preview link that may carry sensitive
access tokens (do not promise token-free URLs); callers must be
authorized for the account and resources returned. Comment-only.

Signed-off-by: sujan kumar reddy challa <sujanchalla0510@gmail.com>
@sujanchalla0510

Copy link
Copy Markdown
Collaborator Author

Thanks @bokelley — both decisions actioned in 7a58d26 (comment-only):

  • Field documentation added in both modules (adcp/types.go, adcp/v3/types.go): account as the owning account; assigned_to as successfully assigned package IDs; platform_id as the seller's creative identifier; the three documented as account/resource metadata, not containers for end-user identifiers; preview_url as a preview link that may carry sensitive access tokens and should be handled accordingly (no token-free promise); callers must be authorized for the account and resources returned.
  • RejectionReason: stays deprecated in place, as decided — no change needed; the Errors/assignment_errors type corrections remain in Follow-up: CreativeResult.Errors []string vs []AdcpError drift (breaking re-type deferred from #545) #546 and Warnings []string is unchanged.

Local: adcp module tests pass; adcp/v3 suite passes against main's generated MacroResolutionResult overlay (the branch predates #555 standalone, same as before — CI builds the merge commit). CI re-running on the new head.

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Approve

Approve — documentation-only delta since prior approve (8aa637d), no new findings.

Checked:

  • Delta since prior approve is doc-comment-only on CreativeResult in adcp/types.go and adcp/v3/types.go. Comments verified accurate (account/resource metadata, PlatformID = seller creative id, PreviewURL token caveat, AssignedTo = package IDs).
  • No semantic, wire-shape, type, or schema/lint-pairing changes in the delta — schema↔generated-type coherence preserved.
  • No breaking exported-symbol changes, so no conventional-commit marker required.
  • high_risk is true only via (modified) entries, but the reviewer surfaced no medium-or-higher concerns, so modifications are presumed safe per the high-risk reasoning rules.

Decision table: no critical/high findings (rows 1 skip), gated_paths false (row 2 skip), no deletions (row 3 skip), no medium findings (rows 4/5/8 skip), prior decision was approve (row 6 skip), no no-auto-approve team match (row 7 skip). Falls through to row 9 → approve.

@torbenbrodt torbenbrodt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approving at 7a58d26: the commit adds only the field documentation Brian asked for (no field or tag changes), so his decisions on this PR are met.

torbenbrodt added a commit that referenced this pull request Oct 22, 2026
* test(adcp/v3): validate wire fixtures against their JSON schema

Add assertSchemaValid, which validates a test fixture against a schema
(or a JSON Pointer into one) in the downloaded bundle with the existing
github.com/google/jsonschema-go dependency. Every $ref resolves from
adcp/v3/schemas by its $id; nothing is fetched.

Go's RE2 cannot compile 8 distinct bundle patterns (lookarounds and
\uXXXX escapes, at 23 locations in 11 files), and Resolve fails on any
schema that reaches one. re2Translations lists each location with an
exact RE2 equivalent, so no pattern and no schema is skipped.
TestRE2TranslationsMatchBundle fails on a new uncompilable pattern, a
stale location, or an original that compiles now.

The helper rejects the first-head fixtures of #545 (status "active")
and #581 (localization in the readback shape), and accepts all 334
top-level examples in the bundle's 113 source schemas that have any.

Refs #564

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(adcp/v3): run wire fixtures through assertSchemaValid

Validate the request and response fixtures in the adcp/v3 tests, and the
encodings of the response and pricing round-trip tests, against their
schemas. Nine were invalid and are corrected. No correction weakens an
assertion; the reach_unit one changes the expected value from the typo
to the enum value:

- create_media_buy: idempotency_key missing (the broadcast storyboard
  fixture, whose storyboard step generates one) or shorter than its
  16-character minimum
- check_governance with verdict conditions: the encoded response lacked
  expires_at; the two decoded fixtures lacked plan_id, expires_at and
  explanation
- get_plan_audit_logs, get_media_buy_delivery and get_adcp_capabilities
  responses: status missing (the two encoded ones sent "status":"")
- optimization goal: reach_unit "household" is not in enums/reach-unit;
  the value is "households". The same typo in the marshal table of
  TestGeneratedCoreRefsAcrossSurfacesMarshalTypedFields is corrected too.

AGENTS.md says when a fixture goes through the helper.

Refs #564

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(adcp/v3): pin RE2 translations with probes; fix #581 SHA

Add probes to three re2Translations entries so a mutation of each now
fails TestRE2Translations*: P1M2D (match) and PY (no match) on the first
ISO duration, P0Y1D (match) on the non-zero duration, and a U+FEFF
inside a macro-bearing URL (no match). Each probe agrees with the
original ECMA-262 pattern in V8.

#581's first head is 7643ff1, not dd5a97a; fix the comment in
TestAssertSchemaValidRejectsKnownBadFixtures. Fix the wrap of the
walkSchemaPatterns doc comment.

Refs #564

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <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.

CreativeResult struct missing 8 spec fields, defines 1 not in spec

3 participants