masking¶
Responsibility¶
Turn a snapshot into players with spans (the token Partition) and a coalition mask into a rendered snapshot (the Absence policy).
Pack masks into bytes and hash them.
Public surface¶
TokenPartitioner(tokens): one player per whitespace token of every message whose role is inRolesOptions.roles(default all; other messages stay present); returnsPlayerSet(player_ids, spans)built bytokens.token_spans(spans carry the message’s speaker); player ids"{snapshot_id}:{turn}:{message}:{token}".MessagePartitioner(messages): one player per non-empty message of the roles inMessagesOptions.roles(an alias ofRolesOptions; default all); span = whole text, label"<role>[/<speaker>] <n>: "plus the firstLABEL_PREVIEW_CHARS(30) characters; ids"{snapshot_id}:{turn}:{message}"(message players).DeletePolicy(delete): removes absent spans together with the whitespace that separated them.PadPolicy(pad): replaces absent spans withplaceholder(default[MASK], plugin optionPadOptions.placeholder).NeutralPolicy(neutral): replaces each absent span withfill_char(default_, plugin optionNeutralOptions.fill_char) repeated to the span’s width.All three take a
PluginContextfirst and read onlyPlayerSet.spans; a player set without spans raises. For spans withsamples(audio players, alignment)audio.render_audioalso edits the message’s firstAudioPart:deletecuts absent samples,padandneutralreplace them with silence of the same length (audio players). Thenaudio.hide_textdrops the text parts ofPlayerSet.hidden_textmessages in every coalition (decision).tokens.py:token_spans(snapshot),render_spans(snapshot, spans, replacements)(replaces character ranges per message,Nonedeletes, text outside every span is kept).MaskBuilder(policy):view(snapshot, players, mask) -> MaskedSnapshot(no copy),render(masked) -> ConversationSnapshot.MaskCodec:packto little-endian bytes,unpack,hash_mask(64-bitblake2bover the packed bytes and bit count, stable across processes).MaskSpace: projects a mask over explainable positions into a full mask; not used by the pipeline.
Data flow¶
In:
ConversationSnapshotandCoalitionMaskfrom domain; thePlayerSetwith spans from the partitioner.Out: one rendered
ConversationSnapshotper coalition, rendered lazily by the pipeline orchestrator as the scheduler consumes jobs.Policies never re-tokenise: any partitioner that fills spans (messages, sentences, custom units) works with every policy and with
vizlabels; underdeletea message player leaves its message with empty text.
Invariants¶
Rendered snapshots keep the turn and message structure and the original whitespace outside deleted spans; only span text changes.
A rendered snapshot gets a new
snapshot_id(rebuilt throughConversationSnapshot.from_turns).Under
delete, different masks can render the same text ("a a a"with one token kept); coalition keys are built from the mask, not the rendered text.
Known issues¶
None open. C09 was fixed in 0.1.17.