Documentation
¶
Overview ¶
Package contextstate holds the durable context contract. Sessions, checkpoints, commit validation, retention classes, and volume Limits live here.
Map: contracts.go = shape bounds, sentinels, ValidationError, ContentRef, PayloadRecord, Reassemble; ContentRef delegates to contextref for the canonical reference form. checkpoint.go = SourceID through Session. commit.go = CommitRequest and its validators. limits.go = Limits. store.go = MemStore. Rationale: ../docs/history/contextstate.md. Contribution rules: ../AGENTS.md.
Index ¶
- Constants
- Variables
- type BindingRevision
- type Checkpoint
- type CheckpointID
- type CommitRequest
- type ContentRef
- type Limits
- type MemStore
- func (m *MemStore) Checkpoint(req CommitRequest) error
- func (m *MemStore) Get(ref ContentRef) (PayloadRecord, error)
- func (m *MemStore) Put(record PayloadRecord) error
- func (m *MemStore) Revoke(ref ContentRef) error
- func (m *MemStore) Session(id string) (Session, error)
- func (m *MemStore) Status(ref ContentRef) (PayloadRecord, error)
- type PayloadRecord
- type RetentionClass
- type Revision
- type Session
- type SourceEvent
- type SourceID
- type SourceRange
- type ValidationError
Constants ¶
const ( // MaxIdentifierBytes bounds every identifier string. MaxIdentifierBytes = 128 // MaxPayloadReferenceBytes bounds a payload reference string. MaxPayloadReferenceBytes = 256 // MaxSourceRangeEvents bounds a source range's event span. MaxSourceRangeEvents = 100_000 )
Shape bounds pin the FORM of a durable value, not its volume. Volume bounds are caller-owned; see limits.go.
Variables ¶
var ( // ErrInvalidRecord wraps every validation failure. ErrInvalidRecord = errors.New("invalid context record") // ErrSessionNotFound marks a read of an unknown session. ErrSessionNotFound = errors.New("session not found") // ErrStaleRevision marks a commit against a moved revision. ErrStaleRevision = errors.New("stale revision") // ErrStaleBinding marks a commit against a moved binding. ErrStaleBinding = errors.New("stale binding") // ErrCheckpointConflict marks a reused operation key that carries // a different request. ErrCheckpointConflict = errors.New("checkpoint conflict") // ErrPayloadNotFound marks a read of an unknown payload. ErrPayloadNotFound = errors.New("payload not found") // ErrPayloadRevoked marks a Get of a payload MemStore.Revoke marked // revoked. Get denies the content; MemStore.Status still answers. ErrPayloadRevoked = errors.New("payload revoked") // ErrOverLimit marks a commit that breaks a volume bound. ErrOverLimit = errors.New("commit over volume limit") )
Sentinels. ErrInvalidRecord wraps every validation failure; each sentinel has a producer in this package.
Functions ¶
This section is empty.
Types ¶
type BindingRevision ¶
type BindingRevision struct {
Provider string `json:"provider"`
Model string `json:"model"`
Generation uint64 `json:"generation"`
}
BindingRevision names the provider-model pair and its generation.
func (BindingRevision) Validate ¶
func (b BindingRevision) Validate() error
Validate bounds both identifiers and requires a positive generation.
type Checkpoint ¶
type Checkpoint struct {
ID CheckpointID `json:"id"`
Revision Revision `json:"revision"`
Binding BindingRevision `json:"binding"`
ActiveContext []byte `json:"active_context"`
TurnID uint64 `json:"turn_id"`
}
Checkpoint is one committed state of a session.
func (Checkpoint) Validate ¶
func (c Checkpoint) Validate() error
Validate enforces a valid ID, a valid Binding, a non-empty ActiveContext, and a positive TurnID.
type CheckpointID ¶
type CheckpointID struct {
SessionID string `json:"session_id"`
SourceRange SourceRange `json:"source_range"`
Algorithm string `json:"algorithm"`
SchemaVersion uint32 `json:"schema_version"`
IdempotencyKey string `json:"idempotency_key"`
}
CheckpointID identifies one checkpoint within a session.
func (CheckpointID) Validate ¶
func (c CheckpointID) Validate() error
Validate enforces the identifier bounds, a valid same-session SourceRange, an Algorithm bounded at 64 bytes, a positive SchemaVersion, and a bounded IdempotencyKey.
type CommitRequest ¶
type CommitRequest struct {
OperationID string `json:"operation_id"`
SessionID string `json:"session_id"`
Expected Revision `json:"expected"`
ExpectedBinding BindingRevision `json:"expected_binding"`
NewSourceEvents []SourceEvent `json:"new_source_events"`
Payloads []PayloadRecord `json:"payloads,omitempty"`
Checkpoint Checkpoint `json:"checkpoint"`
NewSession uint64 `json:"new_session"`
NewDurable uint64 `json:"new_durable"`
NewSourceSequence uint64 `json:"new_source_sequence"`
NewBinding BindingRevision `json:"new_binding"`
TurnID uint64 `json:"turn_id"`
}
CommitRequest is one atomic session advance: events, payloads, and the new active checkpoint under an idempotent operation key.
func NewCommitRequest ¶
func NewCommitRequest(sessionID string, expected Revision, expectedBinding BindingRevision, events []SourceEvent, payloads []PayloadRecord, checkpoint Checkpoint, newBinding BindingRevision, turnID uint64) (CommitRequest, error)
NewCommitRequest builds one complete request. It sets OperationID from the checkpoint's idempotency key, derives the three new revision fields from expected and the event count, validates, and wraps ErrInvalidRecord on failure.
func (CommitRequest) Validate ¶
func (r CommitRequest) Validate() error
Validate enforces shape only, in this order: identity, revision, events, payloads, checkpoint. Volume bounds live in the store (limits.go, store.go).
type ContentRef ¶
type ContentRef struct {
Ref string `json:"ref"`
Namespace string `json:"namespace"`
SHA256 string `json:"sha256"`
WorkspaceID string `json:"workspace_id"`
SessionID string `json:"session_id"`
SubjectID string `json:"subject_id"`
Size int `json:"size"`
}
ContentRef is the durable address of one shared context blob. Ref is the address a caller hands around; SHA256 is the bare digest the payload checks compare against; Size is the whole-payload byte count. The three owner strings replace the source's Principal.
func NewContentRef ¶
func NewContentRef(namespace string, workspaceID string, sessionID string, subjectID string, chunks ...[]byte) (ContentRef, error)
NewContentRef mints a ContentRef over the concatenation of chunks. It fills the namespace and owner fields, validates the result, and wraps ErrInvalidRecord on failure.
func (ContentRef) Validate ¶
func (r ContentRef) Validate() error
Validate enforces the canonical Ref form, its match with SHA256, the identifier bounds on Namespace and the owner strings, and a non-negative Size. Namespace is caller-owned; no SDK constant is compared against it.
type Limits ¶
Limits is the caller-owned set of volume bounds for one store. A zero field means uncapped, matching contextbudget.Limits. The MemStore enforces these at write time; Validate stays shape-only.
type MemStore ¶
type MemStore struct {
// contains filtered or unexported fields
}
MemStore is the shipped in-memory store: payloads by content address, sessions by id, committed operations by key. Mutex-guarded and safe for concurrent use; built through New. The zero value is not usable.
func (*MemStore) Checkpoint ¶
func (m *MemStore) Checkpoint(req CommitRequest) error
Checkpoint applies one commit atomically. A reused OperationID with an equal request is a no-op success; a different request wraps ErrCheckpointConflict, before any other check. A new key runs req.Validate, the volume bounds, and the stale guards. An unknown session commits only against a zero Expected. A payload under a ref already revoked is skipped, matching Put.
func (*MemStore) Get ¶
func (m *MemStore) Get(ref ContentRef) (PayloadRecord, error)
Get returns a copy of the record stored under ref.Ref. Every error case returns the zero PayloadRecord: an unknown ref wraps ErrPayloadNotFound; a revoked record wraps ErrPayloadRevoked and denies Data. Status is the path for a revoked ref's metadata.
func (*MemStore) Put ¶
func (m *MemStore) Put(record PayloadRecord) error
Put validates record and stores a copy under record.Ref.Ref. Content-addressed, so a repeat Put of equal bytes overwrites in place. A Put under a ref already revoked is a no-op: it returns nil and leaves the stored record, including Revoked == true, untouched.
func (*MemStore) Revoke ¶
func (m *MemStore) Revoke(ref ContentRef) error
Revoke sets Revoked on the stored record under ref.Ref, the only way a caller revokes a record after Put or Checkpoint. An unknown ref wraps ErrPayloadNotFound. A second Revoke on an already-revoked record is a no-op success.
func (*MemStore) Session ¶
Session returns the session's revision, binding, active checkpoint, and a copy of its events. An unknown id wraps ErrSessionNotFound.
func (*MemStore) Status ¶
func (m *MemStore) Status(ref ContentRef) (PayloadRecord, error)
Status returns a copy of the record stored under ref.Ref with Data always cleared, whether or not it is revoked. It never wraps ErrPayloadRevoked: revocation is reported through the returned record's Revoked field. An unknown ref wraps ErrPayloadNotFound.
type PayloadRecord ¶
type PayloadRecord struct {
Ref ContentRef `json:"ref"`
Retention RetentionClass `json:"retention"`
Revoked bool `json:"revoked"`
Data []byte `json:"data,omitempty"`
}
PayloadRecord is one stored payload under its content address.
func Reassemble ¶
func Reassemble(ref ContentRef, retention RetentionClass, chunks ...[]byte) (PayloadRecord, error)
Reassemble concatenates the chunks in order under one ref and returns the record with Data set. It fails closed on a size or digest mismatch. The whole-payload digest is the contract; chunk boundaries are storage granularity.
func (PayloadRecord) Validate ¶
func (p PayloadRecord) Validate() error
Validate enforces a valid Ref, a non-empty Retention, and, when Data is present, a length and a digest that match Ref.
type RetentionClass ¶
type RetentionClass string
RetentionClass labels how long a payload is kept. PayloadRecord accepts any non-empty class, so a caller may define its own.
const ( // RetentionSession keeps a payload for the session's lifetime. RetentionSession RetentionClass = "session" // RetentionCompliance keeps a payload past session deletion. RetentionCompliance RetentionClass = "compliance" )
type Revision ¶
type Revision struct {
Session uint64 `json:"session"`
Durable uint64 `json:"durable"`
Source uint64 `json:"source"`
}
Revision is a session's three counters. It carries no Validate; the commit rules compare it as a whole.
type Session ¶
type Session struct {
Revision Revision `json:"revision"`
Binding BindingRevision `json:"binding"`
Active Checkpoint `json:"active"`
Source []SourceEvent `json:"source"`
}
Session is the read model of one session. It carries no Validate, because every part carries its own.
type SourceEvent ¶
type SourceEvent struct {
ID SourceID `json:"id"`
Kind string `json:"kind"`
Role string `json:"role"`
ToolCallID string `json:"tool_call_id,omitempty"`
PayloadRef string `json:"payload_ref,omitempty"`
Provenance string `json:"provenance"`
RedactionStatus string `json:"redaction_status"`
Size int `json:"size"`
}
SourceEvent is one durable event in a session's source log. PayloadRef stays a bounded string, not a forced canonical form, so app-side key schemes stay legal.
func (SourceEvent) Validate ¶
func (e SourceEvent) Validate() error
Validate bounds the four required text fields at 256 bytes, the two optional fields when set, and rejects a negative Size.
type SourceRange ¶
SourceRange spans events of one session, inclusive of both ends.
func (SourceRange) Validate ¶
func (r SourceRange) Validate() error
Validate enforces one session, an ordered span, and a span under MaxSourceRangeEvents.
type ValidationError ¶
ValidationError names the field that made a record invalid. Match with errors.Is(err, ErrInvalidRecord) through Unwrap.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error renders the sentinel, the field, and the reason.
func (*ValidationError) Unwrap ¶
func (e *ValidationError) Unwrap() error
Unwrap reports the sentinel under every validation failure.