Domain · Features

OpenAPI Domain — Features

The spec registry is the central catalog of every REST API in the Oshun platform.

7sections10 minread

On this page
Supporting documentation. This domain also carries 3 operational supporting docs under docs/domains/openapi/ (API notes, ADRs, deep topic guides) — reconciled here by linking, kept beside the code as supporting material rather than a second canonical source (§2, §13).

@oshun/openapi is the centralized OpenAPI specification management library for all Oshun REST APIs. It provides spec loading, validation, registry management, endpoint and schema extraction utilities, TypeScript type generation, breaking change detection, spec-to-type drift detection, generation of specs and typed clients from canonical Zod contracts, and documentation generation. Rather than each domain team maintaining isolated OpenAPI YAML files with no shared tooling, all domain API contracts live here, validated against OpenAPI 3.1, and distributed to consumers as generated TypeScript types and typed clients. This makes API documentation, breaking change detection, and type generation consistent across the entire platform. OpenAPI is the industry standard machine-readable format for describing REST APIs — it enables automatic client generation, interactive documentation, and contract testing. @oshun/openapi is a build-time / CI tooling library; it is not loaded by production services at runtime.


@oshun/openapi owns REST specification quality for the entire platform. Product endpoint behavior — what each endpoint actually does — lives in the owning domain's feature files and implementation packages. The boundary is deliberate: this library governs the shape and contract of every API; the domain libraries govern the behavior.

The features below describe the six capability areas: the spec registry that catalogs all APIs, the loader utilities that read and combine specs, the validation pipeline that guards correctness, the endpoint and schema extraction tools that enable programmatic analysis, the documentation generator, and the code generation pipeline that derives TypeScript types and typed clients from specs and Zod contracts.


OpenAPI Spec Registry#

The spec registry is the central catalog of every REST API in the Oshun platform. It answers "what APIs exist, which domain owns them, and where are their spec files?" without anyone having to search the codebase. Tooling such as the developer portal and the documentation generator drive off this catalog rather than hard-coding domain lists.

  • Central Spec CatalogSPEC_REGISTRY is a Record<string, SpecMetadata> that maps every registered API to its metadata: display name, owning domain, spec file path, version, base path, and tags. It currently registers 20 specs.
  • SPEC_PATHS — Typed map (as const) of every spec file's relative path. Type-safe keys prevent path typos in loaders, validators, and generators. Some keys are forward declarations for files not yet on disk.
  • Per-Domain Spec MetadataSpecMetadata carries name, version, description, spec path, owning domain, base path, OpenAPI tags, and an optional deprecated flag. Used to generate API portal indexes and developer documentation landing pages.
  • ApiDomain Union — TypeScript string-literal union (not a runtime enum) of every Oshun API domain: tara, arete, veritas, lilith, yemaya, isis, sophia, hathor, bellona, calliope, nyx, nisaba, metis, v2, v3, oshun-bff, shared. Enables domain-scoped spec listing (e.g. show me all the Nyx APIs).
  • Spec Discovery by TaggetSpecsByTag(tag) returns all specs whose tags array contains a given tag, enabling cross-cutting views (all specs tagged astronomy or contracts).
  • Domain PathsgetDomainPaths(domain) returns all spec paths for a SPEC_PATHS key, used by the API portal to build per-domain documentation sections.
  • Deprecated Spec TrackingSpecMetadata carries an optional deprecated boolean so a spec can be flagged for developer warnings and migration planning. No registry entry currently sets it.

Spec Loading and Management#

Loader utilities handle reading OpenAPI spec files and combining them, so consuming code works with fully resolved spec objects rather than raw file paths. These are the primitives that every script and generator builds on.

  • loadSpec(path) — Asynchronously read a YAML OpenAPI spec file from disk and parse it into a fully resolved OpenAPIV3_1.Document object.
  • loadSpecSync(path) — Synchronous variant for build scripts and code generators that require blocking I/O.
  • mergeSpecs(base, ...specs) — Merge a base document with any number of additional documents into a single unified document (shallow-merging paths and the components sub-maps, deduplicating tags by name). Used to produce a combined API reference for the developer portal, where all domain APIs are browsable in one place.
  • listSpecs() — Recursively scan src/specs/ and v2/ for .yaml/.yml files and return their relative paths, for use by validators and documentation generators processing every spec.
  • getSpecPath(path) — Resolve a relative spec path to an absolute filesystem path, for code generators and validators.

Spec Validation#

