Skip to content

feat(schema): bound new and experimental lists and strings, inventory the rest - #8512

Open
bokelley wants to merge 1 commit into
mainfrom
conductor/port-louis
Open

bokelley wants to merge 1 commit into
mainfrom
conductor/port-louis

Conversation

@bokelley

@bokelley bokelley commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

WG Session C (2026-10-26) decided to bound list sizes and string lengths across the protocol. This PR inventories every unbounded array and string, proposes a limit for each, and bounds the ones a minor release is allowed to change. It does not edit a stable schema.

  • Inventory (scripts/audit-schema-bounds.cjs, output in scripts/schema-bounds-inventory.json). Before the slice, main (2026-11-08) has 1,731 unbounded arrays in 468 files and 2,239 unbounded strings in 558 files. Each record gives:
    • file and pointer;
    • side: request, response, both or other;
    • stability;
    • the proposed limit and its rationale;
    • the action.
  • Proposal (specs/collection-bounds-proposal.md):
    • tiers, and the justification for the large limits;
    • the property and collection lists carried inline, flagged "move out of band (4.0)" with no limit proposed;
    • the 4.0 plan;
    • open questions for the WG.
  • 3.3 slice: 648 maxItems/maxLength keywords in 152 schemas. They go only on fields that are experimental (580) or new in 3.3 and absent from 3.2.8 (68). scripts/schema-bounds-3-3-slice.json lists each one.
  • 4.0: stable fields are proposed, not edited.

Unbounded arrays on main before the slice (strings are in the proposal doc):

Stability Request Response Both Other Total
stable 234 523 454 231 1,442
experimental 53 129 46 33 261
new in 3.3 2 11 11 4 28

Rebased onto main (2026-11-07, again 2026-11-08)

Main had moved 185 commits since this branch was cut. The slice depends on which fields are new in 3.3 or experimental, and that set has changed, so the rebase regenerated it instead of hand-merging:

  • Every schema file is main's copy plus the bounds that --apply writes.
  • The script, proposal, tests, registry entry and migration-guide section were carried over by hand.
  • Against the pre-rebase slice of 638 bounds:
    • 15 fields are gone or restructured on main;
    • 6 are now excluded as withdrawn;
    • 30 are fields that are new on main since then.
  • No limit changed for a field present in both.
  • The script now compares with the highest 3.2.x release in dist/schemas (3.2.8), the same base lint-additive-minor uses, instead of a hard-coded 3.2.7.

Second regeneration (2026-11-08, on 184f26d159). Main gained #8446 (supported match keys), #8445 and #8722. The same one-command path adds exactly two bounds, both on arrays #8446 added:

  • core/product-identity.json match_keys: maxItems: 64;
  • trusted-match/provider-registration.json match_keys: maxItems: 64.

The script classifies both as experimental (x-added-in: "3.3.0", both files x-status: experimental). The _keys name rule would give 32. Both use the item shape of the seller-wide media_buy.supported_match_keys, which is already maxItems: 64, so an ARRAY_FILE_OVERRIDES entry gives each the same cap:

  • A product's entries must each be covered by a seller-wide entry, so a lower product cap would stop a product from narrowing a large seller-wide set.
  • The TMP registration is compared under the same rule.

Standard code sets (Ladon review of 62f7bb39cb). countries lists were capped at 32 by the closed-vocabulary name rule, but they draw from ISO 3166-1 (249 assigned codes). A rights holder or a global TMP identity provider can legitimately name more than 32, and an omitted list often means "worldwide". Lists drawn from a standard code set are now bounded by the set, as an enum would be:

  • countries and excluded_countries: 256;
  • languages and locales (ISO 639 / BCP 47): 256;
  • regions (ISO 3166-2, about 5,000 subdivisions): 1,000.

That changes 14 slice bounds (13 to 256, 1 to 1,000), and the 4.0 proposal for 46 stable fields. Nothing else moves, and the total stays at 648.

Two more from Ladon's review of df5a1b0d6d:

  • trusted-match/identity-match-request.json package_ids: 100 → 500. All-active mode sends every active package at the publisher; this matches the sibling context-match-request package_ids (500).
  • governance/get-plan-audit-logs-response.json entries: 100 → 10,000. An audit trail grows with the plan and the endpoint has no pagination, so it gets the catalog ceiling.

I swept the slice for the same two patterns: other lists of every active package, and growth-unbounded logs without pagination. These were the only two.

#8446's core/match-key.json uses and property_types arrays are reachable from get_adcp_capabilities through supported_match_keys, so the existing deferred (#8198) rule covers them. scopes was already maxItems: 5. #8445 and #8722 add nothing that needs a bound. The withdrawn (#8501) entries were re-checked against the four PRs' current heads: all seven still match a removal, and no other slice candidate is removed.

Regenerating (one command). If this PR merges second, or anything conflicts with it:

  1. Take main's copy of each conflicting schema, and of scripts/schema-bounds-inventory.json and scripts/schema-bounds-3-3-slice.json.
  2. Run:
node scripts/audit-schema-bounds.cjs --apply

It bounds every node whose action is apply in 3.3, keeps each slice record whose bound is still in the source, drops the rest, and rewrites the inventory. It is idempotent. A second run adds nothing and leaves every file byte-identical.

Interaction with the #8501 withdrawals

Fields that #8765, #8762, #8758 and #8767 withdraw get no bound. The script lists them as withdrawn (#8501), so this PR and those PRs never edit the same line. I found them by comparing each PR's base and head trees node by node, and keeping the removed nodes the slice would otherwise bound:

Field PR
compliance/comply-test-controller-response.json forced.proposal_id #8765 (entry 1)
core/sla-window.json business_calendar_id #8762 (entries 11, 12)
creative/sync-creatives-request.json assignments[].trackers #8758 (entry 21)
media-buy/get-products-response.json refinement_applied[].result_product_id #8758 (entry 23)
media-buy/get-products-response.json execution_readiness.version #8758 (moves to list_products)
core/creative-assignment.json trackers #8767
core/measurement-terms.json billing_measurement.counting_mechanisms #8767

The other fields those PRs remove are already bounded on main, stable or constrained (enum, $ref), or inline collections lists. Entries 2, 3, 6 and 26 touch no slice candidate either: signing_profile is a $ref to an enum, metric_id is a $ref to an id that is already bounded, and entry 26 is an x-entity value.

Merge simulation. git merge-tree with this branch adds no conflict with any of #8765, #8762, #8758, #8767 or #8772 beyond what each already has with main:

The v4 registry entry and its guide section sit next to capabilities_structural_bounds_required_in_4_0, away from the sections #8758 and #8767 edit.

Heads-up for whoever merges after this. Two of those PRs move a field rather than drop it. In the new place the field arrives unbounded, so the new CI guard asks for a bound:

The fix is node scripts/audit-schema-bounds.cjs --apply. Once a withdrawal merges, its WITHDRAWN entries match no node, and the script's summary lists them as exclusions to delete. #8772 changes additionalProperties only and doesn't interact.

Safety

Additive-minor (#8502). node scripts/lint-additive-minor.cjs --baseline-ref origin/main on the rebased tree reports 38 recorded non-additive changes against 3.2.8, 0 new. The baseline file is unchanged.

SDK generation (validate-schema-bundle). The "Generate TypeScript SDK" failure is fixed.

  • I reproduced it locally from the rebased PR bundle with the workflow's exact steps.
  • It now fails on a node that is new since the first push: ReportingSubscriptionCoverage.excluded.package_ids. The SDK reduces excluded[] items (an allOf of if/then rules) to z.object({}).passthrough(), so its @maxItems post-process finds no ZodArray.
  • That node is now deferred. With it, five nodes are deferred (SDK generation), and every mixed-type node is deferred by rule:
    • core/targeting.json collection_lists and collection_lists_exclude: the TypeScript SDK hoists the bounded array into a type alias;
    • creative/list-creatives-response.json seller_revision (["integer", "string"]): becomes z.union([...]).max(N);
    • brand/update-rights-response.json generation_credentials: a Python post-generation fix matches the unbounded field text;
    • core/reporting-subscription-coverage.json excluded[].package_ids: new, see above.
  • With those deferred, I ran the PR bundle against adcp-client main and adcp-client-python next:
    • TypeScript runs clean through generate-types, validate-schemas, build:lib and the creative-asset probe;
    • Python runs clean through regenerate-schemas and validate-generated, and test_code_generation.py plus test_schemas_version_pin.py pass (135 tests).

MCP parity bound. The slice adds maxItems/maxLength to fields in the comply_test_controller request closure. That closure measures 1,385,040 bytes against main's 1,383,804, which is +1,236. PARITY_COMPILE_LIMIT moves from 1,384,000 to 1,386,000 with a measured comment, following the file's per-PR precedent. Every storyboard fixture still compiles, and the 4 MiB and 22 MiB caps are unchanged.

Capabilities structural bounds. No bound reaches get_adcp_capabilities or anything it references. scripts/capabilities-structural-bounds.cjs still reports 99,100,981 bytes worst case and 108 open positions, so DOCUMENTED_WORST_CASE_BYTES, DOCUMENTED_OPEN_POSITIONS and security.mdx are unchanged, and the test passes 25/25.

CI wiring (Ladon's medium finding)

--check-unreleased now runs in the Build Check workflow, next to the additive-minor guard, as npm run lint:schema-bounds. It takes about 4 seconds. It fails when an array or string that is new in 3.3 or experimental has no bound, and names the fix (--apply, or an exclusion with its reason). --check stays unwired: it would make every schema PR regenerate a 1.3 MB file. The proposal explains why.

Not done

  • protocol/get-adcp-capabilities-response.json is untouched, and so is every type it references (Spec tension: creative.supported_formats pushes capabilities past the 64 KiB that gates signing-key discovery #8198 owns it). 25 arrays are recorded as deferred (#8198).
  • Seven experimental inline lists stay unbounded: six collections responses and the TMP provider registration properties. Bounding them would legitimise the inline shape the WG rule removes.
  • 12 x-added-in markers disagree with 3.2.8. They are treated as stable and listed in the proposal for their owners.
  • After 3.3 GA, NEW_VERSION in the script moves to the next minor, so the guard covers that release's new fields.

Test plan

All of these ran on the regenerated tree, on main 184f26d159, then again on the head a8d78d72af (on 3bb0710886, #8798) after the review fixes: additive-minor, test:contracts, projection, registry, docs-nav, sample-request and json-schema. #8798 is compliance-only.

🤖 Generated with Claude Code


Open workspace in Conductor

@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 155+ files under static/schemas/source/**, which are under a hard, deterministic approval gate (gated_paths: true). review_decision is REVIEW_REQUIRED, not APPROVED, so decision-table row 2 fires: the gate is not satisfied and the outcome must be escalate.

The reviewer found no blocking issues. The change is additive-only (658 maxItems/maxLength bounds across 155 schemas), ships a correct patch changeset, adds an inventory script + test, and no stable field was tightened on the wire (spot-checked against 3.2.7). The dual guard (releasedOnWire re-check at audit-schema-bounds.cjs:407-417 and stabilityOf at L419-449) correctly prevents a mis-marked stable field from entering the "apply in 3.3" slice. Schema↔docs coherence holds, no package.json version edit, oneOf untouched, no dist/** mutated. A non-blocking follow-up (author-acknowledged): --check-unreleased is not wired into CI.

Mechanically clean, but the hard gate on protected schema source requires a human/CODEOWNERS approval before merge. No findings carry escalation on their own merits — this is purely the gated-paths gate.

Escalation reasons

  • Modifies protected static/schemas/source/** (155+ files, e.g. static/schemas/source/core/media-buy.json); gated_paths: true with review_decision: REVIEW_REQUIRED — human/CODEOWNERS approval required.

Why human review

  • Modifies protected static/schemas/source/** (155+ files) — gated_paths is true and review_decision is REVIEW_REQUIRED (not APPROVED); human/CODEOWNERS review required to satisfy the hard approval gate (decision table row 2).
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-scope.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-request.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-response.json (modified) matches static/schemas/source/**; static/schemas/source/core/agent-onboarding-requirement.json (modified) matches static/schemas/source/**; static/schemas/source/core/agent-onboarding-tier.json (modified) matches static/schemas/source/**; static/schemas/source/core/agent-onboarding.json (modified) matches static/schemas/source/**; static/schemas/source/core/agent-reporting-destination.json (modified) matches static/schemas/source/**; s

…(truncated)…

@aao-secretariat aao-secretariat Bot added the ladon/needs-human-review Ladon has escalated this PR for human review. label Oct 26, 2026
@aao-secretariat

Copy link
Copy Markdown
Contributor

Ladon cannot review this PR until merge conflicts are resolved.

@bokelley
bokelley force-pushed the conductor/port-louis branch from b5d158c to f3d14b4 Compare October 26, 2026 20:17

@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 — hard approval gate on protected spec paths not yet satisfied.

This PR modifies 150+ files under static/schemas/source/**, which are under the repo's deterministic hard approval gate (gated_paths: true). The current review_decision is REVIEW_REQUIRED, not APPROVED. Per decision table row 2, the gate is not satisfied and Ladon cannot auto-approve or plain-comment — human/CODEOWNERS review is required.

The prior decision was also escalate; this escalation is additionally supported by a fresh medium finding in this run (row 6 sticky is satisfied either way, but row 2 is the controlling trigger).

Escalation reasons:

  • Modifies protected static/schemas/source/** (150+ files) while review_decision is REVIEW_REQUIRED (not APPROVED). Human/CODEOWNERS approval is required to satisfy the hard approval gate.

Medium findings (non-blocking, for the human reviewer):

  • static/schemas/source/core/agent-onboarding-tier.json:20 — Duplicate maxItems key in requirements (added 100 over pre-existing 16; last-key-wins keeps 16, so the added bound is dead code). Worth cleaning up but does not change wire behavior.

Reviewer otherwise verified the schema-bounds classifier, its tests, the v4-compatibility registration, and the new/experimental-only changeset scope; spot-checked ~20 bounded schema files and confirmed bounds land on experimental or new-3.3 fields consistent with the no-stable-field-change claim. No critical/high findings. Once a human/CODEOWNERS approval is recorded, this falls through to a normal (likely approvable) review.

Medium findings

  • static/schemas/source/core/agent-onboarding-tier.json:20 — Duplicate maxItems key in agent-onboarding-tier.json requirements

Why human review

  • Modifies protected static/schemas/source/** (150+ files) — gated_paths is true and review_decision is REVIEW_REQUIRED (not APPROVED); human/CODEOWNERS review required to satisfy the hard approval gate (decision table row 2).
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-scope.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-request.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-response.json (modified) matches static/schemas/source/**; static/schemas/source/core/agent-onboarding-tier.json (modified) matches static/schemas/source/**; static/schemas/source/co

…(truncated)…

@bokelley
bokelley force-pushed the conductor/port-louis branch from f3d14b4 to 7a01b98 Compare October 26, 2026 20:33

@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-paths hard approval gate not satisfied.

This PR adds maxItems/maxLength bounds (615 keywords across 145 schemas) to experimental/new-in-3.3 arrays and strings, plus an inventory script, proposal doc, and v4-compatibility check. The reviewer verified the edits are purely additive (keyword inserted after type; no field renamed, retyped, or made required; no stable schema touched), that heavily-edited files carry x-status:experimental (so the additive-minor exemption and patch changeset hold), and that released dist/3.2.7 artifacts are only read, not modified. The audit-schema-bounds.cjs mixed-type deferral correctly keeps ["integer","string"] nodes out of the 3.3 slice.

Despite the clean diff, this PR touches 150+ files under static/schemas/source/**, which is under a hard, non-overridable approval gate (gated_paths: true). The current review_decision is unknown/none — NOT APPROVED. Per decision table row 2, the outcome MUST be escalate until a human/CODEOWNERS approval is recorded. This also matches the prior decision (escalate), which remains sticky because fresh medium evidence exists this run.

Medium findings

  • static/schemas/source/trust/v1/trust.json:472 — acknowledgements maxItems:100 contradicts the field's own description ("more than a few hundred ... SHOULD use acknowledgements_url"), rejecting inline arrays the prose calls valid. Worth a human look but not blocking on its own.

No critical/high findings. Prior medium (agent-onboarding-tier.json duplicate maxItems) is not in this delta.

Medium findings

  • static/schemas/source/trust/v1/trust.json:472 — acknowledgements maxItems:100 contradicts "a few hundred" in its description

Why human review

  • Modifies protected static/schemas/source/** (150+ files) — gated_paths is true and review_decision is not APPROVED (unknown/none); human/CODEOWNERS review is required to satisfy the hard approval gate (decision table row 2).
  • The bound on trust/v1/trust.json:472 (acknowledgements maxItems:100) contradicts its own description's 'a few hundred' guidance and should be confirmed by a human before merge.
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-scope.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-request.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-response.json (modified) mat

…(truncated)…

@bokelley
bokelley force-pushed the conductor/port-louis branch from 7a01b98 to f3bb27d Compare October 26, 2026 20:57

@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-paths hard approval gate unsatisfied + unresolved medium on a protected schema.

This PR modifies 150+ files under static/schemas/source/**, which is a hard, non-overridable approval gate (gated_paths: true). The current review_decision is REVIEW_REQUIRED, not APPROVED, so decision table row 2 fires: the gate cannot be satisfied by Ladon — a human/CODEOWNERS approval must be recorded before merge, regardless of how clean the diff is.

The prior decision was also escalate, and this run surfaces a fresh medium finding, so the escalation is not stale (row 6 would independently apply).

Medium findings

  • static/schemas/source/trust/v1/trust-acknowledgements.json:20 — acknowledgements maxItems:100 inverts the overflow design: the overflow/url document (described for orgs accepting "thousands of grants") is capped 5x below the inline trust.json list it is meant to relieve (now 500). The prior-pass finding (trust.json acknowledgements at 100) was resolved — now 500 — but the same root cause moved to the overflow document.

Positive signals from the reviewer: changeset present and correctly patch-scoped to unreleased fields; no stable wire change; no oneOf regression; no dist/** mutation; docs v4-compatibility registry updated coherently.

Escalation reasons

  1. Protected path gate: PR modifies static/schemas/source/** (150+ files) and review_decision is REVIEW_REQUIRED, not APPROVED. Human/CODEOWNERS review required to satisfy the hard approval gate.
  2. Unresolved bounds inversion on trust-acknowledgements.json:20 (maxItems:100 vs inline 500) should be confirmed by a human before merge.

Medium findings

  • static/schemas/source/trust/v1/trust-acknowledgements.json:20 — trust-acknowledgements.json acknowledgements maxItems:100 inverts the overflow design (lower than inline 500)

Why human review

  • Gated path: PR modifies static/schemas/source/** (150+ files) and review_decision is REVIEW_REQUIRED, not APPROVED — human/CODEOWNERS approval required to satisfy the hard approval gate (decision table row 2).
  • Medium (unresolved root cause): static/schemas/source/trust/v1/trust-acknowledgements.json:20 — acknowledgements maxItems:100 inverts the overflow design, capped 5x below the inline trust.json list (500) it is meant to relieve; should be confirmed by a human before merge.
  • Prior decision was escalate and a fresh medium finding persists this run (sticky-escalation evidence still present).
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-scope.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-request.json (modified) match

…(truncated)…

@bokelley
bokelley force-pushed the conductor/port-louis branch from f3bb27d to 2a7afd7 Compare October 26, 2026 21: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 — hard approval gate unsatisfied plus sticky-escalation evidence.

This PR modifies 150+ files under static/schemas/source/**, a path under a hard, non-overridable approval gate (gated_paths: true). The current review_decision is not APPROVED (unknown/none), so decision-table row 2 forces escalation: Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.

The prior decision was also escalate, and the reviewer re-surfaced a fresh Medium finding this run, so the sticky-escalation condition (row 6) still holds on live evidence.

Medium findings

  • static/schemas/source/trust/v1/trust-acknowledgements.json:20 — acknowledgements maxItems:100 inverts the overflow design, capped 5x below the inline trust.json list (500) it exists to relieve; root cause is the missing ARRAY_FILE_OVERRIDES entry in scripts/audit-schema-bounds.cjs:619. Should be confirmed by a human before merge.

No Critical/High findings were reported. Bounded fields spot-checked carry x-status: experimental / new-in-3.3, consistent with the passing additive-minor lint (no stable-field tightening, no breaking wire change under the patch changeset). The schema surface still requires human/CODEOWNERS sign-off to satisfy the gate.

Escalation reasons

  • Gated path: PR modifies static/schemas/source/** (150+ files) and review_decision is not APPROVED — human/CODEOWNERS approval required (decision table row 2).
  • Sticky escalation: prior decision was escalate and a fresh medium finding persists this run (row 6).

Medium findings

  • static/schemas/source/trust/v1/trust-acknowledgements.json:20 — trust-acknowledgements.json acknowledgements maxItems:100 inverts the overflow design (below inline 500)

Why human review

  • Gated path: PR modifies static/schemas/source/** (150+ files) and review_decision is not APPROVED — human/CODEOWNERS approval required to satisfy the hard approval gate (decision table row 2).
  • Sticky escalation: prior decision was escalate and a fresh medium finding (trust-acknowledgements.json:20) persists in this run (decision table row 6).
  • Medium (unresolved): static/schemas/source/trust/v1/trust-acknowledgements.json:20 — acknowledgements maxItems:100 inverts the overflow design, capped 5x below the inline trust.json list (500); should be confirmed by a human before merge.
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-scope.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-response.json (modified) mat

…(truncated)…

@bokelley
bokelley force-pushed the conductor/port-louis branch 2 times, most recently from 26e76c7 to d331149 Compare October 27, 2026 00:25

@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 — hard approval gate unsatisfied.

This PR modifies 150+ files under static/schemas/source/**, which are under the repo's hard, deterministic approval gate (gated_paths: true). The current review_decision is unknown/none — not APPROVED — so decision table row 2 forces escalation: Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.

Medium findings

  • static/schemas/source/trust/v1/trust-acknowledgements.json:20 — acknowledgements maxItems:100 inverts the overflow design: the out-of-band overflow destination is capped 5x below the inline trust.json list (500), because ARRAY_FILE_OVERRIDES covers trust.json#acknowledgements but not the overflow file (defaults to array-typical/100). Worth human confirmation before merge.

Escalation reasons

  1. Gated path: PR modifies static/schemas/source/** (150+ files) and review_decision is not APPROVED — human/CODEOWNERS approval required to satisfy the hard approval gate (row 2).
  2. Sticky escalation (row 6): prior decision was escalate and a fresh medium finding (trust-acknowledgements.json:20) persists in this run.

No critical/high findings surfaced. The schema-bounds audit tooling (scripts/audit-schema-bounds.cjs) is reported as conservative (defers stable fields to 4.0), the changeset is patch-scoped to new/experimental fields, and the additive-minor lint passes 0-new — but none of that lifts the gate. A human/CODEOWNERS approval on static/schemas/source/** is the only thing that satisfies it.

Medium findings

  • static/schemas/source/trust/v1/trust-acknowledgements.json:20 — trust-acknowledgements.json acknowledgements maxItems:100 inverts the overflow design (below inline 500)

Why human review

  • Gated path: PR modifies static/schemas/source/** (150+ files, including trust, brand rights, reporting, governance, and account financials schemas) and review_decision is not APPROVED — human/CODEOWNERS approval required to satisfy the hard approval gate (decision table row 2).
  • Sticky escalation (row 6): prior decision was escalate and a fresh medium finding (static/schemas/source/trust/v1/trust-acknowledgements.json:20) persists in this run.
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/get-account-requests-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/get-account-requests-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-scope.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; sta

…(truncated)…

@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-path approval gate unsatisfied + sticky escalation with fresh evidence.

This PR (schema-bounds slice) adds a 905-line audit script, a 234-line test, a patch changeset, a v4-compatibility doc row/section, and maxItems/maxLength bounds across 150+ experimental / new-3.3 schemas. The reviewer confirms the change is non-breaking (bounds land only on fields absent from 3.2.7 or experimental → correct patch type), docs↔schema are coherent (schema_bounds_required_in_4_0 check matches the script), and the test file covers duplicate-bound detection, ref resolution, and mixed-type deferral. No critical/high findings.

Why escalate (not approve):

  1. Row 2 — gated_paths: true (150+ files under static/schemas/source/**) AND review_decision is unknown/none, NOT APPROVED. The hard, non-overridable approval gate requires a recorded human/CODEOWNERS approval before this can merge. A clean diff cannot satisfy it.
  2. Row 6 — prior decision was escalate and a fresh medium finding persists in this run (trust-acknowledgements.json:20), so the earlier escalation legitimately sticks.

Medium findings

  • static/schemas/source/trust/v1/trust-acknowledgements.json:20 — acknowledgements maxItems:100 inverts the overflow design: the by-reference "thousands of grants" shard is capped 5x below trust.json's inline cap of 500, because ARRAY_FILE_OVERRIDES (scripts/audit-schema-bounds.cjs:619-625) lacks an entry for the standalone file. Experimental surface, non-blocking, but worth a human confirming before merge.

Escalation reasons

  • Gated path: PR modifies static/schemas/source/** (150+ files) and review_decision is not APPROVED — human/CODEOWNERS approval required to satisfy the hard approval gate (row 2).
  • Sticky escalation: prior decision was escalate and a fresh medium (trust-acknowledgements.json:20) persists (row 6).

Medium findings

  • static/schemas/source/trust/v1/trust-acknowledgements.json:20 — trust-acknowledgements.json acknowledgements maxItems:100 inverts the overflow design (below inline 500)

Why human review

  • Gated path: PR modifies static/schemas/source/** (150+ files) and review_decision is not APPROVED — human/CODEOWNERS approval required to satisfy the hard approval gate (decision table row 2).
  • Sticky escalation: prior decision was escalate and a fresh medium finding (trust-acknowledgements.json:20) persists in this run (decision table row 6).
  • Medium (unresolved): static/schemas/source/trust/v1/trust-acknowledgements.json:20 — acknowledgements maxItems:100 inverts the overflow design, capped 5x below the inline trust.json list (500); ARRAY_FILE_OVERRIDES lacks an entry for the standalone file. Should be confirmed by a human before merge.
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/get-account-requests-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/get-account-requests-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (mod

…(truncated)…

@bokelley
bokelley force-pushed the conductor/port-louis branch from d331149 to abdd71f Compare October 27, 2026 02:17

@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 — hard approval gate on gated paths is unsatisfied.

This PR modifies 150+ files under static/schemas/source/**, a path under a hard, non-overridable approval gate (gated_paths: true). The current review_decision is REVIEW_REQUIRED, not APPROVED, so decision table row 2 fires: the outcome must be escalate and cannot be approve, regardless of how clean the diff is. A human/CODEOWNERS approval is required to satisfy the gate.

The reviewer found no blocking or medium findings in this run. The prior Medium (trust-acknowledgements.json acknowledgements maxItems inverted below the inline 500) was resolved — it is now maxItems:10000 > inline 500 with a matching ARRAY_FILE_OVERRIDE. Credit to the developer for addressing that feedback; this is a net improvement over the prior pass. Schema↔docs coherence, changeset scope (patch, scoped to new-in-3.3/experimental fields — no stable wire field bounded, so no breaking change on a patch), and the stability gate all check out per the reviewer's sampling.

No findings carry forward as blockers. The sole remaining reason for escalation is the mechanical gated-paths requirement: a human reviewer or CODEOWNERS must record an approval before this can merge.

Escalation reasons

  • Gated path: PR modifies static/schemas/source/** (150+ files) and review_decision is REVIEW_REQUIRED, not APPROVED — human/CODEOWNERS approval required to satisfy the hard approval gate (decision table row 2).

Why human review

  • Gated path: PR modifies static/schemas/source/** (150+ files) and review_decision is REVIEW_REQUIRED, not APPROVED — human/CODEOWNERS approval required to satisfy the hard approval gate (decision table row 2).
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/get-account-requests-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/get-account-requests-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-scope.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-request.json (modified) matches static/schemas/source/**; static/schem

…(truncated)…

@bokelley
bokelley force-pushed the conductor/port-louis branch from abdd71f to 328a336 Compare October 28, 2026 09:55
Comment thread tests/audit-schema-bounds.test.cjs Resolved

@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 adds 638 maxItems/maxLength bounds across 153 schemas under static/schemas/source/**, plus a dev audit script, committed inventory, and a test. The reviewer verified the load-bearing safety premise: bounds land only on new-3.3/experimental nodes, never on stable 3.2.7 wire fields (spot-checked trust/v1/trust.json, core/dooh-inventory-summary.json, core/delivery-metrics.json, and demographic/evaluator-spec nodes against the released artifact). No oneOf regression, no docs drift (v4-compatibility.mdx registry entry added correctly), and the patch changeset reasoning holds since no stable surface changes.

Decision table row 2 applies: gated_paths: true (modifies static/schemas/source/**) AND review_decision: REVIEW_REQUIRED (not APPROVED). This is a hard, non-overridable approval gate — Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, no matter how clean the diff. This matches the prior escalate decision; nothing has changed on the review-status front.

Medium findings (1 — non-blocking):

  • tests/audit-schema-bounds.test.cjs:212 — The --check / --check-unreleased gates are built but not wired into CI, so slice-completeness and inventory freshness go unenforced.

No critical or high findings. Once a human/CODEOWNERS approval lands (review_decision → APPROVED), this PR can fall through to the normal table; the single medium alone would not block.

Escalation reason: Human/CODEOWNERS review required to satisfy the hard approval gate on static/schemas/source/** (150+ files modified) while review_decision is REVIEW_REQUIRED.

Medium findings

  • tests/audit-schema-bounds.test.cjs:212 — Bounds gates (--check / --check-unreleased) not wired into CI

Why human review

  • Gated path: PR modifies static/schemas/source/** (150+ files) and review_decision is REVIEW_REQUIRED, not APPROVED — human/CODEOWNERS approval required to satisfy the hard, non-overridable approval gate (decision table row 2).
  • This PR touches a path under a hard, non-overridable approval gate (static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/get-account-requests-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/get-account-requests-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-scope.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-request.json (modified) ma

…(truncated)…

@bokelley
bokelley force-pushed the conductor/port-louis branch from 328a336 to d67104c Compare November 7, 2026 02:11

@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-path approval gate not satisfied.

This PR modifies 150+ files under static/schemas/source/** (plus .github/workflows/build-check.yml), all of which fall under a hard, non-overridable approval gate (gated_paths: true). The current review_decision is REVIEW_REQUIRED, not APPROVED, so decision table row 2 fires: Ladon cannot auto-approve until a human/CODEOWNERS approval is recorded, regardless of how clean the diff is.

Net improvement acknowledged: the sole prior Medium finding (bounds gates not wired into CI, tests/audit-schema-bounds.test.cjs:212) is resolved — package.json adds lint:schema-bounds → audit-schema-bounds.cjs --check-unreleased, build-check.yml wires it as a guard step beside the additive-minor check, and test:contracts now runs the bounds test. --check is deliberately left unwired with a documented rationale. No new blocking or Medium findings this pass.

Because no critical/high/medium findings remain, the escalation is driven solely by the unsatisfied gated-path gate, not by code-quality concerns.

Escalation reasons

  • Gated path: PR modifies static/schemas/source/** (150+ files) and .github/workflows/build-check.yml, and review_decision is REVIEW_REQUIRED, not APPROVED. Human/CODEOWNERS approval is required to satisfy the hard approval gate (decision table row 2).

Once a human/CODEOWNERS approval is recorded, this PR should fall through to a normal approve on a subsequent pass given the clean findings.

Why human review

  • Gated path: PR modifies static/schemas/source/** (150+ files) and .github/workflows/build-check.yml; review_decision is REVIEW_REQUIRED, not APPROVED — human/CODEOWNERS approval required to satisfy the hard, non-overridable approval gate (decision table row 2).
  • This PR touches a path under a hard, non-overridable approval gate (.github/workflows/build-check.yml (modified) matches .github/workflows/**; static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-request.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-response.json (modified) matches static/schemas/source/**; static/schemas/source/core/account-candidate.json (modified) matches static/schemas/source/**; static/schemas/source/core/accoun

…(truncated)…

Comment thread scripts/audit-schema-bounds.cjs Fixed
@bokelley
bokelley force-pushed the conductor/port-louis branch from d67104c to cea6a4a Compare November 7, 2026 02:24

@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 paths touched without a recorded approval.

This PR modifies files under hard, non-overridable approval gates — .github/workflows/build-check.yml (matches .github/workflows/**) and 150+ files under static/schemas/source/** — and review_decision is not APPROVED (unknown/none). Decision table row 2 (gated_paths: true AND review_decision ≠ APPROVED) fires before any other outcome, so Ladon cannot auto-approve regardless of how clean the diff is. A human/CODEOWNERS approval must be recorded to satisfy the gate.

The reviewer returned a clean pass with no Critical/High/Medium findings. The change adds 646 maxItems/maxLength bounds across 152 schemas plus scripts/audit-schema-bounds.cjs and a CI gate, and the load-bearing safety property (only new-3.3/experimental fields bounded, never stable wire fields) was empirically verified against the 3.2.8 baseline. Schema↔docs coherence, changeset scope, and the compliance registry were all confirmed coherent. This is consistent with the prior escalate, which was also driven solely by the unsatisfied gated-paths gate, not by any actionable finding.

Escalation reasons

  • Modifies .github/workflows/build-check.yml and 150+ files under static/schemas/source/**, both under a hard approval gate; review_decision is not APPROVED — human/CODEOWNERS review required to merge.

Why human review

  • Gated path (decision table row 2): PR modifies .github/workflows/build-check.yml and 150+ files under static/schemas/source/**; review_decision is not APPROVED. Human/CODEOWNERS approval is required to satisfy the hard, non-overridable approval gate — Ladon cannot auto-approve until that approval is recorded, regardless of a clean diff.
  • This PR touches a path under a hard, non-overridable approval gate (.github/workflows/build-check.yml (modified) matches .github/workflows/**; static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-request.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-response.json (modified) matches static/schemas/source/**; static/schemas/source/core/account-candidate.json (modified) matches static/schemas/source/**; static/schemas/source/core/account-request-record.json (modified) matches `static/schem

…(truncated)…

@bokelley
bokelley force-pushed the conductor/port-louis branch from cea6a4a to 62f7bb3 Compare November 8, 2026 03:17

@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 paths touched without an APPROVED review.

This PR modifies .github/workflows/build-check.yml and 150+ files under static/schemas/source/**, both of which fall under the repo's hard, non-overridable approval gate (gated_paths: true). The current review_decision is REVIEW_REQUIRED, not APPROVED. Per decision table row 2, this blocks auto-approval regardless of how clean the diff is — human/CODEOWNERS approval must be recorded first.

The two current findings are both Medium (no critical/high), so row 1 does not fire; row 2 governs. Note that even absent the gate, two Medium findings (<3) with no escalation-category match would fall to approve — but the gate takes precedence.

Escalation reasons

  • Gated path (row 2): PR modifies .github/workflows/build-check.yml and 150+ static/schemas/source/** files; review_decision is REVIEW_REQUIRED, not APPROVED. Human/CODEOWNERS approval required to satisfy the hard approval gate.

Medium findings (non-blocking, for reviewer attention)

  • static/schemas/source/brand/search-brands-response.json:160 — countries arrays capped at maxItems:32, too tight for the ISO 3166 corpus; a >32-country rights grant forced to omit reads as a worldwide over-claim.
  • static/schemas/source/trusted-match/provider-registration.json:31 — provider-registration countries capped at 32 blocks global identity providers from registering full coverage.

These bounds were verified to land only on experimental/new-in-3.3 fields; changeset is patch/experimental-only and correctly scoped; no dist/ artifact mutation (the beta churn is rebase noise). Prior run was also escalate on the same gate with no findings — this remains a gate-driven escalation, now with two Medium corpus-bound concerns worth a human eye during approval.

Medium findings

  • static/schemas/source/brand/search-brands-response.json:160 — countries arrays capped at maxItems:32, too tight for ISO 3166 corpus
  • static/schemas/source/trusted-match/provider-registration.json:31 — provider-registration countries capped at 32 blocks global identity providers

Why human review

  • Gated path (decision table row 2): PR modifies .github/workflows/build-check.yml and 150+ files under static/schemas/source/**; review_decision is REVIEW_REQUIRED, not APPROVED. Human/CODEOWNERS approval is required to satisfy the hard, non-overridable approval gate before Ladon can approve.
  • This PR touches a path under a hard, non-overridable approval gate (.github/workflows/build-check.yml (modified) matches .github/workflows/**; static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static

…(truncated)…

@bokelley
bokelley force-pushed the conductor/port-louis branch from 62f7bb3 to df5a1b0 Compare November 8, 2026 04:11

@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 paths require human/CODEOWNERS approval (review_decision: REVIEW_REQUIRED).

This PR bounds new-in-3.3 and experimental arrays/strings across 152 schemas via a conservative classifier that defers stable fields to 4.0. The patch changeset and additive-minor reasoning are sound, and both prior Medium findings (search-brands and provider-registration countries) are resolved — they are now maxItems:256. Credit to the author for addressing the earlier feedback.

Decision path: Row 1 does not fire (no critical/high findings). Row 2 fires — gated_paths: true (.github/workflows/build-check.yml plus 150+ files under static/schemas/source/**) and review_decision is REVIEW_REQUIRED, not APPROVED. The hard, non-overridable approval gate is not satisfied, so the outcome must be escalate. This is consistent with the prior escalate, and fresh medium findings remain in this run (row 6 would also sustain stickiness), but row 2 is the controlling trigger.

Medium findings (surfaced for the human reviewer; not independently blocking):

  • static/schemas/source/trusted-match/identity-match-request.json:169 — identity-match package_ids maxItems:100 undershoots documented all-active privacy mode and the correlated context-match cap of 500.
  • static/schemas/source/governance/get-plan-audit-logs-response.json:268 — get-plan-audit-logs entries capped at 100 with no pagination truncates the audit trail.

Escalation reasons

  • Gated path (decision table row 2): PR modifies .github/workflows/build-check.yml and 150+ files under static/schemas/source/**; review_decision is REVIEW_REQUIRED, not APPROVED. Human/CODEOWNERS approval is required to satisfy the hard, non-overridable approval gate before Ladon can approve.

Once a human/CODEOWNERS approval is recorded, the gate lifts and this clean-but-for-two-mediums diff falls through to row 9 (approve). The two mediums above are worth a glance during that review.

Medium findings

  • static/schemas/source/trusted-match/identity-match-request.json:169 — identity-match package_ids maxItems:100 undershoots documented all-active privacy mode
  • static/schemas/source/governance/get-plan-audit-logs-response.json:268 — get-plan-audit-logs entries capped at 100 with no pagination truncates audit trail

Why human review

  • Gated path (decision table row 2): PR modifies .github/workflows/build-check.yml and 150+ files under static/schemas/source/**; review_decision is REVIEW_REQUIRED, not APPROVED. Human/CODEOWNERS approval is required to satisfy the hard, non-overridable approval gate before Ladon can approve.
  • This PR touches a path under a hard, non-overridable approval gate (.github/workflows/build-check.yml (modified) matches .github/workflows/**; static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-te

…(truncated)…

…erimental, and inventory the rest

Adds scripts/audit-schema-bounds.cjs and its inventory: every unbounded array and string in the schema source, by stability, request or response side and proposed limit, plus every property or collection list carried inline. Bounds the arrays and strings that are new in 3.3 or experimental: 648 maxItems/maxLength keywords in 152 schemas, written by `node scripts/audit-schema-bounds.cjs --apply`, which is idempotent and is the one command for regenerating the slice after a conflict. Stable fields are proposed for 4.0 in specs/collection-bounds-proposal.md and registered as schema_bounds_required_in_4_0.

Not bounded: get_adcp_capabilities and its referenced types (#8198), inline property and collection lists, five nodes the SDK generators cannot carry a bound on, and seven 3.3 beta fields that the #8501 withdrawal PRs (#8765, #8762, #8758, #8767) remove.

The script now compares with the highest 3.2.x release (3.2.8), the base lint-additive-minor uses. Build Check runs its --check-unreleased guard as npm run lint:schema-bounds, so every new 3.3 or experimental array or string arrives with a bound. The match_keys arrays #8446 added on product identity and TMP provider registration get maxItems 64, the cap media_buy.supported_match_keys already carries. The MCP parity compile limit moves from 1,384,000 to 1,386,000 bytes (the controller closure measures 1,385,040).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bokelley
bokelley force-pushed the conductor/port-louis branch from df5a1b0 to a8d78d7 Compare November 8, 2026 05:06

@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 paths require human/CODEOWNERS approval.

This PR modifies .github/workflows/build-check.yml and 150+ files under static/schemas/source/**, both of which fall under the repo's hard, non-overridable approval gate (gated_paths: true). The current review_decision is REVIEW_REQUIRED, not APPROVED. Per decision table row 2, the gate is not satisfied and the outcome must be escalate — regardless of how clean the diff is.

Net improvement vs. prior run: Both prior Medium findings are resolved:

  • static/schemas/source/trusted-match/identity-match-request.json — package_ids now maxItems 500 (all-active privacy mode) via explicit ARRAY_FILE_OVERRIDES with rationale.
  • static/schemas/source/governance/get-plan-audit-logs-response.json — audit entries now maxItems 10000 (unpaginated audit trail) via explicit override.

No new findings this pass. The change adds maxItems/maxLength only to new-3.3/experimental nodes, driven by scripts/audit-schema-bounds.cjs, gated by lint:schema-bounds, covered by tests, with a valid patch (non-breaking) changeset. No oneOf, docs-coherence, or dist-immutability issues.

Escalation reasons:

  • Gated path (row 2): PR modifies .github/workflows/build-check.yml and 150+ files under static/schemas/source/**; review_decision is REVIEW_REQUIRED, not APPROVED. A human/CODEOWNERS approval is required to lift the hard approval gate before Ladon can approve.

The diff itself is clean — once a CODEOWNERS/human approval is recorded, this PR falls through to approve.

Why human review

  • Gated path (decision table row 2): PR modifies .github/workflows/build-check.yml and 150+ files under static/schemas/source/**; review_decision is REVIEW_REQUIRED, not APPROVED. Human/CODEOWNERS approval is required to satisfy the hard, non-overridable approval gate before Ladon can approve.
  • This PR touches a path under a hard, non-overridable approval gate (.github/workflows/build-check.yml (modified) matches .github/workflows/**; static/schemas/source/account/get-account-financials-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/list-account-changes-response.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-request.json (modified) matches static/schemas/source/**; static/schemas/source/account/request-account-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/acquire-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-brand-identity-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/get-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-pricing-option.json (modified) matches static/schemas/source/**; static/schemas/source/brand/rights-terms.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/search-brands-response.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-request.json (modified) matches static/schemas/source/**; static/schemas/source/brand/update-rights-response.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-request.json (modified) matches static/schemas/source/**; static/schemas/source/compliance/comply-test-controller-response.json (modified) matches static/schemas/source/**; static/schemas/source/core/account-candidate.j

…(truncated)…

This branch has not been deployed

No deployments
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.

2 participants