access

package
v0.63.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 9, 2026 License: AGPL-3.0 Imports: 30 Imported by: 0

Documentation

Overview

Package access is the authoritative Session and Workspace application service. It owns durable session lookup, session-registry access, workspace materialization, and the policy enforcement point for those resources.

Transport code passes a trusted authz.Authority and typed input; it never receives a sqlc query handle, memory.SessionManager, config.Store, or asset store. Session and Workspace decisions are direct, domain-owned rules; every Agent gate is delegated to the Agent PEP so those rules live in one place.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrForbidden   = errors.New("session access forbidden")
	ErrNotFound    = errors.New("session not found")
	ErrUnavailable = errors.New("session authorization unavailable")
)
View Source
var (
	ErrInvalid  = errors.New("invalid workspace request")
	ErrIsDir    = errors.New("workspace path is a directory")
	ErrBinary   = errors.New("workspace file appears to be binary")
	ErrTooLarge = errors.New("workspace file exceeds read limit")
)
View Source
var ErrSummaryNotFound = errors.New("session summary not found")

Functions

func DetectLanguage

func DetectLanguage(path string) string

func NewAgentSessionAccess

func NewAgentSessionAccess(svc *Service) agent.SessionAccessService

NewAgentSessionAccess adapts Service to agent.Service's narrow session PEP port without making internal/agent import Session access.

Types

type Access

type Access struct {
	// contains filtered or unexported fields
}

Access captures one validated Authority for a single Session/Workspace use case. It holds no evaluation or revision; each decision reads the durable facts it needs when it runs. Do not retain it across use cases.

func (*Access) Archive

func (a *Access) Archive(ctx context.Context, info agentsession.Info) error

Archive persists archival after Delete has authorized the exact session.

func (*Access) Create

func (a *Access) Create(ctx context.Context, userID, agentID, projectID string, kind agentsession.Kind, channel agentsession.Channel) (agentsession.Info, error)

Create creates a user-owned session after one create decision. It uses the registry rather than making a second, transport-owned persistence path.

func (*Access) CreateWorkspacePath

func (a *Access) CreateWorkspacePath(ctx context.Context, in WorkspaceCreateInput) (WorkspaceInfo, error)

func (*Access) Delete

func (a *Access) Delete(ctx context.Context, agentID, sessionID string) (agentsession.Info, error)

Delete resolves a routed session and authorizes archival/deletion.

func (*Access) DeleteWorkspacePath

func (a *Access) DeleteWorkspacePath(ctx context.Context, in WorkspacePathInput) error

func (*Access) Detail

func (a *Access) Detail(ctx context.Context, agentID, sessionID string) (Detail, error)

func (*Access) EnsureRead

func (a *Access) EnsureRead(ctx context.Context, req agentsession.Request) (agentsession.Info, error)

EnsureRead resolves or creates a session through the registry, then authorizes reading it. Channel session pre-resolution uses this to materialize the same durable facts later used by the turn.

func (*Access) EnsureUse

func (a *Access) EnsureUse(ctx context.Context, req agentsession.Request) (agentsession.Info, error)

EnsureUse resolves or creates a session through the registry, then authorizes executing a turn on the exact durable session. Exact-ID creation is allowed only when the caller's trusted Authority is already bound to that entry class (channel/group/worker/system); untrusted transports must use Create/ResolveMain.

func (*Access) GetSummary

func (a *Access) GetSummary(ctx context.Context, agentID, sessionID, summaryID string) (SummaryDetail, error)

GetSummary authorizes the session once, then loads a summary detail within that session's conversation.

func (*Access) List

func (a *Access) List(ctx context.Context, agentID string, opts agentsession.ListOptions) ([]agentsession.Info, error)

List lists the actor's sessions and filters every row through the same evaluation, so the collection can never show a row the actor could not read individually. The converse does not hold for an administrator: the durable query deliberately returns only their own sessions plus this agent's guest sessions, while allowSession still grants an admin Read on any single session they name. Discovery is narrower than access on purpose — an admin's own session list is not a directory of every user's private conversations.

func (*Access) ListContextItems

func (a *Access) ListContextItems(ctx context.Context, in ContextItemListInput) (ContextItemPage, error)

ListContextItems authorizes the session once, then loads materialized context items. Old conversations without ctx_item rows fall back to raw messages.

func (*Access) ListMessages

func (a *Access) ListMessages(ctx context.Context, in MessageListInput) ([]Message, error)

ListMessages authorizes the session once, then loads transcript rows for it.

func (*Access) ListPage

