Documentation
¶
Overview ¶
Package sessionregistry defines the immutable registration and authenticated conversation identity consumed by the session registry. The live registry lifecycle is deliberately separate so transports and protocol bridges can share this security boundary without learning workspace paths or secrets.
Index ¶
- Variables
- type ApprovalSnapshot
- type AttachMode
- type AttachRequest
- type Attachment
- func (a *Attachment) AcceptedOutputModes(reference TurnRef) ([]string, error)
- func (a *Attachment) BeginInterrupt(ctx context.Context, reference TurnRef) (claim InterruptClaim, resultErr error)
- func (a *Attachment) BeginProjectionRejection(ctx context.Context, reference TurnRef) (ProjectionRejectionClaim, error)
- func (a *Attachment) Close()
- func (a *Attachment) Cursor() Cursor
- func (a *Attachment) Generation() sessionstore.Generation
- func (a *Attachment) Interrupt(ctx context.Context, reference TurnRef) error
- func (a *Attachment) Next(ctx context.Context) (StreamItem, error)
- func (a *Attachment) ProjectionCurrent(item EventItem) bool
- func (a *Attachment) ProjectionProgress(cursor Cursor) error
- func (a *Attachment) Respond(ctx context.Context, request RespondRequest) (resultErr error)
- func (a *Attachment) RespondElicitation(ctx context.Context, request RespondElicitationRequest) (resultErr error)
- func (a *Attachment) Snapshot() Snapshot
- func (a *Attachment) SnapshotBound() int64
- func (a *Attachment) SnapshotWithBound() (Snapshot, int64)
- func (a *Attachment) SnapshotWithinBound(admittedBound int64) (snapshot Snapshot, actualBound int64, ok bool)
- func (a *Attachment) StartPreparedTurn(ctx context.Context, prepared *PreparedTurn) (result TurnRef, resultErr error)
- func (a *Attachment) StartTurn(ctx context.Context, request StartTurnRequest) (TurnRef, error)
- func (a *Attachment) State() AttachmentState
- func (a *Attachment) Steer(ctx context.Context, request SteerRequest) (resultErr error)
- func (a *Attachment) WaitNext(ctx context.Context) (int, error)
- type AttachmentState
- type Config
- type ControlMode
- type ConversationRef
- type Cursor
- type Descriptor
- type ElicitationSnapshot
- type EnvironmentProvider
- type EventItem
- type ExecutionOperation
- type ExecutionOutcome
- type ExecutionPermit
- type ExecutionPolicy
- type ExecutionRequest
- type ExecutionResult
- type ExpiryKind
- type FileReferencePolicy
- type FileReferencePolicyFunc
- type GapItem
- type GapReason
- type InterruptClaim
- type Phase
- type PreparedTurn
- type Principal
- type ProjectionRejectionClaim
- type Registration
- func (r *Registration) DeriveKey(principal Principal, conversation ConversationRef) (sessionstore.Key, error)
- func (r *Registration) Descriptor() Descriptor
- func (r Registration) Format(state fmt.State, _ rune)
- func (r Registration) GoString() string
- func (r Registration) MarshalJSON() ([]byte, error)
- func (r Registration) String() string
- type RegistrationSpec
- type Registry
- func (r *Registry) Attach(ctx context.Context, request AttachRequest) (attachment *Attachment, resultErr error)
- func (r *Registry) Capabilities() (agent.Caps, bool)
- func (r *Registry) ClaimConsumer(name string) (func(), error)
- func (r *Registry) ClaimExpiryHandler(name string, handler func(TurnExpiry)) (func(), error)
- func (r *Registry) Close(ctx context.Context) error
- func (r *Registry) ControlTimeout() time.Duration
- func (r *Registry) Descriptor() Descriptor
- func (r *Registry) DurableResumeEnabled() bool
- func (r *Registry) Key(principal Principal, conversation ConversationRef) (sessionstore.Key, error)
- func (r *Registry) LifecycleDispatcher() *lifecycle.Dispatcher
- func (r *Registry) MaxReplayEventBytes() int
- func (r *Registry) MaxSnapshotBytes() int64
- func (r *Registry) PrepareTurn(ctx context.Context, principal Principal, conversation ConversationRef, ...) (*PreparedTurn, error)
- func (r *Registry) Probe(ctx context.Context) (agent.Manifest, error)
- func (r *Registry) SessionLimit() int
- func (r *Registry) Stats() RegistryStats
- type RegistryStats
- type RespondElicitationRequest
- type RespondRequest
- type SecretEnv
- type Snapshot
- type StartTurnRequest
- type SteerRequest
- type StreamItem
- type TerminalClaim
- type TerminalOutcome
- type TurnExpiry
- type TurnID
- type TurnRef
- type TurnSnapshot
- type WorkspaceBinding
- type WorkspaceCoordinator
- type WorkspaceLease
- type WorkspaceLeaseProvider
- type WorkspaceLeaseRequest
- type WorkspaceRequest
- type WorkspaceSpec
Constants ¶
This section is empty.
Variables ¶
var ( // ErrExecutionDenied is the sanitized result of policy rejection, failure, a // nil permit, or a policy panic. Driver side effects never begin after it. ErrExecutionDenied = errors.New("session execution denied") // ErrUsageRejected means a turn's cumulative Usage snapshot was malformed, // regressed, or rejected by its active execution permit. ErrUsageRejected = errors.New("session cumulative usage rejected") )
var ( // ErrInvalidRegistration means a RegistrationSpec is incomplete or unsafe. ErrInvalidRegistration = errors.New("sessionregistry: invalid registration") // ErrInvalidPrincipal means an authenticated owner or tenant is invalid. ErrInvalidPrincipal = errors.New("sessionregistry: invalid principal") // ErrInvalidConversation means a conversation reference is invalid. ErrInvalidConversation = errors.New("sessionregistry: invalid conversation") // ErrInvalidEnvironment means a subprocess environment entry is malformed. ErrInvalidEnvironment = errors.New("sessionregistry: invalid environment") // panicked, or returned an invalid environment. The sentinel deliberately has // no provider error or panic payload because those values may contain secrets. ErrEnvironmentUnavailable = errors.New("sessionregistry: environment unavailable") )
var ( ErrInvalidConfig = errors.New("invalid session registry configuration") ErrInvalidAttach = errors.New("invalid session attachment") ErrInvalidExpiryHandler = errors.New("invalid session registry expiry handler") ErrLiveSession = errors.New("live session already exists") ErrConsumerClaimed = errors.New("session registry consumer already claimed") ErrExpiryHandlerClaimed = errors.New("session registry expiry handler already claimed") )
var ( ErrClosed = errors.New("session registry closed") ErrCapacity = errors.New("session registry capacity reached") ErrNoLiveSession = errors.New("no live session") ErrGenerationChanged = errors.New("session generation changed") ErrControlled = errors.New("session already has a controller") ErrControllerStale = errors.New("session controller superseded") ErrCheckpointAmbiguous = errors.New("session checkpoint is not safely resumable") ErrTurnActive = errors.New("session turn already active") ErrTurnNotFound = errors.New("session turn not found") ErrTurnIDConflict = errors.New("session turn id reused with different input") ErrTurnHistoryFull = errors.New("session turn id history reached its limit") ErrInvalidTurnInput = errors.New("session turn input is not JSON-compatible") ErrApprovalNotFound = errors.New("session approval not found") ErrInvalidDecision = errors.New("invalid session approval decision") // ErrDeliveryAmbiguous means a driver-facing control call returned after it // may already have accepted the command. Callers must not retry the command // against a successor session: doing so could duplicate agent side effects. ErrDeliveryAmbiguous = errors.New("session command delivery outcome is ambiguous") ErrSessionEnded = errors.New("session ended") ErrInvalidCursor = errors.New("invalid session event cursor") ErrEventTooLarge = errors.New("session event exceeds ring byte budget") ErrReplayCapacity = errors.New("session registry replay byte budget exhausted") ErrTerminalOutcomeConflict = errors.New("session terminal outcome conflicts with an earlier completion") ErrInvalidTerminalOutcome = errors.New("invalid session terminal outcome") ErrEndedReplayReadOnly = errors.New("ended session replay is read-only") )
var ( // or release a valid binding. Provider error text is deliberately hidden: it // may contain host paths, container identifiers, or backend details. ErrWorkspaceUnavailable = errors.New("session workspace unavailable") // claim its resolved workspace. No driver side effect occurs before the claim. ErrWorkspaceLeaseUnavailable = errors.New("session workspace lease unavailable") )
var (
ErrDecisionConflict = errors.New("approval decision conflicts with an earlier delivery")
)
var ( // ErrFileReferenceRejected is deliberately payload-free. It covers the safe // default, structural failures, provider errors, panics, and invalid provider // behavior without disclosing an inbound URL or provider diagnostics. ErrFileReferenceRejected = errors.New("sessionregistry: file reference rejected") )
Functions ¶
This section is empty.
Types ¶
type ApprovalSnapshot ¶
type AttachMode ¶
type AttachMode uint8
AttachMode controls whether Attach may create or resume a live process.
const ( AttachAuto AttachMode = iota + 1 AttachExisting // AttachFresh deliberately discards resumable continuity and therefore // requires mutable Control; an observer must never create this state change. AttachFresh // AttachResume requires an existing live session or a clean durable // checkpoint. Unlike Auto it never opens a blank successor when continuity is // unavailable. AttachResume )
type AttachRequest ¶
type AttachRequest struct {
Principal Principal
Conversation ConversationRef
Mode AttachMode
Control ControlMode
ControllerID string
ExpectedGeneration sessionstore.Generation
After Cursor
// AfterLatest starts observation at the ring tail as part of the attachment
// linearization point. It is mutually exclusive with an explicit After cursor.
AfterLatest bool
// WaitForControl makes a Control attachment wait, with ctx cancellation, for
// a different controller to release or retire the conversation. It is useful
// for protocol bridges which serialize separate tasks on one conversation;
// Takeover remains the explicit epoch-fencing operation.
WaitForControl bool
}
type Attachment ¶
type Attachment struct {
// contains filtered or unexported fields
}
Attachment is a generation-scoped view of a Registry entry. Close detaches only this view; the Registry retains the process while a turn/approval or another attachment still needs it.
func (*Attachment) AcceptedOutputModes ¶
func (a *Attachment) AcceptedOutputModes(reference TurnRef) ([]string, error)
AcceptedOutputModes returns the immutable per-request output contract most recently delivered for the exact active turn. Empty means Manifest defaults.
func (*Attachment) BeginInterrupt ¶
func (a *Attachment) BeginInterrupt(ctx context.Context, reference TurnRef) (claim InterruptClaim, resultErr error)
BeginInterrupt claims terminal ownership of reference and atomically marks its exact session generation closing. Once this method returns successfully, neither Existing nor Auto attachment can enter that generation; Auto waits for Complete to finish retirement before it may open a successor.
The caller must invoke Complete on every successful claim, even when its protocol publication fails or its request context is canceled.
func (*Attachment) BeginProjectionRejection ¶
func (a *Attachment) BeginProjectionRejection( ctx context.Context, reference TurnRef, ) (ProjectionRejectionClaim, error)
BeginProjectionRejection atomically makes the exact session generation unavailable after its output violates a protocol projection contract. If the turn is still active, the returned claim owns the same token-scoped interrupt path as BeginInterrupt. If Done has already won terminal ownership, the claim instead owns (or joins) an unprojected terminal settlement and never calls the driver's InterruptTurn method for the completed token.
The caller must invoke Complete on every successful claim, even when failure publication or its request context fails. A projection rejection is a fail-closed registry invariant: if an injected execution policy prevents the ordinary interrupt path, the exact generation is still retired without delivering an unfenced control call to the driver.
func (*Attachment) Close ¶
func (a *Attachment) Close()
func (*Attachment) Cursor ¶
func (a *Attachment) Cursor() Cursor
Cursor returns the next-read position accepted atomically by Attach. A raw reattach protocol includes this value in its welcome frame so a client which disconnects before the first event can reconnect without repeating AfterLatest and silently skipping events produced in between.
func (*Attachment) Generation ¶
func (a *Attachment) Generation() sessionstore.Generation
func (*Attachment) Interrupt ¶
func (a *Attachment) Interrupt(ctx context.Context, reference TurnRef) error
Interrupt performs BeginInterrupt and Complete without an intervening protocol publication. Callers which need cancellation publication ordering should use the two-phase API directly.
func (*Attachment) Next ¶
func (a *Attachment) Next(ctx context.Context) (StreamItem, error)
Next returns the next event, an explicit replay gap, or a terminal error. It is pull-based: a slow observer creates no goroutine and never blocks the sole session pump.
func (*Attachment) ProjectionCurrent ¶
func (a *Attachment) ProjectionCurrent(item EventItem) bool
ProjectionCurrent reports whether an EventItem is still meaningful at the projection boundary. Immutable output remains current once appended, except for Approval: a decision, interrupt, expiry, or terminal can resolve it while the item is waiting behind output admission. Projectors must not expose that stale approval as a new actionable prompt.
func (*Attachment) ProjectionProgress ¶
func (a *Attachment) ProjectionProgress(cursor Cursor) error
ProjectionProgress records that this controller successfully published all events through cursor to its protocol boundary. Progress is generation- and controller-epoch-fenced and strictly monotonic: replaying an old cursor cannot keep approval or terminal deadlines alive indefinitely.
Pending deadlines are measured from useful ordered progress, not merely from the moment the driver queued an event. This prevents a bounded protocol-output backlog from consuming the human approval window or the terminal settlement window before either event can be observed. With no successful projector the original absolute deadline still expires fail-closed.
func (*Attachment) Respond ¶
func (a *Attachment) Respond(ctx context.Context, request RespondRequest) (resultErr error)
func (*Attachment) RespondElicitation ¶
func (a *Attachment) RespondElicitation(ctx context.Context, request RespondElicitationRequest) (resultErr error)
RespondElicitation settles the one ordinary-input request on an exact turn. The turn token never crosses the Registry boundary, and the turn control gate serializes response, expiry, steering, approval, and interrupt delivery.
func (*Attachment) Snapshot ¶
func (a *Attachment) Snapshot() Snapshot
func (*Attachment) SnapshotBound ¶
func (a *Attachment) SnapshotBound() int64
SnapshotBound returns an allocation-free conservative bound for the current Snapshot's JSON-compatible protocol encoding. The bound is only a point-in-time observation: callers which perform admission before allocating the snapshot must confirm it with SnapshotWithinBound.
func (*Attachment) SnapshotWithBound ¶
func (a *Attachment) SnapshotWithBound() (Snapshot, int64)
SnapshotWithBound returns one independent snapshot and a conservative bound for its JSON-compatible protocol encoding, both derived under the same entry lock. Callers which must bound even the first snapshot copy should instead use SnapshotBound followed by SnapshotWithinBound after admission.
func (*Attachment) SnapshotWithinBound ¶
func (a *Attachment) SnapshotWithinBound(admittedBound int64) (snapshot Snapshot, actualBound int64, ok bool)
SnapshotWithinBound returns an independent snapshot only when its current conservative encoding bound is no larger than admittedBound. A false result means the snapshot grew after admission; no approval payload is copied, and the caller must release the old admission and retry with actualBound.
func (*Attachment) StartPreparedTurn ¶
func (a *Attachment) StartPreparedTurn(ctx context.Context, prepared *PreparedTurn) (result TurnRef, resultErr error)
StartPreparedTurn durably claims an inflight checkpoint before delivering the exact input snapshot authorized by PrepareTurn to the driver.
func (*Attachment) StartTurn ¶
func (a *Attachment) StartTurn(ctx context.Context, request StartTurnRequest) (TurnRef, error)
StartTurn is the single-call Registry API. It preserves idempotent retries by consulting an already-recorded turn before invoking external policy. A protocol bridge which must durably create its task before driver delivery should instead use PrepareTurn followed by StartPreparedTurn.
func (*Attachment) State ¶
func (a *Attachment) State() AttachmentState
State returns allocation-free lifecycle metadata for this attachment's generation. Use Snapshot only when approval contents are actually needed.
func (*Attachment) Steer ¶
func (a *Attachment) Steer(ctx context.Context, request SteerRequest) (resultErr error)
Steer delivers an ordinary same-turn update without consuming the event stream or opening a successor. Only a running exact generation may be steered; interactions must be answered through their dedicated seams.
func (*Attachment) WaitNext ¶
func (a *Attachment) WaitNext(ctx context.Context) (int, error)
WaitNext reports the encoded size of the next immediately readable event without advancing the cursor or copying/decoding its payload. A zero size means the next item is a gap or terminal condition. Protocol projectors use this readiness barrier to acquire transient-output memory before Next clones a potentially large replay event. The size is advisory if another goroutine consumes the same Attachment concurrently; callers should keep one consumer per attachment, as they already must to preserve projection order.
type AttachmentState ¶
type AttachmentState struct {
Generation sessionstore.Generation
Phase Phase
Latest Cursor
ActiveTurn bool
PendingApprovals int
PendingInput bool
}
AttachmentState is a lightweight view of the state needed for connection lifecycle decisions. Unlike Snapshot it never includes approval payloads or allocates slices, so polling it cannot amplify a large pending approval.
type Config ¶
type Config struct {
Store sessionstore.ResumeStore
DurableResume bool
// WorkspaceCoordinator resolves the immutable local binding used by one
// session generation. Nil selects the Registration's static workspace.
WorkspaceCoordinator WorkspaceCoordinator
// WorkspaceLeaseProvider exclusively fences active turns. Nil selects the
// process-wide local provider, shared across Registry instances.
WorkspaceLeaseProvider WorkspaceLeaseProvider
// ExecutionPolicy adds authoritative external admission/accounting without
// weakening any of the hard limits below. Nil selects the static policy.
ExecutionPolicy ExecutionPolicy
// FileReferencePolicy is the sole opt-in boundary for inbound URL-backed A2A
// File Parts. Nil rejects every URL reference. Core always performs its own
// structural validation before invoking this caller-owned policy; a policy can
// authorize a reference but cannot weaken that validation or mutate the Turn.
FileReferencePolicy FileReferencePolicy
// Lifecycle receives payload-free advisory transitions through a caller-owned
// bounded Dispatcher. The Registry never closes it and observation can never
// alter or delay authoritative state. Nil disables observation.
Lifecycle *lifecycle.Dispatcher
MaxSessions int
RingMaxEvents int
RingMaxBytes int
OpenTimeout time.Duration
ControlTimeout time.Duration
IdleTTL time.Duration
// TurnInactivityTTL bounds a running turn which produces no agent events.
// Approval and elicitation waits are excluded and governed independently by
// their interaction deadlines.
TurnInactivityTTL time.Duration
// MaxTurnDuration is an absolute wall-clock ceiling from successful execution
// policy/workspace admission through terminal Done, including approval waits.
// Time spent waiting for that bounded admission is governed by the caller and
// ControlTimeout. Unlike inactivity timers it is never refreshed by output.
MaxTurnDuration time.Duration
// MaxTurnEvents and MaxTurnEventBytes are cumulative source-admission limits
// for one turn. Ring eviction does not refund them. Done uses the Registry's
// separate bounded terminal reserve and is not charged to these counters.
MaxTurnEvents int
MaxTurnEventBytes int64
ApprovalTTL time.Duration
ElicitationTTL time.Duration
MaxTurnHistory int
MaxApprovalsPerTurn int
MaxPendingApprovalBytes int
MaxDecisionReasonBytes int
ReplayMaxBytes int
// EndedReplayTTL retains the bounded event ring of a successfully opened,
// ended generation so an exact-generation observer can recover events lost
// across a transport disconnect. Retention never keeps the agent process alive.
EndedReplayTTL time.Duration
// MaxEndedGenerations bounds retained generation metadata independently of
// MaxSessions, which counts only live agent processes.
MaxEndedGenerations int
// TerminalSettlementTTL is the maximum time an emitted Done may remain
// unacknowledged by its protocol projector. Expiry fails closed by poisoning
// continuity and retiring the exact generation.
TerminalSettlementTTL time.Duration
}
Config controls the process-local registry. A ResumeStore is a checkpoint fence, not a distributed lease: one NamespaceID may have only one live Registry unless an embedding layer supplies a separate authoritative lease.
type ControlMode ¶
type ControlMode uint8
ControlMode controls whether an attachment may mutate the live session.
const ( Observe ControlMode = iota Control Takeover )
type ConversationRef ¶
type ConversationRef struct {
// contains filtered or unexported fields
}
ConversationRef is the protocol-neutral identity resolved from an A2A request. Owner, tenant, workspace, and registration scope are deliberately not caller-populable fields.
func NewConversationRef ¶
func NewConversationRef(contextID string) (ConversationRef, error)
NewConversationRef validates a context ID without exposing it in errors.
func (ConversationRef) ContextID ¶
func (r ConversationRef) ContextID() string
ContextID returns the protocol conversation identity.
type Cursor ¶
type Cursor struct {
Generation sessionstore.Generation
Seq uint64
}
Cursor identifies the event position within one live session incarnation.
type Descriptor ¶
type Descriptor struct {
NamespaceID string `json:"namespaceId"`
RegistrationID string `json:"registrationId"`
ContinuityID string `json:"continuityId"`
DriverID string `json:"driverId"`
WorkspaceID string `json:"workspaceId"`
}
Descriptor is the complete non-sensitive view of a Registration.
type ElicitationSnapshot ¶
type ElicitationSnapshot struct {
Turn TurnRef
ID string
Cursor Cursor
RequestedAt time.Time
Delivering bool
}
ElicitationSnapshot identifies the one ordinary-input request which currently pauses a turn. Prompt/schema remain in the replay event; the mutable snapshot carries only the bounded identity required for exact continuation.
type EnvironmentProvider ¶
type EnvironmentProvider interface {
ResolveEnvironment(context.Context, Principal) (SecretEnv, error)
}
EnvironmentProvider resolves the environment for an already-authenticated principal during session open. Implementations may read a secret manager or return a static SecretEnv.
Implementations must be safe for concurrent use, check an already-canceled context before doing work, and return promptly after ctx is canceled. They must construct results with NewSecretEnv, return detached state, keep errors payload-free, and must not call back into the Registry. The Registry never closes a provider.
The Registry invokes providers through a fixed-size managed lane. Synchronous panics and non-context provider errors become ErrEnvironmentUnavailable; panic and error payloads are never propagated. A call which ignores ctx does not hold a session generation past Config.OpenTimeout, but it continues to occupy its lane until the implementation actually returns. This bounds goroutine growth instead of starting unbounded replacement calls.
type EventItem ¶
type EventItem struct {
Cursor Cursor
Turn TurnRef
Event agent.Event
// Terminal is a non-forgeable settlement capability on a controller's Done
// delivery. A protocol projector must complete it exactly once: Projected
// makes the staged resume checkpoint clean before admitting a successor;
// Unprojected poisons continuity and retires the exact generation. Observers
// and nonterminal events receive nil.
Terminal TerminalClaim
}
type ExecutionOperation ¶
type ExecutionOperation string
ExecutionOperation identifies one Registry admission boundary.
const ( ExecutionAttach ExecutionOperation = "attach" ExecutionOpen ExecutionOperation = "open" ExecutionStartTurn ExecutionOperation = "start-turn" ExecutionRespond ExecutionOperation = "respond" ExecutionElicit ExecutionOperation = "respond-elicitation" ExecutionSteer ExecutionOperation = "steer" ExecutionInterrupt ExecutionOperation = "interrupt" )
type ExecutionOutcome ¶
type ExecutionOutcome struct {
Result ExecutionResult
Usage agent.Usage
}
ExecutionOutcome completes one permit. Usage is the last successfully accepted cumulative session snapshot for a StartTurn permit, not a sum.
type ExecutionPermit ¶
type ExecutionPermit interface {
ObserveUsage(context.Context, agent.Usage) error
Complete(context.Context, ExecutionOutcome) error
}
ExecutionPermit is the lifetime returned by ExecutionPolicy. ObserveUsage is called serially only for a StartTurn permit and receives cumulative snapshots which must replace, never add to, the prior value. Complete is called exactly once by core with a bounded cleanup context; implementations must nevertheless make it safe and idempotent for concurrent repetition so network retries can use the same implementation. Neither method may call back into the Registry. Panic, error, or a usage rejection fails closed. Core retains its Config hard limits regardless of which policy is injected.
type ExecutionPolicy ¶
type ExecutionPolicy interface {
AdmitExecution(context.Context, ExecutionRequest) (ExecutionPermit, error)
}
ExecutionPolicy admits authoritative Registry operations. Implementations may enforce external quotas, queues, accounting, or fairness. They must be safe for concurrent use, honor ctx, return a distinct non-nil permit for each successful call, and must not call back into the Registry. The Registry never closes the policy. Panic and nil permits fail closed.
Attach permits cover one Attach call; Open permits cover creation of one driver session; Respond and Interrupt permits cover one driver-facing control delivery. A StartTurn permit remains owned by the Registry through approvals until terminal and receives cumulative Usage snapshots.
func NewStaticExecutionPolicy ¶
func NewStaticExecutionPolicy() ExecutionPolicy
NewStaticExecutionPolicy returns the built-in permissive admission layer. Safety remains backed by immutable Registry Config limits (sessions, turn time/events/bytes, approvals, replay, and control timeouts); replacing this policy cannot disable those limits.
type ExecutionRequest ¶
type ExecutionRequest struct {
Operation ExecutionOperation
Registration Descriptor
Principal Principal
Conversation ConversationRef
Generation sessionstore.Generation
Turn TurnRef
ApprovalID string
WorkspaceID string
}
ExecutionRequest is a bounded, payload-free policy input. It intentionally excludes turns, approval decisions, events, environment, resume tokens, and workspace paths. Generation, Turn, ApprovalID, and WorkspaceID are populated only where meaningful for Operation.
type ExecutionResult ¶
type ExecutionResult string
ExecutionResult is the payload-free completion classification reported to a permit. It is not an A2A task state and never enters the wire.
const ( ExecutionSucceeded ExecutionResult = "succeeded" ExecutionFailed ExecutionResult = "failed" ExecutionCanceled ExecutionResult = "canceled" )
type ExpiryKind ¶
type ExpiryKind string
ExpiryKind identifies the fixed Registry governor which terminated a turn. Values are protocol data: callers should compare them with the exported constants instead of depending on free-form terminal text.
const ( ApprovalDeadline ExpiryKind = "approval-deadline" ElicitationDeadline ExpiryKind = "elicitation-deadline" TurnDuration ExpiryKind = "turn-duration" TurnInactivity ExpiryKind = "turn-inactivity" )
type FileReferencePolicy ¶
type FileReferencePolicy interface {
AuthorizeFileReference(context.Context, Principal, agent.Part) error
}
FileReferencePolicy is the explicit opt-in boundary for URL-backed inbound A2A File Parts. Implementations receive an immutable authenticated Principal and a detached Part copy. Mutating or retaining the Part cannot alter the Turn delivered to the driver.
Implementations must be safe for concurrent use, honor ctx, return promptly after cancellation, avoid putting URLs or credentials in errors, and must not call back into the Registry. The Registry never closes a policy.
Core rejects every URL unless a policy is installed. Even with a policy, only bounded, valid absolute HTTP(S) references without userinfo or fragments can reach this callback. The callback therefore grants authority; it does not replace core structural validation or perform fetching on core's behalf.
type FileReferencePolicyFunc ¶
FileReferencePolicyFunc adapts a function to FileReferencePolicy.
func (FileReferencePolicyFunc) AuthorizeFileReference ¶
type GapReason ¶
type GapReason string
const ( GapEvicted GapReason = "evicted" GapGenerationChanged GapReason = "generation-changed" // GapSuperseded advances over an approval which was resolved while waiting // for protocol output admission. It makes the skipped cursor explicit without // resurrecting an actionable prompt. GapSuperseded GapReason = "superseded" )
type InterruptClaim ¶
type InterruptClaim interface {
Complete(context.Context) error
// contains filtered or unexported methods
}
InterruptClaim is an opaque terminal owner for one exact generation-scoped turn. BeginInterrupt atomically makes the generation unavailable before returning it; Complete must then be called to interrupt the driver and publish the registry terminal. Complete is safe to call repeatedly and concurrently.
Keeping this operation two-phase lets a protocol bridge fence the agent turn, publish its own canceled terminal, and only then wait on driver teardown. A claim deliberately exposes no registry key, principal, or resumable token. The unexported marker makes claims non-forgeable and, importantly, prevents a value copy from duplicating its sync.Once terminal owner.
type Phase ¶
type Phase string
const ( PhaseOpening Phase = "opening" PhaseIdle Phase = "idle" PhaseStarting Phase = "starting" PhaseRunning Phase = "running" PhaseAwaitingApproval Phase = "awaiting-approval" PhaseAwaitingInput Phase = "awaiting-input" PhaseInterrupting Phase = "interrupting" PhaseTerminalPending Phase = "terminal-pending" PhaseClosing Phase = "closing" PhaseEnded Phase = "ended" )
type PreparedTurn ¶
type PreparedTurn struct {
// contains filtered or unexported fields
}
PreparedTurn is an opaque, immutable authorization ticket for one exact principal, conversation, turn ID, and cloned input value. PrepareTurn creates it before a protocol task is persisted; StartPreparedTurn consumes that exact snapshot after persistence succeeds, so policy validation and driver delivery cannot observe different inputs.
Callers cannot construct or inspect a valid ticket. A ticket is bound to the Registry which created it and may only be used by an Attachment for the same principal and conversation. Reusing it is safe only as an idempotent retry of the same turn ID.
type Principal ¶
type Principal struct {
// contains filtered or unexported fields
}
Principal is an immutable authenticated owner and authorized tenant. The fields are private so request decoders cannot populate them accidentally; the trusted authentication layer constructs one with NewPrincipal.
func NewPrincipal ¶
NewPrincipal validates a stable authenticated owner and optional authorized tenant. Values are never included in errors.
type ProjectionRejectionClaim ¶
type ProjectionRejectionClaim interface {
Complete(context.Context) error
// contains filtered or unexported methods
}
ProjectionRejectionClaim is an opaque, exactly-once finalizer for rejecting output from one exact generation-scoped turn. BeginProjectionRejection seals the generation before returning. Complete then either interrupts a still-live turn or settles an already-admitted Done as unprojected; it never sends an interrupt for a token which has already completed.
Keeping rejection two-phase lets a protocol bridge publish its own failure after fencing the generation but before waiting for driver teardown or a durable poison checkpoint. Complete must be called for every successful claim and is safe to call repeatedly and concurrently.
type Registration ¶
type Registration struct {
// contains filtered or unexported fields
}
Registration is an immutable driver registration. All fields are private so consumers cannot mutate policy or retrieve its workspace path/environment. Future registry lifecycle code in this package is the sole consumer of those sensitive fields.
func NewRegistration ¶
func NewRegistration(spec RegistrationSpec) (*Registration, error)
NewRegistration validates spec and snapshots its immutable configuration. A nil Environment means an empty overlay. Registration IDs and ContinuityID must remain stable across restarts; bump ContinuityID whenever resuming an old driver token under changed credentials or policy would be unsafe.
func (*Registration) DeriveKey ¶
func (r *Registration) DeriveKey(principal Principal, conversation ConversationRef) (sessionstore.Key, error)
DeriveKey combines immutable registration scope with an authenticated principal and context reference. No caller supplies individual store-key dimensions, and the continuity epoch prevents token reuse after a deliberate registration security-domain change.
func (*Registration) Descriptor ¶
func (r *Registration) Descriptor() Descriptor
Descriptor returns a value-only non-sensitive registration description.
func (Registration) Format ¶
func (r Registration) Format(state fmt.State, _ rune)
Format prevents generic formatting from traversing Registration's private driver, provider, workspace path, profile, or environment state.
func (Registration) GoString ¶
func (r Registration) GoString() string
GoString formats only the non-sensitive Descriptor.
func (Registration) MarshalJSON ¶
func (r Registration) MarshalJSON() ([]byte, error)
MarshalJSON exposes exactly Descriptor and no sensitive registration state.
func (Registration) String ¶
func (r Registration) String() string
String formats only the non-sensitive Descriptor.
type RegistrationSpec ¶
type RegistrationSpec struct {
NamespaceID string
RegistrationID string
ContinuityID string
Driver agent.Driver
Workspace WorkspaceSpec
Profile agent.Profile
Environment EnvironmentProvider
}
RegistrationSpec is the trusted machine-owner input to NewRegistration. Its maps and path are copied into private immutable registration state.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry is the sole owner and event consumer for every live Session in one immutable Registration.
func New ¶
func New(registration *Registration, config Config) (*Registry, error)
New creates an empty Registry for one immutable Registration.
func (*Registry) Attach ¶
func (r *Registry) Attach(ctx context.Context, request AttachRequest) (attachment *Attachment, resultErr error)
Attach attaches to, creates, or resumes the exact logical conversation.
func (*Registry) Capabilities ¶
Capabilities returns the immutable capability snapshot activated by a successful Probe. Protocol assemblies use the boolean to distinguish an all-false Manifest from a Registry which has not yet crossed its Probe boundary; unprobed registries must not expose caller-visible operations based on guessed capabilities.
func (*Registry) ClaimConsumer ¶
ClaimConsumer reserves one process-local projection lane. A protocol bridge which turns replayable registry events into side effects (for example A2A task-store updates) must have a single owner; independent Attachments are observers and would otherwise replay and publish the same event twice. The returned release function is idempotent.
func (*Registry) ClaimExpiryHandler ¶
func (r *Registry) ClaimExpiryHandler(name string, handler func(TurnExpiry)) (func(), error)
ClaimExpiryHandler installs the Registry's single timer-terminal consumer. The handler receives only opaque scope and exact generation/turn/cursor fences; it never receives task identity or user-controlled content.
Calls are serialized on a dedicated bounded worker and never execute on a session pump or timer goroutine. The handler must return promptly and must not call its own release function or Registry.Close: both drain the callback which is presently running and are therefore intentionally non-reentrant. release is idempotent, prevents new handoffs, and waits for every already-accepted callback before returning. A new handler may be claimed after release completes.
func (*Registry) Close ¶
Close drains the registry boundary. It rejects new attachments, cancels opens and control calls, closes each exact session once, and waits until no old process remains mapped. It never closes the injected store or driver.
func (*Registry) ControlTimeout ¶
ControlTimeout returns the immutable driver-control and injected-seam bound selected when the Registry was constructed. Protocol assemblies may use it to reject conflicting endpoint options; it does not expose the mutable Config value or permit reconfiguration of a running Registry.
func (*Registry) Descriptor ¶
func (r *Registry) Descriptor() Descriptor
Descriptor returns the non-sensitive identity of the immutable registration owned by this Registry. Embedding layers use it to verify that discovery and execution are assembled around the same driver without gaining access to the workspace path, environment, profile, or resume state.
func (*Registry) DurableResumeEnabled ¶
DurableResumeEnabled reports the Registry's actual checkpoint policy. It is intentionally distinct from Caps.Resume: a driver may support resume while a particular Registry has no durable store configured.
func (*Registry) Key ¶
func (r *Registry) Key(principal Principal, conversation ConversationRef) (sessionstore.Key, error)
Key derives the opaque storage scope from trusted registration and principal state. It never accepts owner/tenant/workspace/driver dimensions separately.
func (*Registry) LifecycleDispatcher ¶
func (r *Registry) LifecycleDispatcher() *lifecycle.Dispatcher
LifecycleDispatcher returns the caller-owned dispatcher used by this Registry, or nil when observation is disabled. It exists so a higher-level assembly can reject a conflicting observer instead of silently leaving some execution paths unobserved. Callers must not close the returned dispatcher until Registry.Close has completed.
func (*Registry) MaxReplayEventBytes ¶
MaxReplayEventBytes reports the configured upper bound for one encoded agent.Event in the Registry ring. Protocol projectors use it only to verify their own frame limit at assembly time; it exposes no session state.
func (*Registry) MaxSnapshotBytes ¶
MaxSnapshotBytes reports a conservative serialized upper bound for one Registry Snapshot under the configured pending-approval limits. Protocol servers compare it with their frame limit before accepting connections; a reconnect must never discover only after attachment that its authoritative approval snapshot cannot be represented.
func (*Registry) PrepareTurn ¶
func (r *Registry) PrepareTurn( ctx context.Context, principal Principal, conversation ConversationRef, request StartTurnRequest, ) (*PreparedTurn, error)
PrepareTurn takes an ownership-safe snapshot and authorizes every inbound URL reference before a session is opened or a driver side effect can occur. A2A bridges use this phase before persisting SUBMITTED, then pass the returned ticket to StartPreparedTurn only after task persistence succeeds.
func (*Registry) Probe ¶
Probe reports capabilities from the exact immutable driver registration that opens this Registry's sessions. Server assembly uses this instead of probing a second same-ID Driver value whose model, environment, or binary may differ.
func (*Registry) SessionLimit ¶
SessionLimit returns the immutable maximum number of simultaneously mapped live agent sessions. Embedding layers use it to size one-session-per-terminal queues without duplicating Registry configuration or weakening its bound.
func (*Registry) Stats ¶
func (r *Registry) Stats() RegistryStats
Stats returns an approximate point-in-time aggregate. Entries may advance phase while the snapshot is collected, but every field is race-safe and the result owns its map independently of the Registry.
type RegistryStats ¶
type RegistryStats struct {
Closed bool
LiveSessions int
EndedGenerations int
Attachments int
AttachWaiters int
ActiveTurns int
PendingApprovals int
ReplayBytes int64
ReplayLimitBytes int64
ExpiryHandlerClaimed bool
ExpiryCallbacksPending int
ExpiryHandlerPanics uint64
SessionsByPhase map[Phase]int
}
RegistryStats is a bounded, payload-free point-in-time view for embedding metrics and health adapters. It never exposes keys, principals, workspace paths, resume tokens, approval payloads, or event contents.
type RespondElicitationRequest ¶
type RespondElicitationRequest struct {
Turn TurnRef
RequestID string
Response agent.ElicitationResponse
}
RespondElicitationRequest answers one ordinary-input request on the exact active turn. RequestID is the opaque driver identity; the Registry resolves the adapter-owned TurnToken internally so protocol bridges never handle it.
type RespondRequest ¶
type SecretEnv ¶
type SecretEnv struct {
// contains filtered or unexported fields
}
SecretEnv is an immutable, redacted subprocess environment overlay. Values can be copied out only by code in this package when opening a registered session; formatting and JSON serialization never disclose keys or values.
func NewSecretEnv ¶
NewSecretEnv validates and copies values. Subsequent mutations of the input map cannot change the returned environment. Neither invalid keys nor values are included in errors.
func (SecretEnv) Format ¶
Format redacts the environment for every fmt verb, flag, width, and precision.
func (SecretEnv) MarshalJSON ¶
MarshalJSON prevents Registration or provider results from disclosing subprocess credentials through generic JSON logging.
func (*SecretEnv) UnmarshalJSON ¶
UnmarshalJSON refuses a lossy redacted representation. Trusted callers must construct environments explicitly with NewSecretEnv.
type Snapshot ¶
type Snapshot struct {
Generation sessionstore.Generation
Phase Phase
Oldest Cursor
Latest Cursor
Active *TurnSnapshot
Pending []ApprovalSnapshot
Elicitation *ElicitationSnapshot
}
type StartTurnRequest ¶
type SteerRequest ¶
SteerRequest augments one exact running turn without opening a successor. Steering is deliberately unavailable while the turn is paused on approval or elicitation because those states have their own unambiguous continuation.
type StreamItem ¶
type StreamItem interface {
// contains filtered or unexported methods
}
type TerminalClaim ¶
type TerminalClaim interface {
Complete(context.Context, TerminalOutcome) error
// contains filtered or unexported methods
}
TerminalClaim is a non-forgeable, exactly-once settlement capability for a Done event. The first valid outcome wins. Repeating that outcome is idempotent; trying the opposite outcome returns ErrTerminalOutcomeConflict.
Once Complete claims an outcome, finalization is not abandoned when ctx is canceled. Registry checkpoint operations remain bounded by ControlTimeout.
type TerminalOutcome ¶
type TerminalOutcome uint8
TerminalOutcome records whether the protocol boundary durably accepted a terminal event. A terminal checkpoint is deliberately kept non-resumable until this outcome is known.
const ( // TerminalProjected means the protocol boundary accepted the Done event. A // resumable terminal may now advance its checkpoint to clean. TerminalProjected TerminalOutcome = iota + 1 // TerminalUnprojected means the Done event was not accepted. Continuity is // poisoned and the exact live generation is retired. TerminalUnprojected )
type TurnExpiry ¶
type TurnExpiry struct {
Scope sessionstore.Digest
Turn TurnRef
ApprovalID string
ApprovalCursor Cursor
ElicitationID string
ElicitationCursor Cursor
TerminalCursor Cursor
Kind ExpiryKind
}
TurnExpiry is the payload-free identity of a turn terminated by a Registry timer. Scope is the opaque digest of the trusted registration/principal/ conversation key. ApprovalID and ApprovalCursor are populated only for an approval deadline. TerminalCursor identifies the exact failed Done appended before this notification was handed off.
It deliberately contains no task ID, owner, tenant, workspace path, user input, approval payload, resume token, or free-form failure text. Embedding layers may use the opaque scope and exact turn/cursor fences to settle their own durable projection.
type TurnRef ¶
type TurnRef struct {
ID TurnID
Generation sessionstore.Generation
}
TurnRef fences a logical turn to the exact live session incarnation which accepted it.
type TurnSnapshot ¶
type WorkspaceBinding ¶
type WorkspaceBinding struct {
// contains filtered or unexported fields
}
WorkspaceBinding is the immutable result of workspace resolution. ID is a stable non-secret identity suitable for an external lease key; Path is the canonical local path passed to agent.Driver.Open. Generic formatting and JSON serialization expose only ID so accidental logging cannot disclose host layout. Trusted coordinator and lease implementations may call Path.
func NewWorkspaceBinding ¶
func NewWorkspaceBinding(id, path string) (WorkspaceBinding, error)
NewWorkspaceBinding validates and snapshots one resolved local workspace. The path is made absolute and clean at this ownership-transfer boundary.
func (WorkspaceBinding) GoString ¶
func (b WorkspaceBinding) GoString() string
func (WorkspaceBinding) ID ¶
func (b WorkspaceBinding) ID() string
ID returns the stable non-secret identity chosen by the coordinator.
func (WorkspaceBinding) MarshalJSON ¶
func (b WorkspaceBinding) MarshalJSON() ([]byte, error)
MarshalJSON exposes only the stable ID, never the host path.
func (WorkspaceBinding) Path ¶
func (b WorkspaceBinding) Path() string
Path returns the canonical local path. Callers must treat it as sensitive host topology and must not include it in logs, metrics, errors, or wire data.
func (WorkspaceBinding) String ¶
func (b WorkspaceBinding) String() string
type WorkspaceCoordinator ¶
type WorkspaceCoordinator interface {
ResolveWorkspace(context.Context, WorkspaceRequest) (WorkspaceBinding, error)
ReleaseWorkspace(context.Context, WorkspaceBinding) error
}
WorkspaceCoordinator resolves one stable binding before Driver.Open.
Implementations must be safe for concurrent use, honor ctx, and return the same binding ID and path for the same request while the registration's ContinuityID is unchanged. A successful ResolveWorkspace transfers one binding reference to the Registry; ReleaseWorkspace is called exactly once after the session has closed (including open failure). Implementations must not call back into the Registry from either method. The Registry does not close the coordinator itself. A panic is contained and fails the open closed.
func NewStaticWorkspaceCoordinator ¶
func NewStaticWorkspaceCoordinator(spec WorkspaceSpec) (WorkspaceCoordinator, error)
NewStaticWorkspaceCoordinator returns the built-in resolver for a fixed local path. It is concurrency-safe and allocates no per-resolution resources.
type WorkspaceLease ¶
WorkspaceLease is the exclusive active-turn claim returned by a provider. Release must be safe for concurrent and repeated calls, must honor ctx for remote cleanup, and must never call back into the Registry. Core also wraps it with exactly-once ownership. A canceled ctx does not authorize abandoning a process-local lock; implementations should release locally owned state before returning the context error. Panic is contained and retires the session.
type WorkspaceLeaseProvider ¶
type WorkspaceLeaseProvider interface {
AcquireWorkspaceLease(context.Context, WorkspaceLeaseRequest) (WorkspaceLease, error)
}
WorkspaceLeaseProvider acquires an exclusive claim before Session.SendTurn and keeps it through every approval response and interrupt until terminal. It must be safe for concurrent use and honor ctx while waiting. The Registry owns every successfully returned non-nil lease, but never closes the provider. A panic or a nil lease fails closed before driver side effects.
func NewProcessLocalWorkspaceLeaseProvider ¶
func NewProcessLocalWorkspaceLeaseProvider() WorkspaceLeaseProvider
NewProcessLocalWorkspaceLeaseProvider returns an exclusive provider whose lock key is the canonical workspace path. Share one instance across every Registry which may address the same files. It has no goroutines and requires no Close; empty lock records are reclaimed after the final waiter releases.
type WorkspaceLeaseRequest ¶
type WorkspaceLeaseRequest struct {
Registration Descriptor
Principal Principal
Conversation ConversationRef
Turn TurnRef
Binding WorkspaceBinding
}
WorkspaceLeaseRequest identifies one active turn and its resolved binding. It is payload-free and safe to retain for accounting or lock ownership.
type WorkspaceRequest ¶
type WorkspaceRequest struct {
Registration Descriptor
Principal Principal
Conversation ConversationRef
}
WorkspaceRequest is the payload-free identity supplied to a coordinator. Values are immutable snapshots; implementations may retain them. It contains no input, event, approval, environment, resume token, or workspace path.
type WorkspaceSpec ¶
WorkspaceSpec binds a stable, non-secret identity to a local path. ID enters the durable key; Path is canonicalized at registration and is never exposed by Registration or Descriptor.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package registrytest provides hermetic contract harnesses for implementations injected into sessionregistry.
|
Package registrytest provides hermetic contract harnesses for implementations injected into sessionregistry. |