# OpenAPI Domain — Features

> **`@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 Catalog** — `SPEC_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 Metadata** — `SpecMetadata` 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 Tag** — `getSpecsByTag(tag)` returns all specs whose
  `tags` array contains a given tag, enabling cross-cutting views (all specs
  tagged `astronomy` or `contracts`).
- **Domain Paths** — `getDomainPaths(domain)` returns all spec paths for a
  `SPEC_PATHS` key, used by the API portal to build per-domain documentation
  sections.
- **Deprecated Spec Tracking** — `SpecMetadata` 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 Validation** — `validate:all` validates every `.yaml`/`.yml` spec under
  `src/specs/` and `v2/` in a single pass, used as a CI gate.
- **OpenAPI 3.1 Structural Checking** — `validate.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 Validation** — `validate: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 Search** — `getSpecsByTag(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 Generation** — `generate-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 Generation** — `generate: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 Detection** — `drift-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 Enforcement** — `diff: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`.