func (a *Access) ListPage(ctx context.Context, agentID string, opts agentsession.ListOptions, limit int) (ListPage, error)

ListPage filters candidates through policy while retaining a cursor into the unfiltered durable result set. The next page therefore cannot be stranded by denied rows that happened to occupy the SQL page.

func (*Access) ListWorkspace

func (a *Access) ListWorkspace(ctx context.Context, in WorkspaceListInput) (WorkspaceInfo, error)

func (*Access) MoveWorkspacePath

func (a *Access) MoveWorkspacePath(ctx context.Context, in WorkspaceMoveInput) (WorkspaceInfo, error)

func (*Access) ProjectRoot

func (a *Access) ProjectRoot(ctx context.Context, agentID string, sessionID *string) (string, error)

ProjectRoot authorizes the referenced session before resolving its project. Callers that merely use a session ID as optional context therefore cannot bypass session visibility through project-scoped features such as skills.

func (*Access) Read

func (a *Access) Read(ctx context.Context, agentID, sessionID string) (agentsession.Info, error)

Read resolves a routed session and authorizes reading it.

func (*Access) ReadMedia added in v0.61.0

func (a *Access) ReadMedia(ctx context.Context, agentID, sessionID, mediaID string) (Media, error)

ReadMedia authorizes the routed session before resolving a media reference that is actually attached to it. Blob failures are unavailable, never an authorization-shaped success.

func (*Access) ReadWorkspacePath

func (a *Access) ReadWorkspacePath(ctx context.Context, in WorkspaceReadInput) (WorkspaceReadResult, error)

func (*Access) ResolveChatChannel added in v0.61.0

func (a *Access) ResolveChatChannel(ctx context.Context, req agentsession.ChannelRequest) (agentsession.Info, error)

ResolveChatChannel resolves the session a chat channel is currently bound to, creating one when the binding has none yet. It is the channel adapters' entry point: unlike EnsureUse it never treats a derived key as a session id, so the chat can rotate onto a successor without changing identity.

func (*Access) ResolveMain

func (a *Access) ResolveMain(ctx context.Context, userID, agentID string) (agentsession.Info, error)

ResolveMain resolves the caller's durable main session in this Access.

func (*Access) RotateChannel added in v0.61.0

func (a *Access) RotateChannel(ctx context.Context, req agentsession.ChannelRequest) (agentsession.Info, error)

RotateChannel archives a chat channel's current session and returns its successor. Both halves are decided here under one evaluation — Delete on the session being retired and Create on the one replacing it — because the successor does not exist yet and the predecessor is chosen by the registry. req.ExpectedSessionID, when set, makes this a compare-and-rotate.

func (*Access) RotateMain added in v0.61.0

func (a *Access) RotateMain(ctx context.Context, userID, agentID, expectedSessionID string) (agentsession.Info, error)

RotateMain archives the caller's current main session and returns its successor. Both halves are decided here under one evaluation — Delete on the session being retired and Create on the one replacing it — because the successor does not exist yet and the predecessor is chosen by the registry: no caller can pre-authorize an Info and hand it to the lifecycle layer. expectedSessionID, when set, makes this a compare-and-rotate.

func (*Access) SessionRunning added in v0.63.0

func (a *Access) SessionRunning(info agentsession.Info) bool

SessionRunning reports process-local turn state for an already-authorized session record. Durable terminal state remains on Info.

func (*Access) UpdateTitle

func (a *Access) UpdateTitle(ctx context.Context, info agentsession.Info, title string) error

UpdateTitle persists a title after Write has authorized the exact session.

func (*Access) UploadWorkspacePath

func (a *Access) UploadWorkspacePath(ctx context.Context, in WorkspaceUploadInput) (WorkspaceUploadResult, error)

func (*Access) Use

func (a *Access) Use(ctx context.Context, agentID, sessionID string) (agentsession.Info, error)

Use resolves a routed session and authorizes a turn on it.

func (*Access) Workspace

func (a *Access) Workspace(ctx context.Context, agentID, sessionID string, action authz.Action) (agentsession.Info, error)

Workspace authorizes a workspace operation under the session's durable facts. It reuses the Session read gate and then applies the direct Workspace rule in this same Access; there is deliberately no second Begin between them.

func (*Access) Write

func (a *Access) Write(ctx context.Context, agentID, sessionID string) (agentsession.Info, error)

Write resolves a routed session and authorizes a metadata mutation.

func (*Access) WriteWorkspacePath

func (a *Access) WriteWorkspacePath(ctx context.Context, in WorkspaceWriteInput) (WorkspaceReadResult, error)

type AgentPromptWorkspace

type AgentPromptWorkspace struct{}

AgentPromptWorkspace adapts the agent workspace materializer to the prompt port.

func (AgentPromptWorkspace) SetupPrincipalWorkspace added in v0.61.0

func (AgentPromptWorkspace) SetupPrincipalWorkspace(stellaHome, userID, groupID, agentID string) (string, string, error)

type AgentServiceManager

type AgentServiceManager interface {
	GetService(agentID string) *agent.Service
	Default() *agent.Service
}

AgentServiceManager is the production pool shape. The adapter keeps the Session access port narrow despite agent.PoolManager returning concrete services from its public API.

type AttachInput

type AttachInput struct {
	Authority authz.Authority
	AgentID   string
	SessionID string
}

type AttachResult

type AttachResult struct {
	Events               <-chan agent.Event
	Cancel               func()
	Live                 bool
	BeforeProtectedEvent func(context.Context) error
}

type ConfigPromptAgentStore

type ConfigPromptAgentStore struct{ Store config.Store }

ConfigPromptAgentStore adapts the deployment config store to the prompt port.

func (ConfigPromptAgentStore) GetPromptAgent

func (s ConfigPromptAgentStore) GetPromptAgent(ctx context.Context, agentID string) (PromptAgent, error)

type ContextItem

type ContextItem struct {
	Ordinal   int
	EventType *string
	Message   *ContextMessage
	Summary   *Summary
}

type ContextItemListInput

type ContextItemListInput struct {
	AgentID   string
	SessionID string
	PageSize  int
	Offset    int
}

type ContextItemPage

type ContextItemPage struct {
	Items         []ContextItem
	Meta          ContextMeta
	NextOffset    int
	HasNextOffset bool
}

type ContextMessage

type ContextMessage struct {
	ID         string
	Seq        int
	Role       string
	EventType  *string
	Content    *string
	Timestamp  time.Time
	TokenCount int
}

type ContextMeta

type ContextMeta struct {
	MessageCount     int
	SourceTokenCount int
	ActiveTokenCount int
	SummaryDepth     int
}

type Detail

type Detail struct {
	Info      agentsession.Info
	AgentName string
}

Detail resolves an authorized session and the non-sensitive display facts the HTTP representation needs. Configuration lookup remains inside the domain service; transports never reach config.Store for a session.

type ListPage

type ListPage struct {
	Sessions   []agentsession.Info
	NextOffset int
	HasMore    bool
}

type MarkViewedInput added in v0.63.0

type MarkViewedInput struct {
	Authority authz.Authority
	AgentID   string
	SessionID string
}

type Media added in v0.61.0

type Media struct {
	ID       string
	MimeType string
	SHA256   [sha256.Size]byte
	Data     []byte
}

Media is one authorized immutable media object ready for an HTTP response. Its digest is retained solely to form an ETag; no storage path is exposed.

type Message

type Message struct {
	ID         string
	Seq        int64
	Role       string
	EventType  string
	Content    string
	Parts      []MessagePart
	TokenCount int64
	CreatedAt  time.Time
}

type MessageListInput

type MessageListInput struct {
	AgentID   string
	SessionID string
	Limit     int
	Skip      int
	After     *string
	Before    *string
	SeqFrom   *int
	SeqTo     *int
}

type MessagePart added in v0.61.0

type MessagePart struct {
	Type     string
	Text     string
	MediaID  string
	MimeType string
}

MessagePart is the transcript-safe projection of an ordered durable part. Image parts intentionally expose only an authenticated media reference.

type Option

type Option func(*Service)

func WithSystemPromptBuilder

func WithSystemPromptBuilder(builder SystemPromptBuilder) Option

type PromptAgent

type PromptAgent struct {
	SystemPrompt string
	Workspace    string
}

PromptAgent is the narrow agent config needed to build a system prompt.

type PromptAgentStore

type PromptAgentStore interface {
	GetPromptAgent(context.Context, string) (PromptAgent, error)
}

type PromptPlugins

type PromptPlugins interface {
	SessionPluginView(context.Context) (pkgplugins.SessionPluginView, error)
	SystemPromptSections(context.Context, pkgplugins.SystemPromptContext) ([]pkgplugins.SystemPromptSection, error)
	ManifestPluginPrompts() []pkgplugins.SystemPromptSection
}

type PromptProjectStore

type PromptProjectStore interface {
	ProjectRoot(context.Context, string, string) (string, error)
}

type PromptWorkspace

