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.

CouchDB document types — catalogue

A single-page catalogue of every CouchDB document type the system uses or plans to use: what it is, who writes it and when, and its key fields. This is the index; the deep schemas, the status model, and the design views live in couchdb.md, and schema evolution is governed by migrations.md. Storage rationale: CouchDB is the primary store (ADR 0007); full transcript bytes never live here, only in S3 (ADR 0014).

Invariants (all types)

Databases

DatabaseHoldsNotes
claude-sessions (default)Session corpus: event, summary, chunk, session_start, meta, schema_versionThe primary store.
app-logs DB (separate)log (operational/app logs)Kept out of the corpus — see app-logging.md / ADR 0018.

Catalogue

Status: exists = written today · planned = designed, not yet wired. The Owner to define column is intentionally left for you to complete (final field set, validation rules, retention).

type_idDBWritten by → whenStatusPurposeOwner to define
eventauto (CouchDB-assigned)claude-sessionsper-event handlers → live, per hook eventexistsOne marker doc per hook event; the per-session activity stream.which events emit a doc; exact per-event marker fields; preview length caps
summarysummary:<sessionId>claude-sessionssession-end (live) / backfill → at session endexistsThe end-of-session rollup; a session is ended iff this exists. source is "live" (hook) or "backfill" (adopted transcript).final rollup field set; end_reason vocabulary; system_checks shape
chunkchunk:<sessionId>:<byte_start>claude-sessionsbackfill (reconstructed) · chunk-flush (live)existsAppend-only byte-faithful slice of the transcript (mid-flight-chunking.md). Both backfill and the live mid-flight chunker emit them via the shared sliceIntoChunks. With couchFullContentChunks on, each chunk also embeds its parsed entries[] (schema_version 2, ADR 0027) via buildChunkEntries.prune policy; map-reduce views over entries[] (speaker-split, per-turn search)
session_startsession_start:<sessionId>claude-sessionssession-start → once, at startplannedA first-class start record so a running session is queryable before any summary exists (feeds the running status + start_meta view).does this replace/duplicate the SessionStart event doc? fields beyond start metadata
metaautoclaude-sessionsenrichment endpoint → any time, append-onlyplannedOut-of-band enrichment attached to a session (host/actor attribution, tags, derived/extracted facts) without mutating existing docs.the enrichment vocabulary; whether feature extraction (urls/repos/PRs) is meta or its own type; who may write it
schema_versionschema_versionclaude-sessionsmigrations → on migrateexistsSingleton recording the applied migration version plus the applied[] history. Written after each step, so an interrupted run stays consistent (migrations.md).
logautoapp-logs DB (separate)webapi/app → on log eventplannedApplication/operational logs, kept out of the session corpus.log schema; levels; retention; which subsystems emit

Candidate future types (not yet committed — flagged for your call): a dedicated feature type for extracted "events of interest" (URLs, repos, PRs, issues, /-commands, models) if those outgrow meta (couchdb.md → planned feature views, actions.mdextract-feature); a subagent sub-transcript record if subagent runs need first-class capture beyond event markers (tools.mdbackfill). Decide whether each is a new type or a shape of meta.


Per-type field sketches

Concise shape only — the authoritative, validated schemas live in couchdb.md and in the shared code types. Fields marked ? are optional; TODO marks something for the owner to finalise.

event

Common fields on every event doc, plus event-specific marker fields.

{
  "type": "event",
  "event": "PostToolUse",          // the hook event name
  "session_id": "<cc uuid>",
  "timestamp": "2026-01-01T00:00:00.000Z",
  "hostname": "…",
  "cwd": "/abs/path"
  // + event-specific marker fields — see couchdb.md "Event-specific additions"
  //   and the full event list in hook-events.md
}

See hook-events.md for every hook event and its input payload; the marker fields we persist per event are a deliberately short subset (full content lives in chunk/S3). TODO (owner): confirm which of the 30 events emit an event doc and their exact marker fields.

summary

{
  "_id": "summary:<sessionId>",
  "type": "summary",
  "event": "SessionEnd",
  "session_id": "<cc uuid>",
  "timestamp": "…", "hostname": "…", "cwd": "/abs/path",
  "end_reason": "user-input | session-limit | unknown",   // TODO: reconcile with CC SessionEnd `reason` vocabulary
  "event_count": 0, "prompt_count": 0, "error_count": 0,
  "tool_counts": { "Bash": 12, "Edit": 5 },
  "transcript_bytes": 0,                                   // size only; content in S3
  "token_usage": { "input": 0, "output": 0, "cacheCreation": 0, "cacheRead": 0, "total": 0, "messages": 0 },
  "system_checks": {},                                     // TODO: define
  "source": "live | backfill",                             // "live" = hook-recorded; "backfill" = adopted transcript
  "backfilled_at": "…"                                     // only on backfilled docs; the real session time stays in `timestamp`
}

chunk

{
  "_id": "chunk:<sessionId>:<byte_start padded to 12>",
  "type": "chunk",
  "session_id": "<cc uuid>",
  "byte_start": 10240, "byte_end": 10752,
  "entry_count": 8,
  "timestamp": "…", "hostname": "…", "cwd": "/abs/path",
  "schema_version": 2,
  // Present only with couchFullContentChunks (schema_version 2); one entry per
  // non-blank line, partitioned 1:1 with the byte slice. See ADR 0027.
  "entries": [
    { "role": "user", "timestamp": "…", "text": "…" },
    { "role": "assistant", "timestamp": "…", "text": "…", "toolUses": [{ "name": "Edit", "id": "tu_1" }] },
    { "role": "tool_result", "toolUseId": "tu_1", "isError": false, "text": "…" }
  ]
}

session_start (planned)

{
  "_id": "session_start:<sessionId>",
  "type": "session_start",
  "session_id": "<cc uuid>",
  "timestamp": "…", "hostname": "…", "cwd": "/abs/path",
  "source": "startup | resume | clear | compact",
  "model": "…",
  "permission_mode": "…"
  // TODO (owner): is this a distinct doc or just the SessionStart `event` doc?
}

meta (planned)

{
  "type": "meta",
  "session_id": "<cc uuid>",
  "timestamp": "…",
  "meta_kind": "TODO",        // e.g. "attribution" | "tag" | "feature" | …
  "data": { /* TODO: per-kind payload */ }
}

schema_version (planned)

{
  "_id": "schema_version",
  "type": "schema_version",
  "version": 1               // TODO: single int vs per-type map
}

log (planned, separate DB)

{
  "type": "log",
  "timestamp": "…",
  "level": "info | warn | error",   // TODO
  "subsystem": "webapi | hook | …", // TODO
  "message": "…",
  "data": { /* TODO */ }
}

Keep this catalogue in step with the code schemas and the design views in couchdb.md; a type or field change is a versioned migration.