Skip to content

spec(reporting): report definitions at contract_version 1.2 require a package_id dimension (#8971) - #8983

Merged
bokelley merged 1 commit into
mainfrom
spec/8971-report-definition-package-id
Nov 13, 2026
Merged

bokelley merged 1 commit into
mainfrom
spec/8971-report-definition-package-id

Conversation

@bokelley

@bokelley bokelley commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Closes #8971. Thanks to Emma (EmmaLouise2018) for the report and the precise problem statement.

Summary

Reliable Reporting (media_buy.reporting_delivery) is experimental. This adds report-definition contract_version 1.2 to core/reporting-report-definition.json.

  • The rule. At 1.2, a definition whose dimensions include media_buy_id MUST also include package_id, so every row carries the buyer-visible package. The schema uses draft-07 contains, conditional on the 1.2 const, and the new allOf branch carries x-added-in: 3.3.0.
  • Exemption. A definition whose rows are not scoped to a media buy, such as an account-level summary, declares no media_buy_id and is exempt at every version.
  • 1.2 keeps every 1.1 rule. The existing official_correction_mode condition now matches ["1.1", "1.2"].
  • Prose rules at 1.2:
    • media-buy-scoped rows MUST name the dimension media_buy_id, not a seller-native name;
    • the offering's reporting_profile.primary_keys MUST then include package_id, so per-package rows stay distinct.
  • 1.0 and 1.1 definitions keep validating unchanged. A grader SHOULD report one that includes media_buy_id but not package_id as an advisory finding, never a failure. This is the "advisory first" step from the issue.
  • Dimension name. package_id matches media_buy_id. Subscription selectors and offering standard_dimensions keep the standard name package. The mapping is noted in enums/reporting-dimension.json, sync_principal, and get_reporting_status.

How a seller and a buyer get 1.2

1.0 and 1.1 shipped together in #7228 with no capability or request field. The version lives in the definition, and the offering pins it with report_definition_uri and SHA-256. A seller adopts 1.2 by publishing a 1.2 definition in an offering, and a buyer chooses it by selecting that offering, exactly as for 1.1. No capability, feature id, or request field is added.

One difference from 1.1: receivers built from 3.2 already exist, and their contract_version enum is closed at ["1.0", "1.1"]. The PR therefore states the version-pin rule this surface already uses for configuration_task (get_adcp_capabilities): callers pinned below 3.3 accept only 1.0 and 1.1, so a seller MUST serve them offerings whose definitions are 1.0 or 1.1, and a 1.2 offering serves 3.3 callers only. experimental-status.mdx records that a strict validator built from 3.2 rejects a 1.2 definition, which is acceptable for an experimental surface.

Fixtures

  • The reporting-reconciliation reference fixture and its digests are unchanged. It stays at 1.1 with ["date", "media_buy_id"] and draws the advisory.
  • New static/compliance/source/test-vectors/reporting-report-definition/ (README, report-definition-1-2.json, vectors.json):
    • a 1.2 fixture with ["date", "media_buy_id", "package_id"];
    • the negative vector: a 1.2 media-buy definition without package_id fails;
    • account-level exemptions at 1.2 (["date"] and []);
    • ["date", "package_id"] at 1.2, which is valid because the rule keys on media_buy_id;
    • 1.2 without official_correction_mode, which fails;
    • 1.0 and 1.1 media-buy definitions without package_id, which are valid with the advisory.
  • tests/reporting-report-definition-vectors.test.cjs replays them against the built schema and an independent rule grader, and is added to test:schemas. The set is listed in docs/reference/test-vectors/index.mdx.

Storyboards

No storyboard step is added:

  • No storyboard fetches report-definition documents, so a step could not grade dimensions.
  • The one storyboard that reads revision rows (universal/reporting-core.yaml, exact_nonempty_revision_content) already requires package_id in its fixed row vector, as a required check, so an advisory step there would be redundant.

The advisory is defined in the vectors instead.

Release metadata

  • Changeset: minor.
  • x-added-in: 3.3.0 on the new conditional branch. 1.2 is noted in the enum description with "3.3", and the x-added-in-3-3 sweep test asserts both.
  • lint:additive-minor: 0 new against 3.2.10. The schema is experimental.
  • Pinned bounds, measured on base 38a83d1d44 with and without the change:

The training agent is not touched. Its definitions are 1.1 with dimensions: [], and REPORTING_STORAGE_CONTRACT is unchanged.

Notes for review

  • The media-buy marker is the media_buy_id dimension. Every revision and obligation carries a media_buy_ids denominator, aggregates included, so that field cannot tell an account-level definition apart. The definition has no other machine-readable scope; grain is free text. The naming MUST closes the gap of a seller-native name such as order_id.
  • Open, and it predates this PR: whether media_buy_id and date count toward unmapped_dimensions for subscription matching. The 1.2 fixture makes that question concrete for match: exact.

Tests run

  • node --test tests/reporting-report-definition-vectors.test.cjs: 4/4.
  • The new vectors, x-added-in-3-3-sweep, reporting-status-contract, reporting-subscriptions, and lint-schema-enum-drift together: 104/104.
  • The earlier run also covered reporting-core-fixture, reporting-reconciliation-fixture, docs-json-field-audit, and lint-additive-minor: 209/209.
  • mcp-schema-projection and mcp-schema-analysis: 41/41. capabilities-structural-bounds, counterparty-asserted-capability-bounds, and response-size-bounds: 100/100.
  • node tests/schema-validation.test.cjs: 36/36. An earlier run failed once with an ENOENT because it overlapped a concurrent build:schemas; it passed when rerun alone.
  • npm run lint:additive-minor: 0 new.
  • npm run build:compliance -- --check: links current.
  • scripts/lint-conformance-doc-freshness.cjs: vector catalog complete. The compliance source-authority, packaged-refs, doc-drift, and doc-freshness lint tests pass.
  • json-schema-validation and snippet-validation with --file on each edited page: pass. test:docs-nav and test:owned-links: pass.
  • The changeset scope check and changeset status: pass (minor).
  • check-pr-title: exit 0, with the usual notice for the spec type.
  • A pre-PR ad-tech-protocol-expert review. Its Must Fix (3.2 receivers reject 1.2) and Should Fix items are applied as described above.
  • Hooks:
    • pre-commit ran for real:
      • root test:unit 1284/1284, test:test-dynamic-imports, test:format-identity-boundaries, and test:callapi-state-change all passed.
      • The full server unit stage hit its 1500 s timeout under host load. Its parallel shards also had load failures, all in server files this PR doesn't touch: training-agent OAuth and governance credentials, the fixed-trace CLI tests, and exact-inference.
      • The PR stages no server/ file, so it was committed with HUSKY=0, as the coordinator's brief allows. typecheck passed by hand. CI runs the server unit suite.
    • Pushed with ADCP_SKIP_STORYBOARD_MATRIX=1. The matrix is triggered by static/compliance/source/ and package.json, but this PR changes no storyboard and no training-agent code. CI storyboards are authoritative.
    • The rebase onto e903ee6320 replays the same commit; its spec diff is byte-identical apart from the package.json union. It was committed with HUSKY=0.
      • An earlier update on the branch, a merge of main, ran the hook at load about 150. Root test:unit had 10 s timeouts in three unrelated files: ipr-check-and-record, compliance-authored-tool-gates, and adagents-builder-xss. Each passes alone (23/23, 66/66, 10/10).
      • The other pre-server steps and typecheck pass by hand.

🤖 Generated with Claude Code

bokelley added a commit that referenced this pull request Nov 13, 2026
…on 1.2, in the rc.0 docs

#8983 (#8971) adds Reliable Reporting report-definition contract_version
1.2: a definition whose dimensions include media_buy_id must include
package_id, account-level definitions are exempt, and callers pinned below
3.3 get 1.0 or 1.1 offerings. Add it to the release notes (checkpoint
row, feature index, behavior change, experimental table), What's new, and
the migration guide (checklist row 55 and a section), with markers until
it merges. The checkpoint row also gains #8974 and #8972, which it was
missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… package_id dimension (#8971)

Adds report-definition contract_version 1.2 to experimental Reliable
Reporting. A 1.2 definition keeps every 1.1 rule; when its dimensions
include media_buy_id they must also include package_id (draft-07
`contains`, conditional on the 1.2 const), so every row carries the
buyer-visible package. Definitions without media_buy_id, such as
account-level summaries, are exempt. 1.0 and 1.1 definitions are
unchanged; graders report a missing package_id there as advisory.

Callers pinned below 3.3 accept only 1.0 and 1.1, so sellers serve them
1.0 or 1.1 offerings. Adds test-vectors/reporting-report-definition with a
1.2 fixture and a negative vector; the reporting-reconciliation reference
fixture and its digests are unchanged.

Refs #8971

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bokelley
bokelley force-pushed the spec/8971-report-definition-package-id branch from fa00629 to 9148fa5 Compare November 13, 2026 17:26
bokelley added a commit that referenced this pull request Nov 13, 2026
…on 1.2, in the rc.0 docs

#8983 (#8971) adds Reliable Reporting report-definition contract_version
1.2: a definition whose dimensions include media_buy_id must include
package_id, account-level definitions are exempt, and callers pinned below
3.3 get 1.0 or 1.1 offerings. Add it to the release notes (checkpoint
row, feature index, behavior change, experimental table), What's new, and
the migration guide (checklist row 55 and a section), with markers until
it merges. The checkpoint row also gains #8974 and #8972, which it was
missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
#8972 merged as e903ee6. Drop its markers and narrow the shared ones
to #8983. The migration guide adds #8972's capability rule: buyers send
installment_refs only to a seller that lists the feature id, and a seller
without it rejects the field with UNSUPPORTED_FEATURE.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bokelley
bokelley marked this pull request as ready for review November 13, 2026 17:45

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ladon verdict: Escalate to human review

Escalate — gated schema paths require human/CODEOWNERS approval.

This PR modifies files under the deterministic hard approval gate (static/schemas/source/**) while review_decision is REVIEW_REQUIRED (not APPROVED). Per decision rule row 2, the outcome must be escalate.

Escalation reasons

  • Modifies static/schemas/source/core/reporting-report-definition.json (gated path static/schemas/source/**) — human/CODEOWNERS review required.
  • Modifies static/schemas/source/enums/reporting-dimension.json (gated path static/schemas/source/**) — human/CODEOWNERS review required.

The change itself is clean on the merits: the reviewer found no Critical/High/Medium findings. The new contract_version 1.2 branch requiring package_id on media-buy-scoped report definitions is additive on an experimental surface, is 1.2-const-discriminated with x-added-in: 3.3.0, the official_correction_mode condition correctly extends to ["1.1","1.2"], schema↔docs coherence holds across all four docs edits, the minor changeset is correctly scoped, no dist/** artifact is touched, and the test vectors + independent grader mirror the schema rule. The gate lifts once a human approval lands.

Why human review

  • Modifies static/schemas/source/core/reporting-report-definition.json (gated path static/schemas/source/**) with review_decision REVIEW_REQUIRED — human/CODEOWNERS approval required
  • Modifies static/schemas/source/enums/reporting-dimension.json (gated path static/schemas/source/**) with review_decision REVIEW_REQUIRED — human/CODEOWNERS approval required
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/core/reporting-report-definition.json (modified) matches static/schemas/source/**; static/schemas/source/enums/reporting-dimension.json (modified) matches static/schemas/source/**) and the current GitHub review decision is 'REVIEW_REQUIRED', not APPROVED. This is a hard gate enforced in code — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.

@aao-secretariat aao-secretariat Bot added the ladon/needs-human-review Ladon has escalated this PR for human review. label Nov 13, 2026
@bokelley
bokelley merged commit 39334ab into main Nov 13, 2026
73 checks passed
@bokelley
bokelley deleted the spec/8971-report-definition-package-id branch November 13, 2026 18:24
bokelley added a commit that referenced this pull request Nov 13, 2026
…on 1.2, in the rc.0 docs

#8983 (#8971) adds Reliable Reporting report-definition contract_version
1.2: a definition whose dimensions include media_buy_id must include
package_id, account-level definitions are exempt, and callers pinned below
3.3 get 1.0 or 1.1 offerings. Add it to the release notes (checkpoint
row, feature index, behavior change, experimental table), What's new, and
the migration guide (checklist row 55 and a section), with markers until
it merges. The checkpoint row also gains #8974 and #8972, which it was
missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
#8972 merged as e903ee6. Drop its markers and narrow the shared ones
to #8983. The migration guide adds #8972's capability rule: buyers send
installment_refs only to a seller that lists the feature id, and a seller
without it rejects the field with UNSUPPORTED_FEATURE.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
#8983 merged as 39334ab. Drop its seven markers, and state the
serving rule as a MUST everywhere it appears: a seller serves callers
pinned below 3.3 only 1.0 or 1.1 report-definition offerings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
…on 1.2, in the rc.0 docs

#8983 (#8971) adds Reliable Reporting report-definition contract_version
1.2: a definition whose dimensions include media_buy_id must include
package_id, account-level definitions are exempt, and callers pinned below
3.3 get 1.0 or 1.1 offerings. Add it to the release notes (checkpoint
row, feature index, behavior change, experimental table), What's new, and
the migration guide (checklist row 55 and a section), with markers until
it merges. The checkpoint row also gains #8974 and #8972, which it was
missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
#8972 merged as e903ee6. Drop its markers and narrow the shared ones
to #8983. The migration guide adds #8972's capability rule: buyers send
installment_refs only to a seller that lists the feature id, and a seller
without it rejects the field with UNSUPPORTED_FEATURE.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
#8983 merged as 39334ab. Drop its seven markers, and state the
serving rule as a MUST everywhere it appears: a seller serves callers
pinned below 3.3 only 1.0 or 1.1 report-definition offerings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
…on 1.2, in the rc.0 docs

#8983 (#8971) adds Reliable Reporting report-definition contract_version
1.2: a definition whose dimensions include media_buy_id must include
package_id, account-level definitions are exempt, and callers pinned below
3.3 get 1.0 or 1.1 offerings. Add it to the release notes (checkpoint
row, feature index, behavior change, experimental table), What's new, and
the migration guide (checklist row 55 and a section), with markers until
it merges. The checkpoint row also gains #8974 and #8972, which it was
missing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
#8972 merged as e903ee6. Drop its markers and narrow the shared ones
to #8983. The migration guide adds #8972's capability rule: buyers send
installment_refs only to a seller that lists the feature id, and a seller
without it rejects the field with UNSUPPORTED_FEATURE.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bokelley added a commit that referenced this pull request Nov 13, 2026
#8983 merged as 39334ab. Drop its seven markers, and state the
serving rule as a MUST everywhere it appears: a seller serves callers
pinned below 3.3 only 1.0 or 1.1 report-definition offerings.

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

ladon/needs-human-review Ladon has escalated this PR for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reliable Reporting: report-definition contract_version 1.2 requires a package_id dimension for media buys

1 participant