symfonic.agent.transcript_sqlite_reader¶
transcript_sqlite_reader ¶
The native transcript reader over a SQLite checkpoint saver.
The local authority composes it over its own saver; the compatibility factory
composes it over a saver it opens. It lives in the facade layer so both can:
the platform may import the facade, never the reverse. The checkpoint record
it checks is declared in symfonic.core.contracts.conversation_reader.
Rows are the facade's public TranscriptMessage shape, built by the same
pure helper from the same checkpoint channel, so /chats/{id}/transcript
answers what the compatibility facade answered. No facade, provider or engine
is composed; whoever composes the reader owns the saver and its lifetime.
Timestamps keep the facade's semantics: each message carries the ts of the
oldest checkpoint holding its id. The authority records that on its own write
(http_introduced_at), so an authorized read decodes only the row it
authorized. Ids without a record (checkpoints filed before the record existed,
or by another writer) are found by walking the thread's history oldest first
in short pages: saver.lock is held only to fetch a page, decoding happens
off the event loop after release, and the walk stops once every id is found.
SqliteTranscriptReader ¶
Read native-family transcripts the local authority filed.
read_owned reads a checkpoint the authority already authorized for a
verified principal. get_transcript keeps the reader slot's scope-keyed
signature; like the PostgreSQL reader it has no principal, so it answers
only a native-family checkpoint whose tenant, sub-tenant, namespace and
session match, and raises TranscriptReadRefused otherwise. Only a valid
native empty conversation returns []. A scope conversation_owner would
refuse as ambiguous raises the same ConversationRefused before any read.