Skip to content

feat: add export-openapi subcommand (RFC companion) - #73

Draft
gsmith85 wants to merge 1 commit into
mainfrom
feat/export-openapi
Draft

feat: add export-openapi subcommand (RFC companion)#73
gsmith85 wants to merge 1 commit into
mainfrom
feat/export-openapi

Conversation

@gsmith85

@gsmith85 gsmith85 commented Sep 2, 2026

Copy link
Copy Markdown

Summary

Companion RFC: Universal-Commerce-Protocol/ucp#800

This PR introduces the export-openapi subcommand and library API to ucp-schema, providing the reference compiler implementation for the UCP Interface-Definition Strategy RFC.

It compiles raw UCP JSON Schemas (Draft 2020-12) into a canonical, self-contained OpenAPI 3.1.0 specification. This provides the ecosystem with standardized client/server stubs and strongly-typed DTOs, retiring >3,500 lines of brittle AST preprocessing scripts currently maintained across language SDKs (python-sdk, js-sdk).


Core Compiler Pipeline (5 Lowering Passes)

  1. Pass 1 — Scoped $defs Hoisting (mod.rs, normalizer.rs):
    • Hoists internal definitions to components.schemas with <Parent><Def> qualification, eliminating naming collisions while rewriting # self-refs and distributing properties into bare anyOf constraint unions.
  2. Pass 2 — Capability Composition & Directional Slicing (mod.rs, normalizer.rs):
    • Composes active capability extensions (discount.json, fulfillment.json) into root resources (checkout.json, cart.json).
    • Slices schemas by (direction, op) into explicit models (CheckoutCreateRequest, CheckoutUpdateRequest, CheckoutCompleteRequest, Checkout).
    • Prunes empty container schemas (CatalogLookup, CatalogSearch, Pagination) from the registry.
  3. Pass 3 — Directional Reference Alignment (mod.rs):
    • Recursively traverses sliced request models, oneOf unions, and discriminator.mapping dictionaries (e.g. updating LocationDestination to LocationDestinationCreateRequest).
  4. Pass 4 — Polymorphic Discriminator Synthesis (discriminator.rs):
    • Synthesizes explicit OpenAPI 3.1 discriminator.mapping tables from conditional allOf + if/then branches.
  5. Pass 5 — Wire Protocol Projection (operations.rs):
    • Projects canonical routes (/checkout-sessions, /carts, /orders, /catalog) driven by x-ucp-path and x-ucp-lifecycle.
    • Attaches standard protocol parameters (UCP-Agent, Idempotency-Key) and RFC 9421 HTTP Message Signature security schemes.

Built for Zero-Maintenance Extensibility

To eliminate ongoing maintenance overhead as UCP evolves, export-openapi is 100% schema-driven:

  • Zero-Touch for New Verticals: Single-object resources and RPC container operations are detected structurally (is_container_schema, is_extension_schema, {op}_request conventions). Adding new verticals (Lodging, Services) requires zero Rust compiler code edits.
  • Declarative Routing: Canonical paths are governed in schema space via "x-ucp-path" (e.g. "x-ucp-path": "/checkout-sessions"), decoupling route authorship from compiler code.
  • Graph-Driven Profile Down-Scoping: Profiles (--profile shopping) compute transitive $ref dependency closures rather than static file allowlists, ensuring new schema properties are automatically resolved.
  • Hermetic CI Drift Gate: export-openapi --check verifies byte-for-byte spec parity in GitHub Actions, preventing schema drift with zero human review overhead.

Verification & Test Status

  • Cargo Test: 126/126 passed across all unit, conformance, container, and OpenAPI integration tests (tests/export_openapi_test.rs).
  • Cargo Clippy: 0 warnings (cargo clippy --all-targets -- -D warnings).
  • Cryptographic Determinism: Independently compiled against Universal-Commerce-Protocol/ucp with byte-for-byte identical SHA-256 (02668cd8...), zero broken $refs across 447 references, 172 component schemas, and 12 canonical REST routes.

@gsmith85
gsmith85 force-pushed the feat/export-openapi branch 2 times, most recently from db7343b to 7529723 Compare September 2, 2026 21:53
Add `export-openapi` subcommand and library API to compile canonical UCP
JSON Schemas (Draft 2020-12) into valid, self-contained OpenAPI 3.1.0 specifications.

Key capabilities:
- Capability extension composition (`compose_extension_into_root`, `merge_extension_object`)
  prior to directional slicing, seamlessly merging extensions (e.g. discounts, fulfillment)
- Directional Request & Response model slicing (`CreateRequest`, `UpdateRequest`, etc.)
- Dynamic container capability inspection (`{op}_request`/`{op}_response`) and routing
- Transitive `$ref` reachability graph calculation with canonical URL resolution for down-scoping
- Two-pass `$defs` hoisting with `<Parent><Def>` namespacing, eliminating collision race conditions
- Synthesizes polymorphic `discriminator` mappings from `allOf` + `if`/`then` conditionals
- Distributes properties across bare `anyOf` branches (e.g. `ValueConstraint`)
- Zero domain hardcoding: schema-driven `x-ucp-path` routing and `x-ucp-lifecycle` action synthesis
- Projects normative REST operations (`POST`, `GET`, `PUT`) with standard UCP headers and RFC 9421 security
- Supports declarative `x-ucp-path` overrides and RFC 8615 well-known discovery (`GET /.well-known/ucp`)
- Provides declarative `--check` mode to enforce zero drift in CI
- Public library ergonomics (`OpenApiExportOptions` alias, safe error typing, CLI exit codes)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant