symfonic.services.conversation.identity¶
identity ¶
Session identity: one derivation site, and its inverse.
The legacy engine derived thread_id inline in three places. Consolidating
them is the point of the extraction, but the formula is frozen: it is the
key under which every pre-migration transcript and checkpoint already lives.
The inverse (from_thread_id) is what lets the registry, the reconciler,
and the notification policy answer "whose state is this?" from a bare thread
key read out of a backend.
ScopeLike ¶
Bases: Protocol
Anything carrying a tenant, satisfied by shape.
Deliberately structural: the tenancy scope type lives outside this layer and must not be imported into it (T1.2.1 runtime-service row).
SessionIdentityService ¶
Derives and parses session identities. No state, by design.
for_scope ¶
Derive from an authenticated scope object, read by attribute.
Source code in src/symfonic/services/conversation/identity.py
from_thread_id ¶
Parse a thread key back into its identity.
split(":", 2) on purpose: a session id may legitimately contain
colons (adopters use URLs and composite keys), and only the first two
separators are structural. Splitting greedily would corrupt exactly
the ids an adopter cannot change.
This is a positional parse, not a tenant attribution. For a key the
legacy path wrote under a separator-bearing tenant (which it never
validated), the leading segment is a prefix of the tenant rather than
the tenant, and no parse can tell that key apart from an exempt
colon-bearing session id. Reading and resuming such a thread is
unaffected — its key is unchanged — but naming its tenant is refused:
see :attr:CheckpointRef.owning_tenant and
:func:~symfonic.services.conversation.values.tenant_segment_is_provable.
Pass tenant_id when the caller already knows the tenant (from an
authenticated scope, or from a ref that recorded it). The prefix is
then verified rather than inferred, which is the one way a key with
extra separators can be attributed. A separator-bearing tenant_id
is still refused: such state is quarantined, never re-attributed.