controlplane

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2026 License: Apache-2.0 Imports: 40 Imported by: 0

Documentation

Overview

Package controlplane is runeward's governed execution core. Every tool call runs through one path: policy, approval gate, guardrails, backend exec, audit ledger. The Manager owns sandbox sessions and the shared ledger; the REST and MCP servers are thin adapters over it.

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidLease = errors.New("cohort: invalid or expired task lease")

Functions

func CheckProfilePrerequisites added in v0.3.0

func CheckProfilePrerequisites(p *profile.Profile) error

CheckProfilePrerequisites resolves required environment and secret sources without exposing their values. It is shared by server readiness and doctor.

func ExperimentalIDEEnabled added in v0.3.0

func ExperimentalIDEEnabled() bool

ExperimentalIDEEnabled reports whether the browser IDE feature flag is on.

func WithActor added in v0.3.0

func WithActor(ctx context.Context, actor string) context.Context

WithActor attributes Chronicle events produced during ctx to the currently authenticated human or agent. Tenant ownership remains attached to Session.

Types

type Approval

type Approval struct {
	ID      string
	Sandbox string
	Tool    string
	Action  string
	Reason  string
	Created time.Time
	// contains filtered or unexported fields
}

Approval is a pending human-in-the-loop authorization request. The blocked tool call waits on decided until an operator resolves it.

type ApprovalStore

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

ApprovalStore is a concurrency-safe registry of pending approvals.

func NewApprovalStore

func NewApprovalStore() *ApprovalStore

NewApprovalStore returns an empty store.

func (*ApprovalStore) Create

func (s *ApprovalStore) Create(sandbox, tool, action, reason string) *Approval

Create registers a new pending approval and returns it.

func (*ApprovalStore) Get added in v0.3.0

func (s *ApprovalStore) Get(id string) (ApprovalView, bool)

Get returns one pending approval without resolving it.

func (*ApprovalStore) List

func (s *ApprovalStore) List() []ApprovalView

List returns a snapshot of pending approvals in map order; callers sort if they need to.

func (*ApprovalStore) Resolve

func (s *ApprovalStore) Resolve(id string, approve bool) bool

Resolve delivers a decision to the waiting tool call and removes the approval. It reports whether that id was pending.

func (*ApprovalStore) ResolveView

func (s *ApprovalStore) ResolveView(id string, approve bool) (ApprovalView, bool)

ResolveView is like Resolve but also returns a view of the approval that was resolved, so callers can record who decided it and what it authorized.

type ApprovalView

type ApprovalView struct {
	ID      string    `json:"id"`
	Sandbox string    `json:"sandbox"`
	Tool    string    `json:"tool"`
	Action  string    `json:"action"`
	Reason  string    `json:"reason"`
	Created time.Time `json:"created"`
}

ApprovalView is the JSON projection of an Approval.

type ClientError

type ClientError struct {
	// NotFound marks a missing resource (sandbox, fleet, snapshot, browser
	// session) -> 404. When false the error is treated as bad input -> 400.
	NotFound bool
	Message  string
}

ClientError is an error whose message is safe to return to an API caller and which maps to a client-facing HTTP status. It lets the server distinguish bad input and missing resources (which the caller can act on) from genuine internal failures, which must stay opaque so they cannot leak host paths, backend detail, or other server-side information.

func (*ClientError) Error

func (e *ClientError) Error() string

type ConversationMessage added in v0.3.0

type ConversationMessage struct {
	ID        uint64    `json:"id"`
	Sandbox   string    `json:"sandbox"`
	Role      string    `json:"role"`
	Author    string    `json:"author"`
	Content   string    `json:"content"`
	RunID     string    `json:"run_id,omitempty"`
	CreatedAt time.Time `json:"created_at"`
	Redacted  bool      `json:"redacted,omitempty"`
}

ConversationMessage is one redacted, display-safe turn in a Citadel's live conversation feed. The feed is operational visibility, not a replacement for the signed Chronicle.

type CreateOptions

type CreateOptions struct {
	// CopyFrom overrides host.copy_from for this create: a one-time copy into
	// the fresh workspace, the host dir is never mounted. "~/" is expanded.
	CopyFrom string
	// Owner records the RBAC principal that created the sandbox, for
	// per-principal visibility and access control. Empty means unowned
	// (RBAC disabled), in which case every caller can see it.
	Owner string
	// Actor is the authenticated principal; Owner is its tenant boundary.
	Actor string
	// ParentSandbox links a delegated child to an existing parent Citadel. Child
	// creation is constrained to the parent's tenant and exact Charter, which is
	// a conservative monotonic-permission rule.
	ParentSandbox string
	RunID         string
	Agent         string
	Provider      string
	Model         string
}

CreateOptions carries per-create overrides that are not part of the profile.

type Fleet

type Fleet struct {
	ID        string
	Profile   string
	Owner     string
	Board     *fleet.Board
	Sandboxes []string
	Created   time.Time
	// contains filtered or unexported fields
}

Fleet is a set of sandboxes from one profile sharing an atomic task board.

type FleetView

type FleetView struct {
	ID        string      `json:"id"`
	Profile   string      `json:"profile"`
	Owner     string      `json:"owner,omitempty"`
	Sandboxes []string    `json:"sandboxes"`
	Stats     fleet.Stats `json:"stats"`
	Created   time.Time   `json:"created"`
}

FleetView is the JSON projection of a fleet.

type Manager

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

Manager is the control-plane core. It is safe for concurrent use.

func New

func New(configDir string) (*Manager, error)

New constructs a Manager and opens the shared audit ledger.

func (*Manager) AddTask

func (m *Manager) AddTask(fleetID, payload string) (*fleet.Task, error)

AddTask appends a task to a fleet's board.

func (*Manager) Approvals

func (m *Manager) Approvals() *ApprovalStore

Approvals returns the approval store.

func (*Manager) AttachTerminal

func (m *Manager) AttachTerminal(ctx context.Context, id string, stream backend.PTYStream) error

AttachTerminal wires an interactive PTY to the sandbox. Terminals are not policy-gated per keystroke, but the attach itself is audited.

func (*Manager) Browser

func (m *Manager) Browser(ctx context.Context, id, url, mode string) (*ToolResult, error)

Browser renders a page with headless Chromium inside the sandbox. It is policy-gated as tool "browser" (arg = url), and the profile's egress proxy is passed via --proxy-server so egress rules cover browser traffic too. mode is "text" (rendered DOM HTML) or "screenshot" (base64 PNG in Stdout).

func (*Manager) BrowserAct

func (m *Manager) BrowserAct(ctx context.Context, id, sessionID string, cmd browser.Command) (*ToolResult, error)

BrowserAct sends one action to a live browser session through the governed path. Stdout carries the value (or base64 screenshot); a driver-level failure surfaces in Reason.

func (*Manager) BrowserClose

func (m *Manager) BrowserClose(ctx context.Context, id, sessionID string) error

BrowserClose shuts down the driver (best-effort) and always removes local bookkeeping.

func (*Manager) BrowserOpen

func (m *Manager) BrowserOpen(ctx context.Context, id string) (sessionID string, res *ToolResult, err error)

BrowserOpen starts a stateful CDP browser session in the sandbox and returns its id. The driver is launched detached; the egress proxy is threaded through via --proxy. Gated by policy as tool "browser" (action "open"), so a deny or pending verdict comes back in the ToolResult without starting a session.

func (*Manager) CheckReadiness added in v0.2.0

func (m *Manager) CheckReadiness(name string) ReadinessReport

CheckReadiness validates a policy and probes its configured runtime. Host paths and raw engine stderr are intentionally omitted from the result.

func (*Manager) ClaimTask

func (m *Manager) ClaimTask(fleetID, owner string) (fleet.Task, bool, error)

ClaimTask atomically claims the next pending task for a worker.

func (*Manager) Close

func (m *Manager) Close() error

Close stops the sweeper, flushes audit sinks, and releases the ledger handle.

func (*Manager) CompleteTask

func (m *Manager) CompleteTask(fleetID, taskID, owner, leaseToken, result string) error

CompleteTask marks a claimed task done. owner must match the claiming worker.

func (*Manager) ConversationHistory added in v0.3.0

func (m *Manager) ConversationHistory(sandbox string, afterID uint64, limit int) ([]ConversationMessage, error)

ConversationHistory returns at most limit messages newer than afterID.

func (*Manager) CreateFleet

func (m *Manager) CreateFleet(ctx context.Context, profileName string) (*FleetView, error)

CreateFleet provisions the profile's replicas with a shared task board seeded from its task_board list.

func (*Manager) CreateFleetForIdentity added in v0.3.0

func (m *Manager) CreateFleetForIdentity(ctx context.Context, profileName, owner, actor string) (*FleetView, error)

CreateFleetForIdentity creates a tenant-owned Cohort while attributing its member Citadels to the authenticated actor that requested it.

func (*Manager) CreateFleetForOwner