type PromptWorkspace interface {
	SetupPrincipalWorkspace(stellaHome, userID, groupID, agentID string) (homeDir, agentDir string, err error)
}

type RuntimeManager

type RuntimeManager interface {
	GetService(agentID string) RuntimeService
	Default() RuntimeService
}

RuntimeManager is the typed runtime lookup port used by session Send/Attach. Tests can provide a deterministic in-memory implementation; production wraps the agent pool with NewRuntimeManager.

func NewRuntimeManager

func NewRuntimeManager(inner AgentServiceManager) RuntimeManager

type RuntimeService

type RuntimeService interface {
	Chat(context.Context, agent.ChatRequest) <-chan agent.Event
	StopSession(context.Context, string) bool
	SubscribeSession(sessionID string) (<-chan agent.Event, func())
	SessionLive(sessionID string) bool
	CompactAuthorizedSession(context.Context, agentsession.Info) (string, error)
}

RuntimeService is the narrow live-turn port Session access needs from the agent runtime. It deliberately excludes session lookup and policy concerns.

type SQLPromptProjectStore

type SQLPromptProjectStore struct {
	// contains filtered or unexported fields
}

SQLPromptProjectStore adapts project persistence to a prompt-only root lookup.

func NewSQLPromptProjectStore

func NewSQLPromptProjectStore(db sqlc.DBTX) *SQLPromptProjectStore

func (*SQLPromptProjectStore) ProjectRoot

func (s *SQLPromptProjectStore) ProjectRoot(ctx context.Context, userID, projectID string) (string, error)

type SendInput

type SendInput struct {
	Authority authz.Authority
	AgentID   string
	SessionID string
	Message   agent.MessageContent
}

type SendResult

type SendResult struct {
	Events     <-chan agent.Event
	PlainReply string
}

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service owns Session/Workspace use cases and their narrow persistence ports. Agent authorization is delegated wholesale to agents so the two domains cannot drift; this service never re-implements an Agent rule.

func NewService

func NewService(mem memory.Provider, db sqlc.DBTX, store config.Store, assets *asset.Store, agents *agentaccess.Service, opts ...Option) (*Service, error)

NewService constructs the only Session/Workspace PEP. The registry remains the canonical lifecycle owner; this service owns its policy-scoped use and routes every Agent decision through the shared Agent PEP.

func (*Service) Attach

func (s *Service) Attach(ctx context.Context, in AttachInput) (AttachResult, error)

Attach authorizes read access and subscribes to an existing live turn. It never starts a turn. The returned guard starts a fresh Access and Read immediately before each non-store event is encoded, so revocation cannot leak the protected source event that triggered the check.

func (*Service) Begin

func (s *Service) Begin(_ context.Context, authority authz.Authority) (*Access, error)

Begin validates the Authority for one Session/Workspace use case. The context is unused today; it stays in the signature so the agent runtime's session PEP port and every transport caller remain identical.

func (*Service) BindRuntimeManager

func (s *Service) BindRuntimeManager(runtime RuntimeManager) error

BindRuntimeManager wires the live runtime port after the pool has been constructed. It is a one-time composition-root bind; handlers must not look up agent services directly.

func (*Service) GetSystemPrompt

func (s *Service) GetSystemPrompt(ctx context.Context, in SystemPromptInput) (string, error)

GetSystemPrompt resolves, authorizes, and builds a session's effective system prompt behind the session PEP.

func (*Service) MarkViewed added in v0.63.0

func (s *Service) MarkViewed(ctx context.Context, in MarkViewedInput) error

MarkViewed clears terminal status for a session the caller can read.

func (*Service) Send

func (s *Service) Send(ctx, runCtx context.Context, in SendInput) (SendResult, error)

Send authorizes and starts exactly one foreground turn. The returned event chunks are not re-authorized by Session access; the single Access evaluation covers the turn initiation, matching the send semantics expected by the UI.

func (*Service) Stop added in v0.63.0

func (s *Service) Stop(ctx context.Context, in StopInput) error

Stop authorizes use of a session and explicitly cancels its active turn. It is idempotent: stopping an idle session succeeds without inventing state.

type StopInput added in v0.63.0

type StopInput struct {
	Authority authz.Authority
	AgentID   string
	SessionID string
}

type Summary

type Summary struct {
	ID                      string
	Kind                    string
	Depth                   int
	Content                 string
	TokenCount              int
	EarliestAt              *time.Time
	LatestAt                *time.Time
	DescendantCount         int
	DescendantTokenCount    int
	SourceMessageTokenCount int
	CreatedAt               time.Time
}

type SummaryDetail

