Documentation
¶
Overview ¶
Package conversationprojection implements the pure kernel for semantic message identity, never_backend exclusion filtering, deterministic projection/reassertion, anchor/provenance primitives, and immutable projection DTOs at the A-leg/B-leg boundary.
Projection is deterministic and content-preserving for unexcluded messages. This package contains zero stores, writers, locks, reflection, or network/storage I/O.
Index ¶
- Constants
- Variables
- func CanonicalAtomBytes(atom MessageAtomV1) ([]byte, error)
- func CanonicalJSON(raw []byte) ([]byte, error)
- func FilterNeverBackend(call lipapi.Call, snap Snapshot) (lipapi.Call, error)
- func ResolveAnchor(items []lipapi.Item, anchor MessageAnchor) (int, bool, error)
- func VerifyAdaptationPreservesProjection(reasserted, adapted lipapi.Call, snap Snapshot, provenance []OverlayProvenance) error
- type AnchorMissingPolicy
- type ContentKind
- type FallbackEvidence
- type MessageAnchor
- func ComputeCallAnchors(call lipapi.Call) ([]MessageAnchor, error)
- func ComputeItemAnchors(items []lipapi.Item) ([]MessageAnchor, error)
- func ItemAnchorAt(items []lipapi.Item, targetIndex int) (MessageAnchor, error)
- func ResolveAfterIngressTailAnchor(call lipapi.Call, snap Snapshot) (MessageAnchor, error)
- type MessageAtomV1
- type MessageIdentity
- type NormalizedAnnotation
- type NormalizedContent
- type NormalizedExtension
- type NormalizedReasoning
- type Observer
- type Overlay
- type OverlayID
- type OverlayMessage
- type OverlayProvenance
- type Placement
- type PlacementKind
- type ProjectionEvidence
- type ProjectionSummary
- type Reader
- type ReasonCode
- type Snapshot
- type Stage
- type Tag
Constants ¶
const IdentityVersion1 = "v1"
IdentityVersion1 is the pinned prefix for version 1 message identities.
Variables ¶
var ( // ErrNonMessageItem is returned when an item is not a complete message item. ErrNonMessageItem = errors.New("conversationprojection: item is not a complete message item") // ErrEmptyMessage is returned when a message has no content parts. ErrEmptyMessage = errors.New("conversationprojection: message has no content parts") // ErrInvalidRole is returned when a message role is missing or invalid. ErrInvalidRole = errors.New("conversationprojection: invalid message role") // ErrInvalidMessageIdentity is returned when a message identity string is malformed or invalid. ErrInvalidMessageIdentity = errors.New("conversationprojection: invalid message identity") // ErrInvalidMessageAnchor is returned when a message anchor is invalid. ErrInvalidMessageAnchor = errors.New("conversationprojection: invalid message anchor") // ErrAnchorNotFound is returned when an anchor cannot be resolved in a trajectory. ErrAnchorNotFound = errors.New("conversationprojection: anchor not found") // ErrPartialContentNotSupported is returned when an identity or anchor operation targets a partial content part rather than a complete message. ErrPartialContentNotSupported = errors.New("conversationprojection: partial content part identity is not supported") // ErrAnchorMissing is returned when a required fixed anchor cannot be resolved. ErrAnchorMissing = errors.New("conversationprojection: anchor missing") // ErrProjectionFailed is returned when projection cannot produce a valid backend call. ErrProjectionFailed = errors.New("conversationprojection: projection failed") // ErrTerminalUserNotFound is returned when no terminal forwardable user message exists. ErrTerminalUserNotFound = errors.New("conversationprojection: terminal forwardable user message not found") // ErrTerminalNotUser is returned when the terminal forwardable message is not a user message. ErrTerminalNotUser = errors.New("conversationprojection: terminal forwardable message is not user") // ErrOverlayNotFound is returned when an overlay cannot be found for deactivation. ErrOverlayNotFound = errors.New("conversationprojection: overlay not found") // ErrALegNotFound is returned when conversation-view state is requested for an unknown A-leg. ErrALegNotFound = errors.New("conversationprojection: a-leg not found") // ErrInvalidPlacement is returned when a StoredPlacement fails validation. ErrInvalidPlacement = errors.New("conversationprojection: invalid placement") // ErrInvalidSteeringMessage is returned when a StoredMessageV1 fails validation. ErrInvalidSteeringMessage = errors.New("conversationprojection: invalid steering message") // ErrInvalidAnchorMissingPolicy is returned when an AnchorMissingPolicy value is invalid. ErrInvalidAnchorMissingPolicy = errors.New("conversationprojection: invalid anchor missing policy") // ErrInvalidReasonCode is returned when a ReasonCode is missing or exceeds bounds. ErrInvalidReasonCode = errors.New("conversationprojection: invalid reason code") // ErrInvalidOverlayID is returned when an overlay identifier is missing or exceeds bounds. ErrInvalidOverlayID = errors.New("conversationprojection: invalid overlay id") )
Functions ¶
func CanonicalAtomBytes ¶
func CanonicalAtomBytes(atom MessageAtomV1) ([]byte, error)
CanonicalAtomBytes returns the deterministic JSON bytes for atom.
func CanonicalJSON ¶
CanonicalJSON recursively parses raw JSON and re-encodes it with sorted map keys and no insignificant whitespace.
func FilterNeverBackend ¶
FilterNeverBackend returns a deep clone of call with all never_backend messages removed (including dangling item_reference cleanup) but without injecting steering. It is used to derive the filtered baseline for placement-aware reassertion.
func ResolveAnchor ¶
ResolveAnchor locates the 0-based item index matching the anchor in items. If found, returns (index, true, nil). If not found, returns (-1, false, nil).
func VerifyAdaptationPreservesProjection ¶
func VerifyAdaptationPreservesProjection(reasserted, adapted lipapi.Call, snap Snapshot, provenance []OverlayProvenance) error
VerifyAdaptationPreservesProjection checks that adaptedCall still satisfies full projection: - never_backend absent - steering exact count per identity, SlotOrdinal order, and same resolved placement (stable prefix / after anchor) - moved-tail/reordered steering rejects.
Types ¶
type AnchorMissingPolicy ¶
type AnchorMissingPolicy string
AnchorMissingPolicy controls behavior when a fixed anchor disappears.
const ( AnchorStablePrefixFallback AnchorMissingPolicy = "stable_prefix_fallback" AnchorFailClosed AnchorMissingPolicy = "fail_closed" )
func (AnchorMissingPolicy) Validate ¶
func (p AnchorMissingPolicy) Validate() error
type ContentKind ¶
type ContentKind string
ContentKind classifies normalized content parts for semantic identity calculation.
const ( ContentKindText ContentKind = "text" ContentKindImageRef ContentKind = "image_ref" ContentKindFileRef ContentKind = "file_ref" ContentKindVideoRef ContentKind = "video_ref" ContentKindRefusal ContentKind = "refusal" ContentKindReasoning ContentKind = "reasoning" ContentKindSummary ContentKind = "summary" ContentKindAnnotation ContentKind = "annotation" ContentKindAssistantRef ContentKind = "assistant_ref" ContentKindJSON ContentKind = "json" ContentKindToolResult ContentKind = "tool_result" ContentKindExtension ContentKind = "extension" )
type FallbackEvidence ¶
type FallbackEvidence struct {
OverlayID string `json:"overlay_id"`
Anchor MessageAnchor `json:"anchor"`
}
FallbackEvidence records a deterministic stable-prefix fallback for a missing anchor.
type MessageAnchor ¶
type MessageAnchor struct {
Identity MessageIdentity `json:"identity"`
Occurrence uint32 `json:"occurrence"`
}
MessageAnchor pairs a replay-stable message identity with an explicit occurrence ordinal.
func ComputeCallAnchors ¶
func ComputeCallAnchors(call lipapi.Call) ([]MessageAnchor, error)
ComputeCallAnchors computes occurrence-indexed MessageAnchors for all message units in call, supporting both item authority (Items) and legacy authority (Instructions + Messages).
func ComputeItemAnchors ¶
func ComputeItemAnchors(items []lipapi.Item) ([]MessageAnchor, error)
ComputeItemAnchors computes occurrence-indexed MessageAnchors for all message items in items. Non-message items (e.g. tool calls, tool results) are skipped in the resulting anchor slice.
func ItemAnchorAt ¶
func ItemAnchorAt(items []lipapi.Item, targetIndex int) (MessageAnchor, error)
ItemAnchorAt returns the MessageAnchor for the message item at targetIndex in items. If targetIndex is out of range, an error is returned. If the item at targetIndex is not ItemKindMessage, ErrNonMessageItem is returned.
func ResolveAfterIngressTailAnchor ¶
func ResolveAfterIngressTailAnchor(call lipapi.Call, snap Snapshot) (MessageAnchor, error)
ResolveAfterIngressTailAnchor resolves the terminal forwardable user message in call (filtered by snap exclusions) to a MessageAnchor. It rejects if the terminal message is absent, not user, or not safe. It first establishes the concrete original terminal complete message boundary and rejects if that terminal's identity is in snapshot exclusions (never falls back to an earlier forwardable user).
func (MessageAnchor) String ¶
func (a MessageAnchor) String() string
String returns the formatted anchor representation "v1:<hex>#<occurrence>".
func (MessageAnchor) Validate ¶
func (a MessageAnchor) Validate() error
Validate checks that the anchor has a valid v1 identity and a non-zero occurrence ordinal.
type MessageAtomV1 ¶
type MessageAtomV1 struct {
Role lipapi.Role `json:"role"`
Content []NormalizedContent `json:"content"`
}
MessageAtomV1 is the internal representation-neutral projection of a complete message.
func AtomOfItem ¶
func AtomOfItem(item lipapi.Item) (MessageAtomV1, error)
AtomOfItem projects a message item to its normalized MessageAtomV1.
func AtomOfMessage ¶
func AtomOfMessage(msg lipapi.Message) (MessageAtomV1, error)
AtomOfMessage projects a legacy message to its normalized MessageAtomV1.
type MessageIdentity ¶
type MessageIdentity string
MessageIdentity is the versioned replay-stable semantic digest of a complete message. Format: "v1:<64-char lowercase hex sha256>".
func HashAtom ¶
func HashAtom(atom MessageAtomV1) (MessageIdentity, error)
HashAtom returns the versioned MessageIdentity for atom.
func ItemIdentityOf ¶
func ItemIdentityOf(item lipapi.Item) (MessageIdentity, error)
ItemIdentityOf computes the versioned semantic identity for an item.
func MessageIdentityOf ¶
func MessageIdentityOf(msg lipapi.Message) (MessageIdentity, error)
MessageIdentityOf computes the versioned semantic identity for a legacy message.
func ParseMessageIdentity ¶
func ParseMessageIdentity(raw string) (MessageIdentity, error)
ParseMessageIdentity parses and validates a raw identity string.
func (MessageIdentity) Digest ¶
func (id MessageIdentity) Digest() string
Digest returns the lowercase hex hash portion of this identity.
func (MessageIdentity) IsValid ¶
func (id MessageIdentity) IsValid() bool
IsValid reports whether id is a valid v1 message identity.
func (MessageIdentity) String ¶
func (id MessageIdentity) String() string
func (MessageIdentity) Validate ¶
func (id MessageIdentity) Validate() error
Validate checks that id conforms to "v1:<64-char lowercase hex sha256>".
func (MessageIdentity) Version ¶
func (id MessageIdentity) Version() string
Version returns the version prefix of this identity (e.g. "v1").
type NormalizedAnnotation ¶
type NormalizedAnnotation struct {
Type string `json:"type,omitempty"`
Data json.RawMessage `json:"data,omitempty"`
}
NormalizedAnnotation holds deterministic annotation data.
type NormalizedContent ¶
type NormalizedContent struct {
Kind ContentKind `json:"kind"`
Text string `json:"text,omitempty"`
ImageRef string `json:"image_ref,omitempty"`
ImageMIME string `json:"image_mime,omitempty"`
FileRef string `json:"file_ref,omitempty"`
FileData string `json:"file_data,omitempty"`
FileMIME string `json:"file_mime,omitempty"`
FileName string `json:"file_name,omitempty"`
VideoRef string `json:"video_ref,omitempty"`
VideoMIME string `json:"video_mime,omitempty"`
Refusal string `json:"refusal,omitempty"`
Reasoning *NormalizedReasoning `json:"reasoning,omitempty"`
Summary string `json:"summary,omitempty"`
Annotation *NormalizedAnnotation `json:"annotation,omitempty"`
AssistantRef string `json:"assistant_ref,omitempty"`
JSON json.RawMessage `json:"json,omitempty"`
Extension *NormalizedExtension `json:"extension,omitempty"`
}
NormalizedContent is one ordered semantic content fragment in a message atom.
type NormalizedExtension ¶
type NormalizedExtension struct {
Namespace string `json:"namespace,omitempty"`
Type string `json:"type"`
Implementor string `json:"implementor,omitempty"`
Data json.RawMessage `json:"data,omitempty"`
}
NormalizedExtension carries vendor-prefixed custom content parts.
type NormalizedReasoning ¶
type NormalizedReasoning struct {
Dialect string `json:"dialect,omitempty"`
Text string `json:"text,omitempty"`
Signature string `json:"signature,omitempty"`
Opaque json.RawMessage `json:"opaque,omitempty"`
Summary json.RawMessage `json:"summary,omitempty"`
Content json.RawMessage `json:"content,omitempty"`
EncryptedContent json.RawMessage `json:"encrypted_content,omitempty"`
EncryptedContentPresent bool `json:"encrypted_content_present,omitempty"`
}
NormalizedReasoning holds normalized reasoning metadata and payload.
type Observer ¶
type Observer interface {
OnProjection(stage Stage, summary ProjectionSummary)
OnProjectionFailure(stage Stage)
OnAnchorFallback(stage Stage, policy AnchorMissingPolicy)
OnAnchorFailure(policy AnchorMissingPolicy)
}
Observer receives bounded, content-free diagnostics for conversation-view events.
type Overlay ¶
type Overlay struct {
OverlayID string `json:"overlay_id"`
Revision uint64 `json:"revision"`
SlotOrdinal uint64 `json:"slot_ordinal"`
Active bool `json:"active"`
Message OverlayMessage `json:"message"`
Placement Placement `json:"placement"`
AnchorMissingPolicy AnchorMissingPolicy `json:"anchor_missing_policy"`
}
Overlay is the pure immutable per-turn steering record.
type OverlayMessage ¶
OverlayMessage is the model-visible steering payload.
type OverlayProvenance ¶
type OverlayProvenance struct {
OverlayID string `json:"overlay_id"`
Revision uint64 `json:"revision"`
SlotOrdinal uint64 `json:"slot_ordinal"`
ResolvedKind PlacementKind `json:"resolved_kind"`
ResolvedAnchor *MessageAnchor `json:"resolved_anchor,omitempty"`
InjectedIdentity MessageIdentity `json:"injected_identity"`
// Exact injected position for placement-aware reassertion.
InjectedAuthority string `json:"injected_authority"` // "item" or "legacy"
InjectedItemIndex int `json:"injected_item_index,omitempty"` // valid when authority == "item"
InjectedLegacyIsInstruction *bool `json:"injected_legacy_is_instruction,omitempty"`
InjectedLegacyIndex *int `json:"injected_legacy_index,omitempty"`
InjectedTrajectoryIndex int `json:"injected_trajectory_index"`
}
OverlayProvenance is deterministic request-local provenance for one injected overlay. It is derived solely from Snapshot + input call and is used by a later final-reassertion stage to recognize/rebuild/remove projection-owned steering instances without string heuristics. It does not affect MessageIdentityOf values or model-visible content. Injected* fields record the exact trajectory position of the injected copy for placement-aware reassertion without broad identity sweeps.
func (OverlayProvenance) MatchesItem ¶
func (p OverlayProvenance) MatchesItem(item lipapi.Item) bool
MatchesItem reports whether item is the projection-owned copy for this provenance entry.
func (OverlayProvenance) MatchesMessage ¶
func (p OverlayProvenance) MatchesMessage(msg lipapi.Message) bool
MatchesMessage reports whether msg is the projection-owned copy for this provenance entry by semantic identity comparison. It is pure and uses no string-marker heuristics.
type Placement ¶
type Placement struct {
Kind PlacementKind `json:"kind"`
Anchor *MessageAnchor `json:"anchor,omitempty"`
}
Placement describes where an overlay should be injected.
type PlacementKind ¶
type PlacementKind string
PlacementKind enumerates durable steering placement.
const ( PlacementStablePrefix PlacementKind = "stable_prefix" PlacementAfterMessage PlacementKind = "after_message" )
func (PlacementKind) Validate ¶
func (k PlacementKind) Validate() error
type ProjectionEvidence ¶
type ProjectionEvidence struct {
FilteredCount int `json:"filtered_count"`
InjectedCount int `json:"injected_count"`
Fallbacks []FallbackEvidence `json:"fallbacks,omitempty"`
Provenance []OverlayProvenance `json:"provenance,omitempty"`
}
ProjectionEvidence captures bounded diagnostics for a successful projection.
func Project ¶
Project derives the backend-effective call from call and snap. It is pure, deterministic and never mutates the input call. Exclusion is applied first, then steering injection; result is validated.
func Reassert ¶
func Reassert(call lipapi.Call, snap Snapshot, provenance []OverlayProvenance, filteredBaseline lipapi.Call) (lipapi.Call, *ProjectionEvidence, error)
Reassert restores the frozen conversation view after late attempt/candidate/interleaved transforms. It is pure and uses no store read. It removes any reintroduced never_backend messages and ensures each active overlay in snap is present exactly once at its frozen placement (rebuild via Project). It handles late calls that are already based on the projected baseline by stripping existing projection-owned copies (identified via placement-aware provenance) before re-projecting, to avoid duplicate injection. Identity collisions are handled by using exact injected trajectory positions (InjectedTrajectoryIndex / InjectedItemIndex / InjectedLegacy*) plus anchor/slot order, preserving legitimate same role/text messages. If ambiguity remains (multiple identical copies indistinguishable), it fails closed rather than silently deleting. FilteredBaseline is the frozen filtered call (without never_backend, without steering) carried from early projection; when provided it is used to distinguish legitimate user collisions from duplicate steering. If empty, it is derived on the fly.
type ProjectionSummary ¶
type ProjectionSummary struct {
StateRevision uint64 `json:"state_revision"`
FilteredCount int `json:"filtered_count"`
InjectedCount int `json:"injected_count"`
StablePrefixCount int `json:"stable_prefix_count"`
AfterMessageCount int `json:"after_message_count"`
FallbackCount int `json:"fallback_count"`
MaxOverlayRevision uint64 `json:"max_overlay_revision"`
MaxSlotOrdinal uint64 `json:"max_slot_ordinal"`
}
ProjectionSummary is a bounded, content-free diagnostic summary of a projection operation. It contains only counts, revisions, and placement classes (no plaintext, IDs, or digests).
func NewProjectionSummary ¶
func NewProjectionSummary(snap Snapshot, ev *ProjectionEvidence) ProjectionSummary
NewProjectionSummary builds a content-free ProjectionSummary from a snapshot and evidence.
type ReasonCode ¶
type ReasonCode string
ReasonCode is a non-secret identifier for diagnostics.
func (ReasonCode) Validate ¶
func (r ReasonCode) Validate() error
type Snapshot ¶
type Snapshot struct {
StateRevision uint64 `json:"state_revision"`
NeverBackend []Tag `json:"never_backend"`
Steering []Overlay `json:"steering"`
}
Snapshot is the coherent per-turn conversation view.
type Tag ¶
type Tag struct {
Identity MessageIdentity `json:"identity"`
Reason ReasonCode `json:"reason,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
Tag is an A-leg never_backend exclusion record.