Documentation
¶
Overview ¶
Package runneragent dispatches authenticated runner RPCs to a local substrate. Session admission, durable offline enforcement and stream bridges remain separate dependencies; no test server is used by the production daemon.
Index ¶
- type Config
- type Dispatcher
- type Keystore
- type Resident
- func (r *Resident) Call(ctx context.Context, peer *runnerwire.Peer, method string, ...) (any, error)
- func (r *Resident) EraseAll(ctx context.Context) error
- func (r *Resident) EraseExpired(ctx context.Context, now time.Time) error
- func (r *Resident) SweepExpired(ctx context.Context, every time.Duration)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
RunnerID string
Substrate substrate.Substrate
// HoldsSandbox reports whether a local ref is a sandbox this runner created
// and durably holds. Any other ref reaches the substrate only when the
// substrate proves it a sandbox created for this runner.
HoldsSandbox func(string) bool
// BeforeCreate durably establishes a unique creation intent and live lease.
// Nil proves a NEW run; every existing or ambiguous intent must refuse.
BeforeCreate func(context.Context, runner.SandboxSpec) error
// Created durably binds the run to its local ref before success is reported.
Created func(context.Context, runner.SandboxSpec, string) error
// CreateFailed durably contains a failed NEW intent, including partial
// provisioning. It must retain output and retry proxy containment locally.
CreateFailed func(context.Context, runner.SandboxSpec) error
// BeforeRefCall enforces offline/lease policy before a state-changing call.
// The generation is the explicit Exec/Start CALL identity, zero otherwise.
BeforeRefCall func(context.Context, string, string, uuid.UUID) error
// AfterRefCall persists successful state changes with the same generation.
// The exec id is populated for MethodExec, empty otherwise. Persistence
// failures must contain the proxy before returning their error.
AfterRefCall func(context.Context, string, string, string, uuid.UUID) error
// MutationFinished runs after every admitted mutation, including substrate
// failures, output rollback and detached persistence. Create supplies run ID;
// ref calls supply the checked local ref and explicit execution generation.
MutationFinished func(context.Context, string, string, uuid.UUID, uuid.UUID, error) error
// ExecutionResult recovers a durable intent/handle without executing it again.
ExecutionResult func(context.Context, string, uuid.UUID) (runnerwire.ExecutionResult, error)
// Streams serves attach/exec/resize/wait/output, with ref validation of its own.
Streams func(context.Context, *runnerwire.Peer, uint32, string, json.RawMessage) (any, error)
Output func(uuid.UUID) (io.Writer, error)
BindOutput func(uuid.UUID, string) error
ForgetOutput func(uuid.UUID) error
// CheckSelftest admits a BYOI selftest under the task's unattempted
// generation without spending it; nil refuses the selftest.
CheckSelftest func(context.Context, string, uuid.UUID) error
// Resident is the runner_resident adapter; nil refuses both verbs and any
// create or proxy replacement that names a resident grant.
Resident *Resident
}
Config supplies the local executor and the production safety adapters.
type Dispatcher ¶
type Dispatcher struct {
// contains filtered or unexported fields
}
func New ¶
func New(cfg Config) (*Dispatcher, error)
func (*Dispatcher) Call ¶
func (d *Dispatcher) Call(ctx context.Context, peer *runnerwire.Peer, id uint32, method string, args json.RawMessage) (any, error)
Call is RunnerHooks.Call. Byte stream verbs go to the H4 adapter; everything else calls the same substrate interfaces as the local orchestrator.
func (*Dispatcher) Residents ¶ added in v0.9.3
func (d *Dispatcher) Residents() bool
Residents reports whether the runner holds runner_resident credentials, its caps' Resident.
func (*Dispatcher) Selftests ¶ added in v0.9.3
func (d *Dispatcher) Selftests() bool
Selftests reports whether this runner serves runnerwire.MethodSelftest, for its caps' BYOISelftest.
type Keystore ¶
type Keystore struct {
Set func(account, value string) error
Get func(account string) (string, error)
Delete func(account string) error
// DeleteAll deletes every item under this runner's service.
DeleteAll func() error
// Precheck refuses a value the keystore cannot take before any entry is
// written or any keystore call is made.
Precheck func(account, value string) error
}
Keystore is where resident values live; production is package keystore, under this runner's own service.
type Resident ¶
type Resident struct {
// contains filtered or unexported fields
}
Resident is the runner half of runner_resident delivery (design 0.9 §7.4). Values live only in the keystore and in the sandbox or proxy they are applied to. The index of what this runner holds (never a value) is kept in the state directory, so a restarted runner can still erase at run end.
Keystore operations are serialized per account: an account is busy from just before its keystore call until that call really returns, even when the caller stopped waiting (a keystore write that outlives its timeout). No second call starts on a busy account; an erase that meets one asks for the delete instead, and the call's own completion carries it out. A process-local mutex is enough because the state directory has one writer (its flock).
func NewResident ¶
func NewResident(ks Keystore, stateDir string, admit func(uuid.UUID) error, now func() time.Time) (*Resident, error)
NewResident loads the index at stateDir/resident.json. admit binds a delivery to a run this runner may still create. An entry found writing was in flight when the runner stopped: it is marked for erasure and unsettled, and the first sweep deletes it.
func (*Resident) Call ¶
func (r *Resident) Call(ctx context.Context, peer *runnerwire.Peer, method string, args json.RawMessage) (any, error)
Call serves deliver_resident and erase_resident.
func (*Resident) EraseAll ¶ added in v0.9.3
EraseAll deletes every value this runner holds, on revoke. Every entry is marked for erasure first (durably), so one with a call in flight is deleted by that call's completion and any other by the sweep if its delete fails here. It sends no report: the org settles a revoked runner's erasures itself.
func (*Resident) EraseExpired ¶
EraseExpired is the sweep. It deletes every value past its NotAfter, whether or not its run's end ever reached this runner, every value marked for erasure with no call in flight, and an unsettled value again while its settle window is open. Each is marked erased but unreported, and the run's next erase reports it. A value whose delete fails stays for the next sweep.