func (m *Manager) CreateFleetForOwner(ctx context.Context, profileName, owner string) (*FleetView, error)

CreateFleetForOwner provisions the profile's replicas with a shared task board seeded from its task_board list and attributes member sandboxes to the owning principal when provided.

func (*Manager) CreateSandbox

func (m *Manager) CreateSandbox(ctx context.Context, profileName string, opts CreateOptions) (*backend.Sandbox, error)

CreateSandbox loads the named profile, provisions a sandbox on its backend, and registers a governed session for it.

func (*Manager) Evidence added in v0.3.0

func (m *Manager) Evidence(id, version string) (evidence.Document, error)

Evidence builds the portable, signed evidence document for a Citadel.

func (*Manager) ExportBundle

func (m *Manager) ExportBundle(w io.Writer, sessionID string) error

ExportBundle writes a verifiable transcript of a session's audit events (all events when sessionID is "") to w. Fails when signing is disabled.

func (*Manager) ExportWorkspace added in v0.2.0

func (m *Manager) ExportWorkspace(ctx context.Context, id string, w io.Writer) error

ExportWorkspace streams a point-in-time tar archive from a governed sandbox.

func (*Manager) FailTask

func (m *Manager) FailTask(fleetID, taskID, owner, leaseToken, errMsg string, requeue bool) error

FailTask marks a claimed task failed, optionally requeuing it. owner must match the claiming worker.

func (*Manager) FileList

func (m *Manager) FileList(ctx context.Context, id, path string) (*ToolResult, error)

FileList lists a directory in the sandbox.

func (*Manager) FileRead

func (m *Manager) FileRead(ctx context.Context, id, path string) (*ToolResult, error)

FileRead returns the contents of a file in the sandbox.

func (*Manager) FileSearch

func (m *Manager) FileSearch(ctx context.Context, id, query, path string) (*ToolResult, error)

FileSearch runs a recursive grep rooted at path.

func (*Manager) FileWrite

func (m *Manager) FileWrite(ctx context.Context, id, path, content string) (*ToolResult, error)

FileWrite writes a file in the sandbox, creating parent directories. Content travels base64-encoded to stay binary-safe over the shell.

func (*Manager) FleetOwner added in v0.3.0

func (m *Manager) FleetOwner(id string) (string, bool)

FleetOwner returns the principal that owns a Cohort. A known, unowned Cohort returns ("", true), matching SandboxOwner semantics.

func (*Manager) FleetView

func (m *Manager) FleetView(id string) (*FleetView, bool)

FleetView returns a single fleet's projection.

func (*Manager) HeartbeatTask

func (m *Manager) HeartbeatTask(fleetID, taskID, owner, leaseToken string) (fleet.Task, error)

HeartbeatTask extends a worker's lease on a task so the sweeper won't requeue it.

func (*Manager) IDEAgents added in v0.3.0

func (m *Manager) IDEAgents(id string) []string

IDEAgents returns Charter-declared CLI agent hints for the Citadel IDE UI.

func (*Manager) IDEEndpoint added in v0.3.0

func (m *Manager) IDEEndpoint(id string) (string, bool)

IDEEndpoint returns the in-cell IDE host:port when the experimental IDE is running for the Citadel.

func (*Manager) InjectSession added in v0.3.0

func (m *Manager) InjectSession(sess *Session)

InjectSession registers a session for tests (no backend create).

func (*Manager) KillFleet

func (m *Manager) KillFleet(ctx context.Context, id string) error

KillFleet tears down every sandbox in the fleet and removes it.

func (*Manager) KillSandbox

func (m *Manager) KillSandbox(ctx context.Context, id string) error

KillSandbox tears down a sandbox and removes its session.

func (*Manager) Ledger

func (m *Manager) Ledger() *ledger.Ledger

Ledger returns the shared ledger.

func (*Manager) LedgerPublicKey

func (m *Manager) LedgerPublicKey() (pub string, keyID string)

LedgerPublicKey returns the base64 signing key and key id, or empty strings when signing is disabled.

func (*Manager) ListFleets

func (m *Manager) ListFleets() []FleetView

ListFleets returns all fleets.

func (*Manager) ListProfiles

func (m *Manager) ListProfiles() ([]ProfileInfo, error)

ListProfiles returns the resolvable profiles for the configured search path.

func (*Manager) ListRuns added in v0.3.0

func (m *Manager) ListRuns() []Run

ListRuns returns durable run records in creation order.

func (*Manager) ListSandboxInfos

func (m *Manager) ListSandboxInfos() []SandboxInfo

ListSandboxInfos returns every governed sandbox together with its owner. The server uses this to filter the list per principal ("multi-user" views).

func (*Manager) ListSandboxes

func (m *Manager) ListSandboxes() []backend.Sandbox

ListSandboxes returns handles for every governed sandbox.

func (*Manager) ListSnapshots

func (m *Manager) ListSnapshots() []backend.SnapshotRef

ListSnapshots returns all captured snapshot references.

func (*Manager) ListTasks

func (m *Manager) ListTasks(fleetID string) ([]fleet.Task, error)

ListTasks returns a snapshot of a fleet's tasks.

func (*Manager) LoadProfile added in v0.2.0

func (m *Manager) LoadProfile(name string) (*profile.Profile, error)

LoadProfile resolves a policy from the Manager's configured directory. HTTP adapters use this instead of re-reading process environment state.

func (*Manager) Node

func (m *Manager) Node(ctx context.Context, id, code string) (*ToolResult, error)

Node runs a JavaScript snippet via `node -e`.

func (*Manager) PublishConversation added in v0.3.0

func (m *Manager) PublishConversation(ctx context.Context, sandbox, role, content, runID string) (ConversationMessage, error)

PublishConversation adds a turn and broadcasts it to read-only observers. The authenticated actor is derived from ctx; callers cannot spoof authors. Declared and pattern-detected secrets are scrubbed before storage or fan-out.

func (*Manager) Python

func (m *Manager) Python(ctx context.Context, id, code string) (*ToolResult, error)

Python runs a Python snippet via `python3 -c`.

func (*Manager) RecordUsage

func (m *Manager) RecordUsage(id string, tokens int64, costUSD float64) error

RecordUsage attributes reported model usage (tokens and/or US-dollar spend) to a sandbox, updating the accounting totals and metrics and appending an audit event. Callers (agents, fleet workers) report usage they observe from the model provider; once the profile's budget is exceeded, govern denies further tool calls. It errors if the sandbox is unknown.

func (*Manager) RecordUsageContext added in v0.3.0

func (m *Manager) RecordUsageContext(ctx context.Context, id string, tokens int64, costUSD float64) error

RecordUsageContext is RecordUsage with request actor attribution.

func (*Manager) ResolveApproval

func (m *Manager) ResolveApproval(id string, approve bool, actor string) bool

ResolveApproval resolves a pending approval and records who decided it in the tamper-evident ledger, so a human-in-the-loop decision is always attributed. It reports whether the id was pending.

func (*Manager) RestoreSnapshot

func (m *Manager) RestoreSnapshot(ctx context.Context, snapshotID, owner string) (*backend.Sandbox, error)

RestoreSnapshot recreates a governed sandbox from a snapshot, re-deriving policy and guardrails from the snapshot's profile.

func (*Manager) RestoreSnapshotForIdentity added in v0.3.0

func (m *Manager) RestoreSnapshotForIdentity(ctx context.Context, snapshotID, owner, actor string) (*backend.Sandbox, error)

RestoreSnapshotForIdentity restores a tenant-owned snapshot while retaining the individual human or agent actor in run lineage and Chronicle metadata.

func (*Manager) Run added in v0.3.0

func (m *Manager) Run(id string) (Run, bool)

Run returns one durable run record.

func (*Manager) Sandbox

func (m *Manager) Sandbox(id string) (*backend.Sandbox, bool)

Sandbox returns the handle for a sandbox id.

func (*Manager) SandboxCapabilities added in v0.3.0

func (m *Manager) SandboxCapabilities(id string) []string

SandboxCapabilities returns optional runtime tools declared by the Citadel's Charter. Empty intentionally means shell/files only.

func (*Manager) SandboxOwner

func (m *Manager) SandboxOwner(id string) (owner string, ok bool)

SandboxOwner returns the owning principal for a sandbox id. ok is false when the sandbox is unknown; a known-but-unowned sandbox returns ("", true).

func (*Manager) SandboxUsage

func (m *Manager) SandboxUsage(id string) accounting.Usage

SandboxUsage returns the cumulative reported usage for a sandbox.

func (*Manager) SetIDEEndpointForTest added in v0.3.0

func (m *Manager) SetIDEEndpointForTest(id, endpoint string)

SetIDEEndpointForTest sets the IDE proxy target without starting code-server.

func (*Manager) Shell

func (m *Manager) Shell(ctx context.Context, id string, command []string, workdir string) (*ToolResult, error)

Shell runs a command vector in the sandbox under policy control.

func (*Manager) Signed

func (m *Manager) Signed() bool

Signed reports whether the ledger is being signed.