type SummaryDetail struct {
	Summary        Summary
	Children       []Summary
	MessageSeqFrom int
	MessageSeqTo   int
}

type SystemPromptBuildInput

type SystemPromptBuildInput struct {
	Info agentsession.Info
}

type SystemPromptBuilder

type SystemPromptBuilder interface {
	BuildSessionSystemPrompt(context.Context, SystemPromptBuildInput) (string, error)
}

func NewSystemPromptBuilder

func NewSystemPromptBuilder(deps SystemPromptDeps) (SystemPromptBuilder, error)

type SystemPromptDeps

type SystemPromptDeps struct {
	StellaHome string
	HomeDir    string
	Memory     memory.Provider
	Agents     PromptAgentStore
	Projects   PromptProjectStore
	Workspace  PromptWorkspace
	Plugins    PromptPlugins
	SkillStore pkgplugins.SkillStore
	Skills     PromptSkillSectionBuilder
}

type SystemPromptInput

type SystemPromptInput struct {
	Authority authz.Authority
	AgentID   string
	SessionID string
}

SystemPromptInput is the transport-owned identity and route tuple for the session system-prompt read use case.

type Tool added in v0.63.0

type Tool struct {
	// contains filtered or unexported fields
}

Tool exposes read-only session discovery to an agent. Identity always comes from the runtime context; model arguments cannot select another owner or executor.

func NewTool added in v0.63.0

func NewTool(svc *Service) *Tool

func (*Tool) Definition added in v0.63.0

func (t *Tool) Definition() tools.Definition

func (*Tool) Execute added in v0.63.0

func (t *Tool) Execute(ctx context.Context, args map[string]any) (string, error)

type WorkspaceCreateInput

type WorkspaceCreateInput struct {
	AgentID   string
	SessionID string
	Scope     WorkspaceScope
	Path      string
	Content   string
	IsDir     bool
}

type WorkspaceInfo

type WorkspaceInfo struct {
	Root        string   `json:"root"`
	SandboxRoot string   `json:"sandbox_root"`
	Paths       []string `json:"paths"`
	TotalFiles  int      `json:"total_files"`
	TotalDirs   int      `json:"total_dirs"`
	TotalBytes  int64    `json:"total_bytes"`
}

type WorkspaceListInput

type WorkspaceListInput struct {
	AgentID    string
	SessionID  string
	Scope      WorkspaceScope
	ShowHidden bool
	Path       string
	Depth      int
}

type WorkspaceMoveInput

type WorkspaceMoveInput struct {
	AgentID   string
	SessionID string
	Scope     WorkspaceScope
	Path      string
	NewPath   string
}

type WorkspacePathInput

type WorkspacePathInput struct {
	AgentID   string
	SessionID string
	Scope     WorkspaceScope
	Path      string
}

type WorkspaceReadInput

type WorkspaceReadInput struct {
	AgentID   string
	SessionID string
	Scope     WorkspaceScope
	Path      string
	Raw       bool
	// MaxBytes bounds allocation at the authorized file boundary. Zero leaves
	// existing workspace read behavior unchanged.
	MaxBytes int64
}

type WorkspaceReadResult

type WorkspaceReadResult struct {
	Path         string    `json:"path"`
	Content      string    `json:"content,omitempty"`
	Language     string    `json:"language,omitempty"`
	Raw          bool      `json:"-"`
	RawName      string    `json:"-"`
	RawMediaType string    `json:"-"`
	RawContent   []byte    `json:"-"`
	RawModTime   time.Time `json:"-"`
}

type WorkspaceScope

type WorkspaceScope string
const (
	WorkspaceScopeAgent WorkspaceScope = "agent"
	WorkspaceScopeUser  WorkspaceScope = "user"
)

type WorkspaceUploadInput

type WorkspaceUploadInput struct {
	AgentID   string
	SessionID string
	Filename  string
	Reader    io.Reader
	Now       time.Time
}

type WorkspaceUploadResult

type WorkspaceUploadResult struct {
	// Path is the sandbox-view path the agent reads (e.g. /user/assets/... on
	// isolating backends, the absolute host path otherwise).
	Path string `json:"path"`
	// RelativePath is the upload location relative to its workspace root.
	// Combine with Scope to build a workspace file-content read URL.
	RelativePath string `json:"relative_path"`
	// Scope is the workspace root the file was written to.
	Scope WorkspaceScope `json:"scope"`
}

type WorkspaceWriteInput

type WorkspaceWriteInput struct {
	AgentID   string
	SessionID string
	Scope     WorkspaceScope
	Path      string
	Content   string
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL