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.

16. The webapi is the sole I/O gateway and stability column

Date: 2026-06-18

Status

Accepted. Amended 2026-08-09 — see Amendment.

Context

The system has several backends (CouchDB, S3, Meilisearch) and several consumers (webui, CLI, AI agents, third-party integrations). If each consumer talks to each backend directly, every internal change — a renamed view, a new chunk format, a swapped search engine — breaks every consumer, and there is no single place to enforce shape, abstraction, or (later) auth.

We also want the internals to be free to churn (chunking on/off, S3 present or not, Meilisearch swapped) without breaking the contract consumers rely on.

Decision

The webapi is non-optional and is the single gateway for all application I/O. It is the stability column — the most compatibility-reliable part of the system, whose contract holds even as internals change, break, or toggle.

Consequences

Amendment: the hook is a second writer

2026-08-09.

The exception above describes something narrower than what the code does, and the gap is worth stating plainly rather than leaving a reader to infer that nothing writes around the webapi.

The hook writes to CouchDB and S3 directly. Not metadata handed to the webapi — its own connections, its own writes. All four of its actions:

actionwriteshow
write-event-markerevent docsctx.couch.postDoc
flush-transcript-chunkchunk docsctx.couch.putDoc
write-summarysummary doc + summary.jsonctx.couch.putDoc, ctx.blob.put
upload-blobstranscript.jsonlctx.blob.put

Why

The hook must never block or fail a session, and routing its writes through the webapi would make recording a session depend on the webapi being up. Start Claude Code before the stack, or during a container restart or an upgrade, and the session is lost — silently, because a logging tool that surfaces its own failures is worse than one that drops a record. Writing to the store directly means the writer depends only on the store.

backfill is the contrast that shows this is a deliberate distinction rather than drift: same CLI, same document builders, but it delivers through /api/ingest/* like any other consumer. Backfill is interactive — a failure is visible and the command is re-run. The hook is on the session hot path, where failure must be both invisible and lossless. Different constraints, different path.

What it costs, and what covers it

What still holds

Everything else in the decision. The read path is unchanged — no consumer reads a backend directly. The webui and CLI remain webapi clients with generated clients. The gateway is still the stability column and still the one place to add auth, masking and rate limiting later. The exception is one writer, on one path, for one reason.