func (*Manager) Snapshot

func (m *Manager) Snapshot(ctx context.Context, id, name string) (*backend.SnapshotRef, error)

Snapshot captures a sandbox's workspace and registers the reference.

func (*Manager) SnapshotOwner added in v0.2.0

func (m *Manager) SnapshotOwner(id string) (string, bool)

SnapshotOwner returns the principal that created a recovery snapshot.

func (*Manager) SnapshotRef added in v0.3.0

func (m *Manager) SnapshotRef(id string) (backend.SnapshotRef, bool)

SnapshotRef returns one registered recovery artifact.

func (*Manager) StateDir

func (m *Manager) StateDir() string

StateDir returns the directory holding runeward state (ledger, keys, and terminal recordings).

func (*Manager) SubscribeConversation added in v0.3.0

func (m *Manager) SubscribeConversation(sandbox string) (<-chan ConversationMessage, func(), error)

SubscribeConversation streams future messages until cancel is called or the Citadel is removed. Slow observers lose old live updates but can recover via ConversationHistory without blocking an agent.

func (*Manager) VerifyLedger

func (m *Manager) VerifyLedger() error

VerifyLedger checks the hash chain and, when signing is enabled, signatures.

type ProfileInfo

type ProfileInfo struct {
	Name         string   `json:"name"`
	Host         string   `json:"host"`
	Egress       string   `json:"egress"`
	Image        string   `json:"image,omitempty"`
	Capabilities []string `json:"capabilities,omitempty"`
}

ProfileInfo is a lightweight profile descriptor for listing.

type ReadinessCheck added in v0.2.0

type ReadinessCheck struct {
	Name    string `json:"name"`
	Status  string `json:"status"`
	Message string `json:"message"`
}

ReadinessCheck is one safe, user-actionable setup diagnostic.

type ReadinessReport added in v0.2.0

type ReadinessReport struct {
	Ready   bool             `json:"ready"`
	Profile string           `json:"profile"`
	Checks  []ReadinessCheck `json:"checks"`
}

ReadinessReport distinguishes control-plane liveness from the ability to launch the selected policy's sandbox runtime.

type Run added in v0.3.0

type Run struct {
	ID          string     `json:"id"`
	ParentRunID string     `json:"parent_run_id,omitempty"`
	CitadelID   string     `json:"citadel_id"`
	Tenant      string     `json:"tenant,omitempty"`
	Actor       string     `json:"actor,omitempty"`
	Charter     string     `json:"charter"`
	Agent       string     `json:"agent,omitempty"`
	Provider    string     `json:"provider,omitempty"`
	Model       string     `json:"model,omitempty"`
	Status      string     `json:"status"`
	CreatedAt   time.Time  `json:"created_at"`
	FinishedAt  *time.Time `json:"finished_at,omitempty"`
	Error       string     `json:"error,omitempty"`
}

Run is the durable, provider-neutral record for one agent execution lineage node. Citadels are runtime resources; Runs remain queryable after teardown.

type SandboxInfo

type SandboxInfo struct {
	Sandbox backend.Sandbox
	Owner   string
}

SandboxInfo pairs a sandbox handle with its owning principal for listing.

type Session

type Session struct {
	Sandbox *backend.Sandbox
	Backend backend.Backend
	Profile *profile.Profile
	Engine  policy.Evaluator
	Guard   *policy.Guard

	Env     map[string]string
	Workdir string

	// Owner is the tenant boundary used for visibility and access control.
	// It may be shared by several authenticated principals (agents or humans).
	// Empty when RBAC is not configured.
	Owner string
	// Actor is the authenticated principal performing work inside the tenant.
	// It is distinct from Owner so multiple agents can collaborate safely.
	Actor string

	// Agent-run lineage makes delegated activity attributable across providers.
	RunID       string
	ParentRunID string
	Agent       string
	Provider    string
	Model       string
	// contains filtered or unexported fields
}

Session is the per-sandbox governed state.

type ToolResult

type ToolResult struct {
	Verdict    profile.Verdict `json:"verdict"`
	Reason     string          `json:"reason,omitempty"`
	ApprovalID string          `json:"approval_id,omitempty"`
	Pending    bool            `json:"pending,omitempty"`
	ExitCode   int             `json:"exit_code"`
	Stdout     string          `json:"stdout,omitempty"`
	Stderr     string          `json:"stderr,omitempty"`
	DurationMS int64           `json:"duration_ms"`
}

ToolResult is the governed outcome of a single tool invocation.

Jump to

Keyboard shortcuts

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