Claude Transcripts docs GitHub
Work in progressUnder active development — not tested as ready for use. Breaking changes land without notice, stored data may need to be discarded between revisions, and there is no auth or security model. These docs describe the intended design as much as the current state.

19. OpenAPI spec is the source of truth; clients are generated

Date: 2026-06-18

Status

Accepted (supersedes ADR 0006)

Context

ADR 0006 had the webui import shared workspace types directly and skip OpenAPI client codegen — reasonable when the only consumer was a webui living in the same monorepo.

That assumption no longer holds. Under ADR 0016 the webapi is the single I/O gateway with multiple consumers: the webui, a standalone CLI (Bun + Ink), and — in later tiers — third-party integrations and AI agents. A shared-workspace-types approach only works for consumers that live in the workspace and can import TypeScript source; it doesn't serve a CLI that may ship as a standalone binary, nor external consumers.

Decision

The webapi's OpenAPI spec is the single source of truth for the API contract, and typed clients are generated from it.

Consequences

Amendment: the spec is committed, and compatibility is checked

Date: 2026-08-12

Calling the spec "the single source of truth" while .gitignore called it "a transient build input" was a contradiction, and it had a cost: with nothing in git to compare against, no change could be assessed for whether it broke a consumer.

The spec is therefore committed (openapi.json), and scripts/check-contract.ts compares the working tree's spec against the baseline's, failing on changes that break a consumer generated from the older one.

Committing a generated artefact is only safe if something proves it is still generated — which is exactly the trap this repo already fell into, when packages/webui/src/api/generated.ts spent weeks hand-written under a generated name. CI now regenerates everything and fails on a diff, so a stale committed spec is a build failure rather than a quiet lie.

Two consequences worth stating: