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/openapiis 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/openapiis 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 Catalog —
SPEC_REGISTRYis aRecord<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 Metadata —
SpecMetadatacarries name, version, description, spec path, owning domain, base path, OpenAPI tags, and an optionaldeprecatedflag. Used to generate API portal indexes and developer documentation landing pages. ApiDomainUnion — 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 Tag —
getSpecsByTag(tag)returns all specs whosetagsarray contains a given tag, enabling cross-cutting views (all specs taggedastronomyorcontracts). - Domain Paths —
getDomainPaths(domain)returns all spec paths for aSPEC_PATHSkey, used by the API portal to build per-domain documentation sections. - Deprecated Spec Tracking —
SpecMetadatacarries an optionaldeprecatedboolean 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 resolvedOpenAPIV3_1.Documentobject.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-mergingpathsand thecomponentssub-maps, deduplicatingtagsby name). Used to produce a combined API reference for the developer portal, where all domain APIs are browsable in one place.listSpecs()— Recursively scansrc/specs/andv2/for.yaml/.ymlfiles 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
validatescript (--domain-only) validates spec files in the recognized domain directories, skipping root-level specs such asmain.yamlandv3.yaml. - Full Validation —
validate:allvalidates every.yaml/.ymlspec undersrc/specs/andv2/in a single pass, used as a CI gate. - OpenAPI 3.1 Structural Checking —
validate.tsis a self-contained validator that field-checks each spec:openapi/infopresence, well-formed paths, response codes, schemas, security schemes, and duplicate operation IDs (a duplicate is an error). - Broken Reference Detection — Detect
$refpointers 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:validateadditionally runs the external@redocly/cli lintoversrc/specs/. - V3 Contract Validation —
validate:v3validatesv3.yamlagainst 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'spathsand 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'scomponents/schemassection. Thetypehandling accounts for OpenAPI 3.1 allowingtypeto be a string array.- Cross-Spec Endpoint Search —
getSpecsByTag(tag)combined withextractEndpointsfinds all endpoints across the registered specs that share a classification tag (e.g. everyastronomy-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 Generation —
generate-docs.tsbuilds 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, andconcordia. - Per-Domain Developer Pages — Each documented domain gets a Redoc page plus
a downloadable copy of its spec; a landing
index.htmllists every domain with a "Getting Started" section. - Live Documentation Server — The
docsscript runsgenerate:docsfollowed bynpx serve docsto 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-leveldocs/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
generatescript runsopenapi-typescriptover every spec to emit TypeScript types intosrc/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, andmain.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:calliopebuildscalliope-api.yamlfrom@calliope/coreZod schemas;generate:oshun-v1-specsbuilds the six<domain>-v1-contracts.yamlfiles plus the BFF contract spec from@oshun/persistencecontracts;generate:v3-specbuildsv3.yamlfrom@oshun/contracts/v3. This keeps each generated spec derived from its canonical Zod source rather than maintained as a diverging artifact. - Typed Client Generation —
generate:oshun-v1-clientsgenerates a typed@<domain>/api-clientpackage per V1 domain, andgenerate:v3-clientsgenerates the four V3 tenant clients — all from the same Zod contracts. - Drift Detection —
drift-check.tsdetects 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:checkfails CI on any drift. - Spec Currency Check Mode — Every generator has a
--checkvariant (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
diffscript 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 Enforcement —
diff:checkfails 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.yamland the BFF contract spec share abearerAuthHTTP-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,JWTformat) security scheme; authenticated operations reference it. - Pagination — The generated V1 specs use a consistent cursor convention
(
LimitParam/CursorParamand aPageInfoblock withnextCursor).main.yamladditionally documents offset-based pagination. - Streaming — Server-Sent Events (
text/event-stream) are documented in the specs that expose streaming endpoints (includingmain.yaml,lilith-api.yaml,isis-api.yaml,hathor-api.yaml,bellona-api.yaml, andsophia-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.