access

package
v0.60.1 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: AGPL-3.0 Imports: 25 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")
)
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. Collection visibility and individual visibility therefore cannot drift apart.

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) ReadWorkspacePath

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

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) 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) SetupUserWorkspace

func (AgentPromptWorkspace) SetupUserWorkspace(stellaHome, userID, agentID 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 Message

type Message struct {
	ID         string
	Seq        int64
	Role       string
	EventType  string
	Content    string
	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 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 {
	SetupUserWorkspace(stellaHome, userID, agentID string) (string, 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
	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) Send

func (s *Service) Send(ctx 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.

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 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
}

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:"-"`
}

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 string `json:"path"`
}

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