Conversation
…ta.extensions validate_catalogs_identifiers walked every dict and list under a component or function definition and checked the keys of any `properties` object it met against UAX a2ui-project#31. That reaches into `metadata.extensions`, which common_types.json's `Extensions` types as opaque vendor JSON, so an extension whose value carries a JSON Schema fragment with a hyphenated key was refused with "Invalid argument/property name" although the naming rule covers only the names a catalog declares. Descend through JSON Schema subschema positions only (`properties`, `items`, `allOf`/`anyOf`/`oneOf`, `$defs`, `additionalProperties`, ...), and add such an extension to testing_catalog.json: it passes the structural check already and now passes the identifier check too, while a hyphenated key in a real subschema position is still refused.
…lk with synthetic cases Review of the subschema-only walk found two positions it no longer reached that ajv still evaluates under `--spec=draft2020`: schema-valued `dependencies` (legacy, but honoured) and `contentSchema`. Add both. Factor the walk into `iter_subschemas`, which yields `(pointer, subschema)` for every JSON Schema subschema position and nothing else, so other checks over catalog schemas can share the one definition of "what is schema and what is annotation". The shipped catalogs only ever carry valid names, so a keyword dropped from the SUBSCHEMA_* tuples went unnoticed. Add a harness step that runs the walk over synthetic schemas and checks the exact names it reports: hyphens under `allOf -> items -> properties`, function `args`, a declared property named `metadata` and `dependencies` are refused; the same key inside `metadata.extensions` or `examples` is not.
…the walk Under `--spec=draft2020 --strict=false` ajv ignores `additionalItems`, so walking it claimed a rationale that does not hold; `definitions` and `dependencies` are still evaluated and stay. The synthetic cases covered only a few keywords, so most of the SUBSCHEMA_* tuples could lose an entry unnoticed. Place an invalid name under every keyword the walk must follow, with the keywords spelled out in the case block rather than derived from the tuples, so a dropped keyword still has a failing case.
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request introduces a utility to recursively validate property names against UAX #31 identifiers within JSON schemas, including comprehensive synthetic test cases to ensure the identifier walk correctly traverses subschemas. The reviewer suggested an optimization for the iter_subschemas function to improve performance and readability by using a single dictionary mapping for keyword categories instead of multiple tuples. No review comments were removed.
e00f07b to
952b0bd
Compare
Review suggestion: one keyword -> shape dictionary, iterated over the keys the schema actually has, instead of three tuples looked up on every node.
|
Hi @uny, I have reviewed and verified the changes. Thank you for your contribution. Hi @gspencergoog, I would like to escalate this PR. Could you please take a look? |
Description
validate_catalogs_identifiersinspecification/v1_0/test/run_tests.pywalks everydictandlistunder a component or function definition and checks the keys of anypropertiesobject it meets against UAX #31 (str.isidentifier()). That reaches intometadata.extensions, whichcommon_types.json'sExtensionstypes as opaque vendor JSON — keys are identifiers, values are unconstrained (patternProperties: {…: {}}). The naming rule itself (docs/a2ui_protocol.mdline 529) covers "component names, function names, and argument/property names": the names a catalog declares.So a catalog component carrying
passes the structural (ajv) check against
catalog_definition.jsonand is refused by the identifier check withInvalid argument/property name: 'x-legacy-name', although no stated rule constrains what is inside an extension value.This PR:
iter_subschemas, which yields the direct subschemas of a schema through JSON Schema subschema positions only (properties,items,prefixItems,allOf/anyOf/oneOf,not,if/then/else,$defs,patternProperties,additionalProperties,dependentSchemas,contentSchema, … plus the legacydefinitions/dependenciesthat ajv still evaluates under--spec=draft2020) and skips annotation values such asmetadata,description,examples;validate_catalogs_identifierscheckspropertieskeys through it;test/testing_catalog.jsonas the fixture;validate_identifier_walk, a harness step that places an invalid name under every keyword the walk must follow (and insidemetadata.extensions/examples, where it must not look) and checks the exact names reported — the shipped catalogs only ever carry valid names, so without this a keyword dropped from the tables would go unnoticed.Fixes #2705.
Reproduction
No workflow runs
run_tests.py, so:main+ the fixture alone: structural check passes, identifier check fails with the message above (166 passed / 1 failed).allOf → items → properties, under a function'sargs.properties, under a declared property namedmetadata, and under each of the 20 subschema keywords is still refused, and dropping a keyword from the tables fails its case.Pre-launch Checklist
One time:
For this PR:
specification/testing_catalog.jsonand the synthetic cases invalidate_identifier_walkspecification/v1_0/testonly;python3 run_tests.py,pyink --checkandprettier --checkpass🤖 Generated with Claude Code