Skip to content

feat(codegen): add directional schema slicing and $ref alignment - #82

Open
gsmith85 wants to merge 2 commits into
feat/codegen-normalizerfrom
feat/codegen-slicing
Open

gsmith85 wants to merge 2 commits into
feat/codegen-normalizerfrom
feat/codegen-slicing

Conversation

@gsmith85

@gsmith85 gsmith85 commented Sep 30, 2026 •

Copy link
Copy Markdown

Summary

Implements Task 2 (PR 1b) of the two-layer ucp-schema code-generation pipeline: directional schema slicing and reference alignment passes in src/codegen/normalizer.rs, stacked on #81.

Changes

  • normalize_def_schema: strip UCP keywords, rewrite $ref targets to #/$defs/<PascalName>, synchronize canonical top-level titles, and normalize additionalProperties: true onto open object definitions.
  • has_directional_annotations and schema_supports_complete: detect ucp_request/ucp_response annotations and "complete" lifecycle operations via loader::for_each_schema_object (skipping instance data inside const/enum/default/examples).
  • slice_directional_schemas: resolve CreateRequest, UpdateRequest, optional CompleteRequest, and Response ("read") slices via resolver::resolve, omitting empty request slices for response-only nested value types.
  • align_directional_refs: rewrite #/$defs/<Target> inside directional request slices to #/$defs/<Target><Suffix> when present in known_defs (falling back to <Target>UpdateRequest for CompleteRequest slices).

Stacked PR Series Roadmap

  1. PR 1a (feat(codegen): add identifier naming, UCP keyword stripping, and $defs ref rewriting #81): Identifier qualification, UCP keyword stripping, $ref rewriting (src/codegen/normalizer.rs)
  2. PR 1b (this PR): Directional schema slicing & $ref alignment (src/codegen/normalizer.rs)
  3. PR 1c (feat(codegen): add capability reachability, composition, and generate_types() API #83): Capability/extension reachability, composition & generate_types() library API (src/codegen/{mod,reachability,hoist,compose}.rs)
  4. PR 1d (feat(cli): add generate-types subcommand #84): CLI generate-types subcommand (src/bin/ucp-schema.rs, tests/generate_types_test.rs)
  5. PR 2 (feat(codegen): add self-contained .well-known/ucp profile scoping for generate-types #85): Self-contained .well-known/ucp --profile scoping (src/codegen/profile.rs)
  6. PR 3a (feat(codegen): add AST shape normalizers and inline conditional variant hoisting #86): Codegen AST shape normalizers & inline conditional variant hoisting (src/codegen/normalizer.rs, src/codegen/reify.rs)
  7. PR 3b (feat(codegen): lower open string discriminator unions into ordered anyOf with <Union>Base #87): Open string discriminator union lowering (<Union>Base) (src/codegen/reify.rs)
  8. PR 3c (feat(codegen): discover and register decentralized extended subtypes into open unions #88): Cross-file extended subtype discovery & registration (src/codegen/reify.rs)
  9. PR 4a (python-sdk#101): Python SDK direct JSON Schema codegen (generate_models.sh, postprocess_models.py, src/ucp_sdk/models/)
  10. PR 4b (js-sdk#87): JS/TS SDK direct JSON Schema codegen (generate_models.sh, scripts/generate-zod-from-types.mjs, src/spec_generated.ts)
  11. PR 5: OpenAPI 3.1 REST service & type binding (ucp-schema generate-openapi, src/openapi/mod.rs)

Test Plan

  • cargo fmt --check
  • cargo test --all-targets
  • cargo clippy --all-targets -- -D warnings

@damaz91 damaz91 added the status:needs-triage Signal that the PR is ready for human triage label Sep 30, 2026
gsmith85 added a commit that referenced this pull request Oct 1, 2026
Implement Task 4 (PR 1d) of the ucp-schema codegen pipeline:
- Wire Commands::GenerateTypes in src/bin/ucp-schema.rs with --profile, --capability, --extension, --schema-dir (alias --schema-local-base), --schema-remote-base, --output, and --pretty.
- Implement CliExitCode for CodegenError and generalize write_json_output to <T: serde::Serialize + ?Sized>.
- Add CLI integration tests in tests/generate_types_test.rs covering stdout pretty/compact output, file output, repeatable/comma-delimited flags, and error exit codes.

Stacked PR Roadmap:
- PR 1a (#81): Identifier qualification, UCP keyword stripping, $ref rewriting
- PR 1b (#82): Directional schema slicing and $ref alignment
- PR 1c (#83): Capability/extension reachability, composition, and generate_types() library API
- PR 1d (this PR): CLI generate-types subcommand
- PR 2: Self-contained .well-known/ucp --profile scoping
- PR 3: Inline conditional variant hoisting and ordered anyOf union lowering
- PR 4: OpenAPI 3.1 REST binding assembly (generate-openapi)
gsmith85 added a commit that referenced this pull request Oct 1, 2026
Implement Task 4 (PR 1d) of the ucp-schema codegen pipeline:
- Wire Commands::GenerateTypes in src/bin/ucp-schema.rs with --profile, --capability, --extension, --schema-dir (alias --schema-local-base), --schema-remote-base, --output, and --pretty.
- Implement CliExitCode for CodegenError and generalize write_json_output to <T: serde::Serialize + ?Sized>.
- Add CLI integration tests in tests/generate_types_test.rs covering stdout pretty/compact output, file output, repeatable/comma-delimited flags, and error exit codes.

Stacked PR Roadmap:
- PR 1a (#81): Identifier qualification, UCP keyword stripping, $ref rewriting
- PR 1b (#82): Directional schema slicing and $ref alignment
- PR 1c (#83): Capability/extension reachability, composition, and generate_types() library API
- PR 1d (this PR): CLI generate-types subcommand
- PR 2: Self-contained .well-known/ucp --profile scoping
- PR 3: Inline conditional variant hoisting and ordered anyOf union lowering
- PR 4: OpenAPI 3.1 REST binding assembly (generate-openapi)
gsmith85 added a commit that referenced this pull request Oct 1, 2026
Implement Task 4 (PR 1d) of the ucp-schema codegen pipeline:
- Wire Commands::GenerateTypes in src/bin/ucp-schema.rs with --profile, --capability, --extension, --schema-dir (alias --schema-local-base), --schema-remote-base, --output, and --pretty.
- Implement CliExitCode for CodegenError and generalize write_json_output to <T: serde::Serialize + ?Sized>.
- Add CLI integration tests in tests/generate_types_test.rs covering stdout pretty/compact output, file output, repeatable/comma-delimited flags, and error exit codes.

Stacked PR Roadmap:
- PR 1a (#81): Identifier qualification, UCP keyword stripping, $ref rewriting
- PR 1b (#82): Directional schema slicing and $ref alignment
- PR 1c (#83): Capability/extension reachability, composition, and generate_types() library API
- PR 1d (this PR): CLI generate-types subcommand
- PR 2: Self-contained .well-known/ucp --profile scoping
- PR 3: Inline conditional variant hoisting and ordered anyOf union lowering
- PR 4: OpenAPI 3.1 REST binding assembly (generate-openapi)
@gsmith85
gsmith85 force-pushed the feat/codegen-slicing branch from b6fcada to 88c578b Compare October 1, 2026 23:45
gsmith85 added a commit that referenced this pull request Oct 1, 2026
Implement Task 4 (PR 1d) of the ucp-schema codegen pipeline:
- Wire Commands::GenerateTypes in src/bin/ucp-schema.rs with --profile, --capability, --extension, --schema-dir (alias --schema-local-base), --schema-remote-base, --output, and --pretty.
- Implement CliExitCode for CodegenError and generalize write_json_output to <T: serde::Serialize + ?Sized>.
- Add CLI integration tests in tests/generate_types_test.rs covering stdout pretty/compact output, file output, repeatable/comma-delimited flags, and error exit codes.

Stacked PR Roadmap:
- PR 1a (#81): Identifier qualification, UCP keyword stripping, $ref rewriting
- PR 1b (#82): Directional schema slicing and $ref alignment
- PR 1c (#83): Capability/extension reachability, composition, and generate_types() library API
- PR 1d (this PR): CLI generate-types subcommand
- PR 2: Self-contained .well-known/ucp --profile scoping
- PR 3: Inline conditional variant hoisting and ordered anyOf union lowering
- PR 4: OpenAPI 3.1 REST binding assembly (generate-openapi)
gsmith85 added a commit that referenced this pull request Oct 2, 2026
Implement Task 4 (PR 1d) of the ucp-schema codegen pipeline:
- Wire Commands::GenerateTypes in src/bin/ucp-schema.rs with --profile, --capability, --extension, --schema-dir (alias --schema-local-base), --schema-remote-base, --output, and --pretty.
- Implement CliExitCode for CodegenError and generalize write_json_output to <T: serde::Serialize + ?Sized>.
- Add CLI integration tests in tests/generate_types_test.rs covering stdout pretty/compact output, file output, repeatable/comma-delimited flags, and error exit codes.

Stacked PR Roadmap:
- PR 1a (#81): Identifier qualification, UCP keyword stripping, $ref rewriting
- PR 1b (#82): Directional schema slicing and $ref alignment
- PR 1c (#83): Capability/extension reachability, composition, and generate_types() library API
- PR 1d (this PR): CLI generate-types subcommand
- PR 2: Self-contained .well-known/ucp --profile scoping
- PR 3: Inline conditional variant hoisting and ordered anyOf union lowering
- PR 4: OpenAPI 3.1 REST binding assembly (generate-openapi)
gsmith85 added a commit that referenced this pull request Oct 2, 2026
Implement Task 4 (PR 1d) of the ucp-schema codegen pipeline:
- Wire Commands::GenerateTypes in src/bin/ucp-schema.rs with --profile, --capability, --extension, --schema-dir (alias --schema-local-base), --schema-remote-base, --output, and --pretty.
- Implement CliExitCode for CodegenError and generalize write_json_output to <T: serde::Serialize + ?Sized>.
- Add CLI integration tests in tests/generate_types_test.rs covering stdout pretty/compact output, file output, repeatable/comma-delimited flags, and error exit codes.

Stacked PR Roadmap:
- PR 1a (#81): Identifier qualification, UCP keyword stripping, $ref rewriting
- PR 1b (#82): Directional schema slicing and $ref alignment
- PR 1c (#83): Capability/extension reachability, composition, and generate_types() library API
- PR 1d (this PR): CLI generate-types subcommand
- PR 2: Self-contained .well-known/ucp --profile scoping
- PR 3: Inline conditional variant hoisting and ordered anyOf union lowering
- PR 4: OpenAPI 3.1 REST binding assembly (generate-openapi)
@gsmith85
gsmith85 force-pushed the feat/codegen-slicing branch from 88c578b to 4ed1ea1 Compare October 2, 2026 16:37
@gsmith85
gsmith85 force-pushed the feat/codegen-slicing branch from 4ed1ea1 to 7b74335 Compare October 7, 2026 06:00
@gsmith85
gsmith85 force-pushed the feat/codegen-slicing branch from 7b74335 to 9380b3c Compare October 7, 2026 22:04
Extend `src/codegen/normalizer.rs` with the directional slicing and reference alignment passes needed to compile UCP-annotated schemas into standard JSON Schema `$defs` entries:
- `normalize_def_schema`: strip UCP keywords, rewrite `$ref` targets to `#/$defs/<PascalName>`, and normalize `additionalProperties: true` onto open object definitions
- `has_directional_annotations` and `schema_supports_complete`: detect `ucp_request`/`ucp_response` annotations and `"complete"` lifecycle operations via `loader::for_each_schema_object`
- `slice_directional_schemas`: resolve `CreateRequest`, `UpdateRequest`, optional `CompleteRequest`, and `Response` ("read") slices via `resolver::resolve`, omitting empty request slices for response-only nested value types
- `align_directional_refs`: rewrite `#/$defs/<Target>` inside directional request slices to `#/$defs/<Target><Suffix>` when present in `known_defs` (falling back to `<Target>UpdateRequest` for `CompleteRequest` slices)

This PR is **Part 2 (PR 1b)** of a stacked series introducing a unified two-layer codegen pipeline to `ucp-schema` so downstream SDKs (`python-sdk`, `js-sdk`, `java-sdk`) can delete their bespoke schema preprocessors and generate idiomatic models directly from UCP schemas:

- **PR 1a (`feat/codegen-normalizer`, #81)**: Naming qualification, UCP keyword stripping, and `$ref` rewriting utilities (`src/codegen/normalizer.rs`).
- **PR 1b (this PR)**: Base definition normalization, directional request/response slicing (`CreateRequest` / `UpdateRequest` / `CompleteRequest` / `Response`), and directional `$ref` alignment.
- **PR 1c**: Capability/extension reachability, extension composition, and the `generate_types()` library API (`src/codegen/mod.rs`).
- **PR 1d**: `ucp-schema generate-types` CLI subcommand (`--schema-dir`, `--capability`, `--extension`, `--output`, `--pretty`).
- **Phase 2 (PR 2)**: `--profile` discovery, remote schema fetching via `ucp.capabilities[].schema` URLs, and self-describing `x-ucp-metadata`.
- **Phase 3 (PRs 3a-3d)**: Polymorphic union reification (open-union `anyOf` with `<Union>Base` fallback) and `ucp-schema generate-openapi` (Layer 2 REST path projection).
@gsmith85
gsmith85 force-pushed the feat/codegen-slicing branch from 9380b3c to e626830 Compare October 8, 2026 00:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:needs-triage Signal that the PR is ready for human triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants