Documentation
¶
Overview ¶
Package personal implements the domain-general durable state and runtime primitives for autonomous agents.
Index ¶
- Constants
- func AppendMemory(home, note string) error
- func CanonicalFilesystemGrant(path string) (string, error)
- func CanonicalPolicy(p DelegationPolicy) ([]byte, string, error)
- func CommitGenerated(root, message string) error
- func InitializeGeneratedWorkspace(home string) (string, error)
- func InitializeHome(home string) error
- func IsRestriction(parent, next DelegationPolicy) bool
- func NextDue(kind, spec string, after time.Time) (time.Time, error)
- func PathWithinGrant(path, root string) bool
- func PrepareRunDirectory(home, runID string, e ExecutionEnvelope) (string, error)
- func ReadMemory(home string) string
- func RedactActionRequest(v json.RawMessage) json.RawMessage
- func ResolveInteraction(s *Store, id, answer string) error
- func RollbackGenerated(root, revision string) error
- func SandboxAvailable() bool
- func ValidateDelegation(parent DelegationPolicy, e ExecutionEnvelope) error
- func ValidateExecutiveBudget(maxSeconds, maxTools, maxDelegation int) error
- func WriteConfigMirror(ctx context.Context, home string, s *Store) error
- type Action
- type ActionIntent
- type ActionStatus
- type ConsequenceClass
- type DelegationPolicy
- type EffectivenessEvaluation
- type EvolutionChoice
- type ExecutionEnvelope
- type Executive
- type ExecutiveDecision
- type ExecutiveState
- type GeneratedIndex
- type GeneratedItem
- type Interaction
- type MissedRunPolicy
- type Notification
- type Objective
- type PacePolicy
- type PaceState
- type Policy
- type Resource
- type ResourceGrantModel
- type ResourceType
- type Run
- type RunOutcome
- type RunResult
- type RunSpec
- type Store
- func (s *Store) ActionForJob(ctx context.Context, jobID string) (string, error)
- func (s *Store) ApprovePolicy(ctx context.Context, hash string) error
- func (s *Store) ApprovedPolicy(ctx context.Context, objectiveID string) (Policy, bool, error)
- func (s *Store) CancelInteraction(ctx context.Context, id string) error
- func (s *Store) CancelPendingNotifications(ctx context.Context) error
- func (s *Store) ClaimDueTrigger(ctx context.Context, id string, now time.Time) (Trigger, bool, error)
- func (s *Store) Close() error
- func (s *Store) CompleteAction(ctx context.Context, id string, status ActionStatus, ...) error
- func (s *Store) CreateObjective(ctx context.Context, o Objective) error
- func (s *Store) CreateRun(ctx context.Context, r Run) error
- func (s *Store) CreateTrigger(ctx context.Context, t Trigger) error
- func (s *Store) DB() *sql.DB
- func (s *Store) DeleteObjective(ctx context.Context, id string) error
- func (s *Store) DueTriggers(ctx context.Context, now time.Time) ([]Trigger, error)
- func (s *Store) GetInteraction(ctx context.Context, id string) (Interaction, bool, error)
- func (s *Store) GetObjective(ctx context.Context, id string) (Objective, bool, error)
- func (s *Store) InsertInteraction(ctx context.Context, in Interaction) error
- func (s *Store) InsertNotification(ctx context.Context, n Notification) error
- func (s *Store) InsertPolicy(ctx context.Context, p Policy) error
- func (s *Store) InsertResource(ctx context.Context, r Resource) error
- func (s *Store) LinkActionJob(ctx context.Context, actionID, jobID string) error
- func (s *Store) ListActions(ctx context.Context, objectiveID string, limit int) ([]Action, error)
- func (s *Store) ListObjectives(ctx context.Context) ([]Objective, error)
- func (s *Store) ListPolicies(ctx context.Context, objectiveID string) ([]Policy, error)
- func (s *Store) ListResources(ctx context.Context, objectiveID string) ([]Resource, error)
- func (s *Store) ListRuns(ctx context.Context, objectiveID string, limit int) ([]Run, error)
- func (s *Store) ListSubgoals(ctx context.Context, objectiveID string) ([]Subgoal, error)
- func (s *Store) ListTriggers(ctx context.Context) ([]Trigger, error)
- func (s *Store) MarkActionRunning(ctx context.Context, id string) error
- func (s *Store) NextPolicyVersion(ctx context.Context, objectiveID string) (int, error)
- func (s *Store) PendingInteractions(ctx context.Context, agentID string) ([]Interaction, error)
- func (s *Store) RecoverableRuns(ctx context.Context) ([]Run, error)
- func (s *Store) ReserveAction(ctx context.Context, a ActionIntent) (Action, bool, error)
- func (s *Store) ResolveInteraction(ctx context.Context, id, answer string) error
- func (s *Store) ResolveUncertainAction(ctx context.Context, id string, status ActionStatus) error
- func (s *Store) RevokeResources(ctx context.Context, objectiveID string) error
- func (s *Store) SetObjectiveStatus(ctx context.Context, id, status string) error
- func (s *Store) SetObjectiveText(ctx context.Context, id, description string) error
- func (s *Store) SetResourceStatus(ctx context.Context, id, status string) error
- func (s *Store) SetSubgoalStatus(ctx context.Context, id, status string) error
- func (s *Store) StatusSummary(ctx context.Context) (map[string]int, error)
- func (s *Store) UpdateRunStatus(ctx context.Context, id, status string, outcome json.RawMessage) error
- func (s *Store) UpsertSubgoal(ctx context.Context, g Subgoal) error
- type Subgoal
- type Trigger
Constants ¶
const ( BrowserExistingChrome = "existing_chrome" BrowserEphemeral = "ephemeral" )
Variables ¶
This section is empty.
Functions ¶
func AppendMemory ¶
AppendMemory adds one durable note. Append-only and deduplicated: a wake that re-learns something it already recorded must not grow the file without bound, since every line is replayed into the model on every future wake.
func CanonicalPolicy ¶
func CanonicalPolicy(p DelegationPolicy) ([]byte, string, error)
func CommitGenerated ¶
func InitializeHome ¶
func IsRestriction ¶
func IsRestriction(parent, next DelegationPolicy) bool
func NextDue ¶
NextDue resolves when a trigger should next fire.
The only kinds here are the ones an AGENT writes for itself from inside a run (schedule_wake: "come back in 45 minutes"), which are always a single future instant. Recurring cadence a HUMAN configures is not a trigger at all — it is an ordinary gateway schedule delivering to agent:<name>, parsed and validated once by gwconfig (see ValidateScheduleSpec/BuildSchedule).
That split is deliberate: this package used to carry its own interval/cron parsing, which meant two cron implementations in one binary and two places for scheduling rules to disagree. Adding kinds back here would rebuild the second scheduler — internal/guard's TestSingleCronParser fails if it happens.
func PathWithinGrant ¶
PathWithinGrant reports whether path resolves (symlinks evaluated) to a location inside the canonical grant root. The requested path's symlinks are resolved before the containment check so a symlink inside a granted dir that points outside cannot escape the boundary.
func PrepareRunDirectory ¶
func PrepareRunDirectory(home, runID string, e ExecutionEnvelope) (string, error)
func ReadMemory ¶
ReadMemory returns the agent's memory, or "" when it has none yet.
func RedactActionRequest ¶
func RedactActionRequest(v json.RawMessage) json.RawMessage
func ResolveInteraction ¶
func RollbackGenerated ¶
func SandboxAvailable ¶
func SandboxAvailable() bool
func ValidateDelegation ¶
func ValidateDelegation(parent DelegationPolicy, e ExecutionEnvelope) error
func ValidateExecutiveBudget ¶
func WriteConfigMirror ¶
WriteConfigMirror regenerates config.yaml — ONE readable file in the agent's home holding the authority state that lives in the database: its policies (draft and approved) and its resource grants. This is what makes `ls ~/.memcode/agents/<name>/` show something a person can read, diff, and grep instead of only an opaque SQLite file, matching every other piece of memcode config (gateway.yaml, .mcp.json, MEMCODE.md, skills).
The agent's objective, autonomy, browser mode, and pause state are NOT here: they are ordinary configuration in gateway.yaml, which is already a readable file. Mirroring them too would mean two places to look and two chances to disagree.
This file is a MIRROR, not the source of truth — the DB stays authoritative for two reasons that are correctness, not habit:
- Policy approval is a deliberate hash-gated ceremony (see ApprovePolicy): a autonomous agent runs unsupervised, so "the document a human actually reviewed" must be pinned by hash, not re-derived from whatever the file happens to say at wake time. Editing config.yaml's policy section and having it silently take effect would defeat that.
- The action/trigger/interaction journal needs atomic claim/complete semantics under concurrent access (the gateway wake loop and an admin session can both touch the same agent) — a SQL transaction gives that almost for free; a flat file would need to reinvent it (see the atomicfile-write fix elsewhere in this package for how easily a plain file write loses that property). So the run journal stays out of this file entirely — read it with gw_journal.
Called after every mutation to policies/resources (gw_policy, gw_grant), best-effort: a mirror failure never blocks the underlying write, which has already succeeded.
Types ¶
type Action ¶
type Action struct {
ID, ObjectiveID, SubgoalID, RunID, Kind, Target, ConsequenceClass, PolicyHash, Status, IdempotencyKey string
// JobID links a delegate action to the detached job it spawned, so a later
// wake can find the action to close out (see Store.ActionForJob).
JobID string
Request, Result, Evidence json.RawMessage
CreatedAt, UpdatedAt time.Time
}
type ActionIntent ¶
type ActionIntent struct {
ID, ObjectiveID, SubgoalID, RunID, Kind, Target string
Consequence ConsequenceClass
PolicyHash string
Request json.RawMessage
IdempotencyKey string
}
type ActionStatus ¶
type ActionStatus string
const ( ActionPlanned ActionStatus = "planned" ActionReserved ActionStatus = "reserved" ActionRunning ActionStatus = "running" ActionSucceeded ActionStatus = "succeeded" ActionFailed ActionStatus = "failed" ActionUncertain ActionStatus = "uncertain" ActionCancelled ActionStatus = "cancelled" )
type ConsequenceClass ¶
type ConsequenceClass string
const ( Observe ConsequenceClass = "observe" LocalMutation ConsequenceClass = "local_mutation" ExternalEffect ConsequenceClass = "external_effect" ExternalRepresentation ConsequenceClass = "external_representation" Financial ConsequenceClass = "financial" LegalAttestation ConsequenceClass = "legal_attestation" Destructive ConsequenceClass = "destructive" )
type DelegationPolicy ¶
type DelegationPolicy struct {
ObjectiveScope string `json:"objective_scope"`
AllowedTools []string `json:"allowed_tools,omitempty"`
FilesystemRoots map[string]string `json:"filesystem_roots,omitempty"`
BrowserOrigins []string `json:"browser_origins,omitempty"`
MCPTools []string `json:"mcp_tools,omitempty"`
ConsequenceClasses []ConsequenceClass `json:"consequence_classes,omitempty"`
MaxActionsPerPeriod int `json:"max_actions_per_period,omitempty"`
MaxConcurrency int `json:"max_concurrency,omitempty"`
MaxDelegationDepth int `json:"max_delegation_depth,omitempty"`
MaxTokens int `json:"max_tokens,omitempty"`
MaxSeconds int `json:"max_seconds,omitempty"`
GeneratedCode bool `json:"generated_code,omitempty"`
QuietHours string `json:"quiet_hours,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
Revoked bool `json:"revoked,omitempty"`
}
func NarrowPolicy ¶
func NarrowPolicy(parent, child DelegationPolicy) (DelegationPolicy, error)
func (DelegationPolicy) AllowsConsequence ¶
func (p DelegationPolicy) AllowsConsequence(c ConsequenceClass, now time.Time) bool
type EffectivenessEvaluation ¶
type EvolutionChoice ¶
type EvolutionChoice string
const ( EvolutionContinue EvolutionChoice = "continue" EvolutionChangeStrategy EvolutionChoice = "change_strategy" EvolutionReuse EvolutionChoice = "reuse_artifact" EvolutionGenerate EvolutionChoice = "generate_artifact" EvolutionImprove EvolutionChoice = "improve_artifact" EvolutionRetire EvolutionChoice = "retire_artifact" EvolutionEscalate EvolutionChoice = "request_information_or_authority" EvolutionAbandon EvolutionChoice = "abandon" )
func ChooseEvolution ¶
func ChooseEvolution(e EffectivenessEvaluation, hasCompatibleArtifact bool) EvolutionChoice
type ExecutionEnvelope ¶
type ExecutionEnvelope struct {
Task, ExpectedOutput, CompletionCondition string
Context json.RawMessage
Toolsets []string
Resources []string
Consequences []ConsequenceClass
Deadline string
Budgets jobs.ExecutionBudgets
ParentRunID, SubgoalID string
AllowDelegation bool
DelegationDepth int
// BrowserSession selects the worker's browser backend when Toolsets
// includes "browser": BrowserExistingChrome (the default for Personal
// Agent delegation — the user's own already-running, already-logged-in
// Chrome, reached through the gateway-owned broker) or BrowserEphemeral
// (a fresh, logged-out profile — explicit opt-down only). See
// docs/design/autonomous-agents.md "Browser broker trust boundary".
BrowserSession string
}
type Executive ¶
type Executive struct {
Store *Store
Home string
AgentID string
// Objective is the durable outcome this wake advances, read from the
// agent's configuration (gwconfig.Agent.Objective) rather than the store —
// a human edits it in one place and it hot-reloads. An empty Objective
// blocks the run rather than inventing one.
Objective string
Runner *llm.Runner
Now func() time.Time
MaxSteps int
// DelegationDepth is this wake's own depth in a delegation chain — 0 for a
// top-level RunOnce/ResumeSuspended wake. A worker spawned via delegate is
// itself a plain `memcode run` job, not another Executive, so depth never
// grows past 1 today; the field exists so ValidateDelegation's depth check
// means something even before nested Personal-Agent delegation exists.
DelegationDepth int
}
Executive is one bounded decision loop for an agent running unattended. Each RunOnce is a single bounded wake: read durable state, run one LLM turn with domain-neutral tools, journal consequential actions, then complete, schedule the next wake, or suspend for human input. It never holds an open loop.
func (*Executive) ResumeSuspended ¶
func (e *Executive) ResumeSuspended(ctx context.Context, in Interaction, answer string) (RunOutcome, error)
ResumeSuspended continues a suspended run after its interaction is answered. It loads the saved transcript, appends the exact tool_result for the suspended tool_use_id, then re-enters the bounded loop so the model actually continues — no replay of completed actions, no fabricated user turn. It marks the continuation resolved ONLY after the resumed run finishes, so a failure leaves the interaction retryable.
func (*Executive) RunOnce ¶
func (e *Executive) RunOnce(ctx context.Context) (RunOutcome, error)
RunOnce executes a single bounded wake for the agent's primary objective. It fails closed: no approved policy, inactive objective, or an expired/revoked policy all block consequential work before any LLM call is made.
type ExecutiveDecision ¶
func EvaluateEffectiveness ¶
func EvaluateEffectiveness(e EffectivenessEvaluation) ExecutiveDecision
func SelectNextAction ¶
func SelectNextAction(state ExecutiveState, now time.Time) ExecutiveDecision
type ExecutiveState ¶
type ExecutiveState struct {
Objective Objective
Subgoals []Subgoal
PendingInteractions int
RecentActions []Action
LastEvaluation *EffectivenessEvaluation
}
type GeneratedIndex ¶
type GeneratedIndex struct {
Path, Hash, Purpose, SourceObjectiveID, SourceRunID, ParentRevision string
BuildCommand, RunCommand, TestCommand []string
Evaluations []EffectivenessEvaluation
ActiveRevision string
}
type GeneratedItem ¶
type Interaction ¶
type Interaction struct {
ID, AgentID, ObjectiveID, RunID string
Kind, Question, Context string
Answer *string
Status string // pending | answered | cancelled
ToolUseID string
CreatedAt time.Time
AnsweredAt *time.Time
}
Interaction is a durable human-in-the-loop request created by a suspending tool (ask_user). It lives in the agent's personal.db and is answered via `personal answer`. Resume is exact: the saved tool_use_id gets the answer.
func GetInteraction ¶
func GetInteraction(s *Store, id string) (Interaction, bool, error)
func PendingInteractions ¶
func PendingInteractions(s *Store, agentID string) ([]Interaction, error)
Package-level wrappers used by cmd (store passed explicitly).
type MissedRunPolicy ¶
type MissedRunPolicy string
const ( MissedSkip MissedRunPolicy = "skip" MissedRunOnce MissedRunPolicy = "run_once" MissedCatchUp MissedRunPolicy = "catch_up" )
type Notification ¶
type Notification struct {
ID, ObjectiveID, Kind, Status string
Payload json.RawMessage
CreatedAt, UpdatedAt time.Time
}
type PacePolicy ¶
type PaceState ¶
type PaceState struct {
PeriodStarted time.Time
Actions, ConsecutiveFailures int
CooldownUntil time.Time
Suspended bool
Warning string
}
func (PaceState) AfterFailure ¶
func (PaceState) AfterSuccess ¶
func (s PaceState) AfterSuccess(now time.Time, p PacePolicy) PaceState
type ResourceGrantModel ¶
type ResourceType ¶
type ResourceType string
const ( ResourceFilesystem ResourceType = "filesystem" ResourceBrowser ResourceType = "browser" ResourceMCP ResourceType = "mcp" ResourceCommand ResourceType = "command" ResourceRepository ResourceType = "repository" ResourceCloud ResourceType = "cloud" ResourceDocument ResourceType = "document" ResourceChannel ResourceType = "channel" ResourceGeneratedProcess ResourceType = "generated_process" )
type RunOutcome ¶
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) ActionForJob ¶
ActionForJob returns the id of the action that spawned jobID, or "" when there is none.
func (*Store) ApprovedPolicy ¶
func (*Store) CancelInteraction ¶
func (*Store) CancelPendingNotifications ¶
func (*Store) ClaimDueTrigger ¶
func (*Store) CompleteAction ¶
func (s *Store) CompleteAction(ctx context.Context, id string, status ActionStatus, result, evidence json.RawMessage) error
func (*Store) CreateObjective ¶
func (*Store) DB ¶
DB exposes the underlying handle for store-internal submodules (same package); external callers use Store methods only.
func (*Store) DeleteObjective ¶
func (*Store) DueTriggers ¶
DueTriggers returns only enabled triggers whose next_due_at has passed, filtered in SQL rather than pulling every trigger row (including completed ones) and filtering in Go on every poll.
func (*Store) GetInteraction ¶
func (*Store) GetObjective ¶
func (*Store) InsertInteraction ¶
func (s *Store) InsertInteraction(ctx context.Context, in Interaction) error
func (*Store) InsertNotification ¶
func (s *Store) InsertNotification(ctx context.Context, n Notification) error
func (*Store) InsertResource ¶
func (*Store) LinkActionJob ¶
LinkActionJob records which detached job an action spawned, so a later wake can find its way back from a job id to the action it must close out.
func (*Store) ListActions ¶
func (*Store) ListObjectives ¶
func (*Store) ListPolicies ¶
func (*Store) ListResources ¶
func (*Store) ListSubgoals ¶
func (*Store) MarkActionRunning ¶
func (*Store) NextPolicyVersion ¶
func (*Store) PendingInteractions ¶
func (*Store) ReserveAction ¶
func (*Store) ResolveInteraction ¶
ResolveInteraction atomically marks a pending interaction answered. Returns an error if it was already resolved (prevents double-resume of a suspended run).
func (*Store) ResolveUncertainAction ¶
func (*Store) RevokeResources ¶
func (*Store) SetObjectiveStatus ¶
func (*Store) SetObjectiveText ¶
SetObjectiveText updates an objective's description (the user-authored goal).