Catching spec errors before they reach production prevents clients from receiving inconsistent responses. Validation runs in CI to gate merges. There are two distinct validators: the structural validator (written in-repo) which checks OpenAPI 3.1 field correctness, and the Redocly linter (external tool) which applies additional style and conformance rules.

  • Domain-Only Validation — The validate script (--domain-only) validates spec files in the recognized domain directories, skipping root-level specs such as main.yaml and v3.yaml.
  • Full Validationvalidate:all validates every .yaml/.yml spec under src/specs/ and v2/ in a single pass, used as a CI gate.
  • OpenAPI 3.1 Structural Checkingvalidate.ts is a self-contained validator that field-checks each spec: openapi/info presence, well-formed paths, response codes, schemas, security schemes, and duplicate operation IDs (a duplicate is an error).
  • Broken Reference Detection — Detect $ref pointers of the form #/components/schemas/<Name> referencing schemas that do not exist in the document. Broken refs cause client code generation to fail or produce incorrect types.
  • Redocly Lint — The Nx target openapi:validate additionally runs the external @redocly/cli lint over src/specs/.
  • V3 Contract Validationvalidate:v3 validates v3.yaml against every V3 contract fixture, asserting each fixture validates as both a request body and a response body.

Endpoint and Schema Extraction#

Extraction utilities enable tooling that analyzes API surfaces programmatically — endpoint indexes, coverage reports, and breaking change detectors. Rather than each tool re-implementing its own YAML walker, they all call these shared functions.

  • extractEndpoints(spec) — Walk a document's paths and return a flat list of { method, path, operationId, tags, summary } descriptors, one per operation across the seven HTTP methods. Used by the API portal to build searchable endpoint indexes and by the breaking change detector to compare endpoint lists across versions.
  • extractSchemas(spec) — Return all schema descriptors ({ name, type, description }) from a spec's components/schemas section. The type handling accounts for OpenAPI 3.1 allowing type to be a string array.
  • Cross-Spec Endpoint SearchgetSpecsByTag(tag) combined with extractEndpoints finds all endpoints across the registered specs that share a classification tag (e.g. every astronomy-tagged spec's endpoints).

Documentation Generation#

The docs generation tooling turns OpenAPI YAML specs into human-readable, searchable developer documentation without manual writing effort. It uses Redoc, which produces a rich single-page explorer for any OpenAPI 3.1 document.

  • HTML Documentation Generationgenerate-docs.ts builds a static HTML site from the domain specs using Redoc, with a schema explorer and a shared dark navbar. It documents nine domains: isis, sophia, hathor, bellona, yemaya, lilith, calliope, nyx, and concordia.
  • Per-Domain Developer Pages — Each documented domain gets a Redoc page plus a downloadable copy of its spec; a landing index.html lists every domain with a "Getting Started" section.
  • Live Documentation Server — The docs script runs generate:docs followed by npx serve docs to start a local documentation server for reviewing generated docs during development.
  • Generated Output Location — Documentation is generated to libs/openapi/docs/ with one flat subdirectory per domain (docs/<domain>/index.html + docs/<domain>/openapi.yaml) plus a top-level docs/index.html.

Code Generation Integration#

Type generation ensures TypeScript types in service implementations exactly match API contracts, eliminating runtime errors where implementation assumes a field not in the spec. There are two distinct generation flows: types generated from hand-authored YAML specs, and specs (plus clients) generated from canonical Zod contracts.

  • TypeScript Type Generation — The generate script runs openapi-typescript over every spec to emit TypeScript types into src/generated/. Generated modules: lilith.ts, yemaya.ts, isis.ts, sophia.ts, hathor.ts, bellona.ts, nyx.ts, calliope.ts, concordia.ts, metis.ts, oshun-bff.ts, and main.ts. Domain service code imports these types rather than writing its own.
  • Spec Generation from Zod Contracts — Several specs are generated rather than hand-authored: generate:calliope builds calliope-api.yaml from @calliope/core Zod schemas; generate:oshun-v1-specs builds the six <domain>-v1-contracts.yaml files plus the BFF contract spec from @oshun/persistence contracts; generate:v3-spec builds v3.yaml from @oshun/contracts/v3. This keeps each generated spec derived from its canonical Zod source rather than maintained as a diverging artifact.
  • Typed Client Generationgenerate:oshun-v1-clients generates a typed @<domain>/api-client package per V1 domain, and generate:v3-clients generates the four V3 tenant clients — all from the same Zod contracts.
  • Drift Detectiondrift-check.ts detects when a spec YAML was edited but its generated TypeScript was not regenerated (or vice versa), comparing paths, operation IDs, schemas, and the generated file's source header. drift:check fails CI on any drift.
  • Spec Currency Check Mode — Every generator has a --check variant (generate:calliope:check, generate:oshun-v1-specs:check, generate:oshun-v1-clients:check, generate:v3:check) that rebuilds the artifact and fails CI if the committed file differs, enforcing the single-source-of-truth principle.
  • Breaking Change Detection — The diff script compares the current specs against a base git ref, reporting removed paths, removed operations, parameters that became required or were removed, and removed success responses.
  • Breaking Change Enforcementdiff:check fails with exit code 1 if any breaking changes are detected, preventing teams from accidentally shipping breaking API changes.

Domain API Specifications#

The src/specs/ directory contains the OpenAPI 3.1 YAML specifications for the Oshun domain REST APIs. Each implemented domain has a single <domain>-api.yaml spec file — there are no per-feature spec files such as chat.yaml or projects.yaml. The Oshun V1 domains additionally have a generated <domain>-v1-contracts.yaml. The V2 companion spec lives separately at libs/openapi/v2/companion.yaml.

Specs fall into two authoring categories. Hand-authored specs are edited directly by domain teams and validated by the structural validator. Generated specs must never be edited by hand — they are deterministically regenerated from canonical Zod contracts, and CI's *:check gates will reject any committed artifact that does not match a fresh regeneration.

The hand-authored domain specs (info.title, OpenAPI 3.1.0):

Spec file API Authoring
main.yaml AI Wisdom Platform API (legacy consolidated spec) Hand-authored
lilith/lilith-api.yaml Lilith API — Consciousness Experience Hand-authored
yemaya/yemaya-api.yaml Yemaya API — Creative Studio Hand-authored
isis/isis-api.yaml Isis API — Generative Factory Hand-authored
sophia/sophia-api.yaml Sophia API — Knowledge Engine Hand-authored
hathor/hathor-api.yaml Hathor API — Worldbuilding & Narrative Hand-authored
bellona/bellona-api.yaml Bellona API — Engine Bridge Hand-authored
nyx/nyx-api.yaml Nyx Astronomy API Hand-authored
concordia/concordia-api.yaml Concordia API — Cooperative Mediation Hand-authored
v2/companion.yaml V2 Companion Public API Hand-authored

The generated specs (do not edit by hand; regenerated from canonical Zod contracts and gated by *:check CI scripts):

Spec file API Generated from
calliope/calliope-api.yaml Calliope API — Autonomous AI Artist Platform @calliope/core Zod schemas
v3.yaml Oshun V3 Contract API @oshun/contracts/v3
tara/tara-v1-contracts.yaml Tara V1 Contract API @oshun/persistence Zod contracts
arete/arete-v1-contracts.yaml Arete V1 Contract API @oshun/persistence Zod contracts
veritas/veritas-v1-contracts.yaml Veritas V1 Contract API @oshun/persistence Zod contracts
nyx/nyx-v1-contracts.yaml Nyx V1 Contract API @oshun/persistence Zod contracts
nisaba/nisaba-v1-contracts.yaml Nisaba V1 Contract API @oshun/persistence Zod contracts
metis/metis-v1-contracts.yaml Metis V1 Contract API @oshun/persistence Zod contracts
oshun-bff/oshun-bff-v1-contracts.yaml Oshun BFF V1 Contract API @oshun/persistence Zod contracts

SPEC_REGISTRY registers 20 of these specs with metadata (the isis-api.yaml spec exists on disk but is not registered). The V2 companion spec is consumed by apps/oshun/web V2 handlers and route adapters.

Shared API Conventions#

The generated V1 contract specs share a single, enforced convention because the V1 spec builder emits the same components block into every one. The hand-authored <domain>-api.yaml specs and main.yaml predate that pattern and vary in their conventions.

  • Generated V1 envelope — Every <domain>-v1-contracts.yaml and the BFF contract spec share a bearerAuth HTTP-bearer-JWT security scheme; four reusable parameters (SourceRecordIdParam, LimitParam, CursorParam, IncludeTombstonesParam); six reusable error responses (BadRequest, Unauthorized, Forbidden, NotFound, Conflict, InternalError); and three fixed envelope schemas (ErrorResponse, PageInfo, TombstoneResponse). This is generated, not hand-maintained.
  • Authentication — Most domain specs declare a bearerAuth (HTTP bearer, JWT format) security scheme; authenticated operations reference it.
  • Pagination — The generated V1 specs use a consistent cursor convention (LimitParam/CursorParam and a PageInfo block with nextCursor). main.yaml additionally documents offset-based pagination.
  • Streaming — Server-Sent Events (text/event-stream) are documented in the specs that expose streaming endpoints (including main.yaml, lilith-api.yaml, isis-api.yaml, hathor-api.yaml, bellona-api.yaml, and sophia-api.yaml).

Note: per-spec conventions differ. RFC 7807 application/problem+json error responses appear in concordia-api.yaml; X-RateLimit-* headers appear in nyx-api.yaml; a /health path is defined in main.yaml and sophia-api.yaml. There is no single shared spec file enforcing these platform-wide.

Concordia Mediation API Spec#

libs/openapi/src/specs/concordia/concordia-api.yaml (Phase 179) is a hand-authored OpenAPI 3.1 spec at version 0.1.0, base path /v1/concordia. It defines 11 path entries / 11 operations covering the cooperative mediation REST surface: creating mediation cases, adding parties, collecting private intake, identifying issues, launching preference queries and search runs, retrieving Pareto frontiers, drafting settlements, routing review decisions, executing settlements, and exporting case audits. Its tag set is Cases, Intake, Search, Drafts, Review, Execute, and Audit.