profile

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: 11 Imported by: 0

Documentation

Overview

Package profile is the application boundary for per-(user, agent) memory: the profile blob, agent soul, hard constraints, reset, and the change history. It composes the memory Provider's ProfileStore/ChangelogReader with the memorywrite transactional helpers and the raw ctx_agent_memory rows, and owns the Agent-access gate and the change-source audit that the HTTP transport used to orchestrate itself.

It lives beside memorywrite (not in package memory) because it reuses memorywrite, and memorywrite imports memory — a service in package memory could not call it without an import cycle. Every use case is Authority-bound: the caller passes a trusted authz.Authority. Agent-specific operations authorize agent access; cross-agent user lists enforce self-or-admin before any read.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrKnowledgeUnavailable reports the knowledge/changelog-page backend is not
	// wired (Provider without the keyset changelog capability) — a 503.
	ErrKnowledgeUnavailable = errors.New("knowledge management not configured")
	// ErrKnowledgeNotFound reports a knowledge item the caller's agent memory does
	// not contain (404).
	ErrKnowledgeNotFound = errors.New("knowledge not found")
	// ErrKnowledgeNotRestorable reports a lifecycle transition that does not apply
	// to the item's current state (404 on edit/delete, 409 on restore).
	ErrKnowledgeNotRestorable = errors.New("knowledge not restorable")
	// ErrKnowledgeDuplicateContent reports a restore blocked by an active item with
	// identical content (409).
	ErrKnowledgeDuplicateContent = errors.New("active knowledge already has this content")
	// ErrKnowledgeRestoreExpired reports a restore past the retention window (410).
	ErrKnowledgeRestoreExpired = errors.New("knowledge restore window expired")
)

Knowledge lifecycle errors, owned by this boundary so the transport maps them without importing the persistence layer. They wrap the memorywrite sentinels so an errors.Is against either matches.

View Source
var (
	// ErrConstraintNotFound reports a delete of a constraint that does not exist (404).
	ErrConstraintNotFound = errors.New("constraint not found")
	// ErrProfileStoreUnavailable reports a Provider without ProfileStore (503).
	ErrProfileStoreUnavailable = errors.New("profile memory store not configured")
	// ErrChangelogReaderUnavailable reports a Provider without ChangelogReader (503).
	ErrChangelogReaderUnavailable = errors.New("memory changelog reader not configured")
)

Typed errors. Agent-gate denials propagate the agentaccess sentinels unchanged so the transport maps them to the same 404/403 as everywhere else.

Functions

This section is empty.

Types

type AgentAuthorizer

type AgentAuthorizer interface {
	Authorize(ctx context.Context, authority authz.Authority, agentID string, action authz.Action) error
}

AgentAuthorizer is the narrow Agent PEP port: it authorizes an action on an agent for a trusted authority. agentaccess.Service satisfies it. Profile operations gate on read access to the agent (the same gate the transport's requireAgentAccess applied), so a user may only touch memory for an agent they can see.

type KnowledgeCursor

type KnowledgeCursor struct {
	Timestamp time.Time
	ID        string
}

KnowledgeCursor is the transport-neutral keyset cursor for a knowledge page.

type KnowledgeItem

type KnowledgeItem struct {
	Fact            memory.Fact
	RemovalSource   string
	DeprecatedAt    *time.Time
	RestoreDeadline *time.Time
	IsRestorable    bool
}

KnowledgeItem is one knowledge row projected for presentation, with its removal metadata for the removed slice.

type KnowledgeManager

type KnowledgeManager interface {
	ListKnowledge(ctx context.Context, in memorywrite.KnowledgeListQuery) (memorywrite.KnowledgePage, error)
	CreateKnowledge(ctx context.Context, in memorywrite.KnowledgeCreateInput) (memory.Fact, error)
	ReplaceKnowledge(ctx context.Context, in memorywrite.KnowledgeReplaceInput) (memory.Fact, error)
	DeprecateKnowledge(ctx context.Context, in memorywrite.KnowledgeDeprecateInput) (memory.Fact, error)
	RestoreKnowledge(ctx context.Context, in memorywrite.KnowledgeRestoreInput) (memorywrite.KnowledgeRestoreResult, error)
	ReadChangelogPage(ctx context.Context, userID string, agentID string, scope string, cursor *memory.ChangelogCursor, limit int) ([]memory.ChangeEntry, error)
}

KnowledgeManager is the narrow persistence port for the user-facing knowledge lifecycle and the keyset changelog projection. *memorywrite.ManagementService satisfies it. Profile is the only caller: every method here is reached through a Service method that has already applied the Agent gate and derived the owner tuple from the trusted Authority, so the manager never sees a caller-supplied owner id.

type KnowledgePage

type KnowledgePage struct {
	Items      []KnowledgeItem
	Total      int64
	HasMore    bool
	NextCursor *KnowledgeCursor
}

KnowledgePage is one deterministic knowledge page with its keyset cursor.

type KnowledgeState

type KnowledgeState string

KnowledgeState selects the active or removed lifecycle slice.

const (
	KnowledgeStateActive  KnowledgeState = "active"
	KnowledgeStateRemoved KnowledgeState = "removed"
)

type Memory

type Memory struct {
	UserID         string
	AgentID        string
	Content        string
	Soul           string
	Version        int64
	Constraints    []memory.ConstraintEntry
	ProfileEntries []memory.ProfileEntry
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

Memory is the transport-neutral projection of one (user, agent) memory row with its fact-backed profile/soul applied. Constraints/ProfileEntries are decoded domain values (never raw JSON), and timestamps are UTC.

type Service

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

Service owns the per-(user, agent) memory use cases.

func NewService

func NewService(db *pgxpool.Pool, profiles memory.ProfileStore, changelog memory.ChangelogReader, knowledge KnowledgeManager, agents AgentAuthorizer, defaultSoul func() string, log *slog.Logger) *Service

NewService builds the profile service. profiles/changelog are the memory Provider viewed through its capability interfaces (nil when the Provider does not implement them — the matching endpoints then report 503). knowledge is the persistence adapter for the user-facing knowledge lifecycle and keyset changelog projection (nil degrades those endpoints to 503); Profile wraps it with the Agent gate and derives the owner tuple from the Authority so the transport never supplies an owner id. defaultSoul supplies the fallback soul when none is stored. log defaults to slog.Default().

func (*Service) AddConstraint

func (s *Service) AddConstraint(ctx context.Context, authority authz.Authority, agentID, text string) ([]memory.ConstraintEntry, error)

AddConstraint appends a hard constraint (a Manual-sourced change) and returns the full updated list.

func (*Service) Changelog

func (s *Service) Changelog(ctx context.Context, authority authz.Authority, agentID string, scopes []string, limit int) ([]memory.ChangeEntry, error)

Changelog returns the merged change history for the caller's agent memory across the requested scopes (profile/soul via the Provider's changelog reader, constraint from the durable changelog table). It reads at most limit rows per scope; the transport merges, sorts, and truncates for presentation.

func (*Service) ChangelogPage

func (s *Service) ChangelogPage(ctx context.Context, authority authz.Authority, agentID, scope string, cursor *memory.ChangelogCursor, limit int) ([]memory.ChangeEntry, error)

ChangelogPage returns one keyset-paginated logical page of change history for a single scope of the caller's agent memory. Gated on agent read access; the owner tuple is the Authority's. The transport merges scopes and derives the next page token.

func (*Service) CreateKnowledge

func (s *Service) CreateKnowledge(ctx context.Context, authority authz.Authority, agentID, content string) (memory.Fact, error)

CreateKnowledge adds one active knowledge item to the caller's agent memory.

func (*Service) DeleteUserMemory

func (s *Service) DeleteUserMemory(ctx context.Context, authority authz.Authority, targetUserID, agentID string) error

DeleteUserMemory resets targetUserID's memory for an agent in a single transaction. The change source reflects admin-acting-on-other. Gated on the caller's read access to the agent.

func (*Service) DeprecateKnowledge

func (s *Service) DeprecateKnowledge(ctx context.Context, authority authz.Authority, agentID, factID string) error

DeprecateKnowledge removes (soft-deletes) an active knowledge item. The deprecating actor is the authenticated caller, never a request field.

func (*Service) ListConstraints

func (s *Service) ListConstraints(ctx context.Context, authority authz.Authority, agentID string) ([]memory.ConstraintEntry, error)

ListConstraints returns the caller's hard constraints for an agent.

func (*Service) ListKnowledge

func (s *Service) ListKnowledge(ctx context.Context, authority authz.Authority, agentID string, state KnowledgeState, limit int, cursor *KnowledgeCursor) (KnowledgePage, error)

ListKnowledge returns one active or removed knowledge page for the caller's agent memory. Gated on agent read access; the owner tuple is the Authority's.

func (*Service) ListUserMemories

func (s *Service) ListUserMemories(ctx context.Context, authority authz.Authority, targetUserID string) ([]Memory, error)

ListUserMemories returns every agent memory for one user (fact-backed). It is self-or-admin; a foreign target is opaque and denied before the durable list read. This reads across agents and therefore has no single-agent gate.

func (*Service) Memory

func (s *Service) Memory(ctx context.Context, authority authz.Authority, agentID string) (Memory, error)

Memory returns the caller's own memory for an agent (fact-backed profile/soul, constraints, entries). Gated on agent read access.

func (*Service) RemoveConstraint

func (s *Service) RemoveConstraint(ctx context.Context, authority authz.Authority, agentID, constraintID string) ([]memory.ConstraintEntry, error)

RemoveConstraint deletes a constraint by ID (a Manual-sourced change), returning ErrConstraintNotFound when it does not belong to the caller's agent memory, and otherwise the updated list.

func (*Service) ReplaceKnowledge

func (s *Service) ReplaceKnowledge(ctx context.Context, authority authz.Authority, agentID, factID, content string) (memory.Fact, error)

ReplaceKnowledge edits an active knowledge item in place (deprecate + create).

func (*Service) RestoreKnowledge

func (s *Service) RestoreKnowledge(ctx context.Context, authority authz.Authority, agentID, factID string) (memory.Fact, error)

RestoreKnowledge restores a removed knowledge item within the retention window. The restoring actor is the authenticated caller, never a request field.

func (*Service) SetSoul

func (s *Service) SetSoul(ctx context.Context, authority authz.Authority, agentID, soul string) (Memory, error)

SetSoul overwrites the caller's agent soul (a User-sourced change) and returns the refreshed memory. Gated on agent read access.

func (*Service) SetUserMemory

func (s *Service) SetUserMemory(ctx context.Context, authority authz.Authority, targetUserID, agentID, content string) (Memory, error)

SetUserMemory overwrites targetUserID's profile for an agent and returns the refreshed memory. The change source reflects whether an admin is acting on another user's memory. Gated on the caller's read access to the agent.

Jump to

Keyboard shortcuts

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