Documentation
¶
Overview ¶
Package harnesses defines the harness adapter contract (design §7.1).
A harness controls its own reasoning loop. The seat-runner supplies an Environment (identity, revision, generation, persistent locations, instructions and the tool command) and drives the adapter through Prepare -> StartOrResume -> Deliver* -> Quiesce -> Checkpoint -> Stop.
Technical completion versus business completion: a TurnResult's Status says only whether the harness finished processing a delivered message (completed, failed, interrupted, timed_out). Whether the agent considers a task done is the agent's claim. Adapters may surface it in TurnResult.Claim, but the platform never uses it for lifecycle decisions.
Index ¶
- Constants
- Variables
- func KillProcessGroup(pid int, sig syscall.Signal)
- func MustJSON(v any) json.RawMessage
- func NewProcessGroup(cmd *exec.Cmd)
- func Register(d Descriptor)
- func RenderBootstrap(env Environment, recoveryNote string) string
- func RenderEnvelope(d Delivery) string
- func RenderHandoff(h runtimeapi.Handoff) string
- func StatusFor(tctx context.Context) (string, string)
- func TruncateUTF8(s string, n int) string
- type Adapter
- type Capabilities
- type Claim
- type Delivery
- type Descriptor
- type Environment
- type Event
- type EventBus
- type MCPServer
- type ModelEndpoint
- type QuiesceResult
- type RecoveryDescriptor
- type ResumeResult
- type Setting
- type TurnGuard
- type TurnResult
Constants ¶
const ( RecoveryFresh = "fresh" // no previous session RecoveryNativeResume = "native_resume" // harness-native session resumed RecoveryPortableHandoff = "portable_handoff" // new session seeded from the portable handoff (§6.4) )
Recovery modes.
const ( GuaranteeApplication = "application_checkpoint" GuaranteeProcess = "process_snapshot" )
Checkpoint guarantees (runtimeapi.Checkpoint.Guarantee).
const ( TurnCompleted = "completed" TurnFailed = "failed" TurnInterrupted = "interrupted" TurnTimedOut = "timed_out" )
Turn statuses: technical completion only.
const ( EventProgress = "progress" EventToolRequest = "tool_request" EventToolResult = "tool_result" EventOutput = "output" EventCompletion = "completion" EventError = "error" )
Event kinds; they match runtimeapi.ExecutionEvent.Kind.
const ( APIAnthropicMessages = "anthropic_messages" // POST /v1/messages APIOpenAIResponses = "openai_responses" // POST /v1/responses APIOpenAIChat = "openai_chat" // POST /v1/chat/completions )
Model API protocols. A harness speaks some of them; a model connection serves some of them; a harness profile uses one both sides support.
const ProbePrompt = "This is a Steadmesh readiness probe, not a task. Call the steadmesh `self` tool exactly once, " +
"then answer with the single word: ready. Do not call any other tool and do not send any message."
ProbePrompt is the readiness probe turn the seat runner gives a model-backed harness to prove it works end to end.
Variables ¶
var ( ErrQuiescing = errors.New("harness: quiescing; not accepting deliveries") ErrStopped = errors.New("harness: stopped") ErrNotStarted = errors.New("harness: StartOrResume has not been called") ErrBusy = errors.New("harness: a turn is already in progress") )
Errors returned by adapters.
var ( ErrInterruptedByQuiesce = errors.New("turn interrupted: quiesce deadline reached") ErrInterruptedByStop = errors.New("turn interrupted: harness stopped") )
Interruption causes, available through context.Cause on a turn context.
var ModelAPIs = []string{APIAnthropicMessages, APIOpenAIResponses, APIOpenAIChat}
ModelAPIs lists every model API protocol.
Functions ¶
func KillProcessGroup ¶ added in v0.4.0
KillProcessGroup sends sig to the process group led by pid.
func MustJSON ¶
func MustJSON(v any) json.RawMessage
MustJSON marshals v, returning a JSON string on error so events are always valid JSON.
func NewProcessGroup ¶ added in v0.4.0
NewProcessGroup makes cmd the leader of its own process group, so KillProcessGroup also reaches the tools it spawns.
func Register ¶ added in v0.2.0
func Register(d Descriptor)
Register adds a harness. It panics on a duplicate name, as a programming error.
func RenderBootstrap ¶
func RenderBootstrap(env Environment, recoveryNote string) string
RenderBootstrap renders the bootstrap context a harness receives as its system context (§7.2): identity, instructions, guidance, tools, routes and recovery state. It is deliberately small: memory is retrieved via tools.
func RenderEnvelope ¶
RenderEnvelope renders a delivered message as the harness prompt: the trusted envelope fields first, then the body.
func RenderHandoff ¶
func RenderHandoff(h runtimeapi.Handoff) string
RenderHandoff renders a portable handoff (§8.4).
func StatusFor ¶
StatusFor maps a turn context's state to a TurnResult status, or "" when the context is still live.
func TruncateUTF8 ¶
TruncateUTF8 cuts s to at most n bytes without splitting a rune.
Types ¶
type Adapter ¶
type Adapter interface {
// DescribeCapabilities reports tools, streaming, recovery, interruption
// and checkpoint modes. It must not require Prepare.
DescribeCapabilities() Capabilities
// Prepare validates the pinned runtime, generates startup configuration
// and attaches platform-owned resources.
Prepare(ctx context.Context, env Environment) error
// StartOrResume starts the seat from a recovery descriptor. It reports
// whether the native session was resumed or a portable handoff was used.
StartOrResume(ctx context.Context, rec RecoveryDescriptor) (ResumeResult, error)
// Deliver processes one platform message and blocks until the turn is
// technically complete. Cancelling ctx interrupts the turn. All events for
// the turn are emitted on Events before Deliver returns.
Deliver(ctx context.Context, d Delivery) (TurnResult, error)
// Events returns the adapter's event stream. The same channel is returned
// on every call; it is closed by Stop. Consumers must drain it.
Events() <-chan Event
// Quiesce stops accepting deliveries and waits for the current turn to
// reach a safe point. When ctx expires first the turn is interrupted.
Quiesce(ctx context.Context) (QuiesceResult, error)
// Checkpoint persists the recovery descriptor and reports its guarantee.
Checkpoint(ctx context.Context) (runtimeapi.Checkpoint, error)
// Stop terminates execution without deleting durable seat data. An
// already-expired ctx means kill immediately.
Stop(ctx context.Context) error
}
Adapter is the §7.1 harness adapter interface. Implementations must be safe for one Deliver at a time; Quiesce, Stop and Events may be called concurrently with Deliver.
type Capabilities ¶
type Capabilities struct {
Adapter string `json:"adapter"`
// Version is the pinned runtime version, when known before Prepare.
Version string `json:"version,omitempty"`
// ToolTransports lists how platform tools reach the harness: mcp, cli.
ToolTransports []string `json:"tool_transports"`
EventStreaming bool `json:"event_streaming"`
// Interruption is how a running turn can be interrupted: signal, cooperative or none.
Interruption string `json:"interruption"`
// RecoveryModes lists supported recovery modes (Recovery* constants).
RecoveryModes []string `json:"recovery_modes"`
// CheckpointGuarantees lists the guarantees Checkpoint can report.
CheckpointGuarantees []string `json:"checkpoint_guarantees"`
// GracefulSuspension reports whether a live process can be suspended and
// resumed. False means Quiesce only reaches a turn boundary.
GracefulSuspension bool `json:"graceful_suspension"`
// SessionFormat identifies the native session format family.
SessionFormat string `json:"session_format,omitempty"`
}
Capabilities answers describe_capabilities.
type Delivery ¶
type Delivery struct {
DeliveryID int64
ExecutionID string
Attempt int
Message runtimeapi.Envelope
// Passive are queued messages (sent with wake=false) handed over with
// this turn. They are context, not separate requests to answer.
Passive []runtimeapi.Envelope
}
Delivery is one platform message with its execution context.
type Descriptor ¶ added in v0.2.0
type Descriptor struct {
// Name is the harness profile adapter value.
Name string
// Aliases are accepted alternative names.
Aliases []string
// APIs are the model APIs the harness can speak, in order of preference.
APIs []string
// NeedsModel means a harness profile must select a model.
NeedsModel bool
// Settings are the model.settings keys the harness understands.
Settings map[string]Setting
// Capabilities are values a profile's required_capabilities may name.
Capabilities []string
// New returns an unprepared adapter.
New func() Adapter
}
Descriptor describes a harness adapter. Compile validation reads descriptors; the seat runner constructs adapters with New. Adding a harness means a new package that registers its descriptor, an image and a contract (docs/harnesses.html), with no change to the core.
func Lookup ¶ added in v0.2.0
func Lookup(name string) (Descriptor, bool)
Lookup returns the descriptor registered under name or one of its aliases.
func Registered ¶ added in v0.2.0
func Registered() []Descriptor
Registered returns every registered descriptor, sorted by name.
type Environment ¶
type Environment struct {
OrganizationID string
SeatID string
SeatKey string
DisplayName string
ConfigRevision string
// Generation is the execution lease generation (fencing token).
Generation int64
// PlatformURL is the platform base URL; TokenFile is the projected token.
PlatformURL string
TokenFile string
// WorkspaceDir is the harness working directory (/seat/workspace),
// HomeDir is HOME (/seat/home), RunnerDir holds runner and adapter state
// (/seat/runner), TmpDir is scratch space (/tmp).
WorkspaceDir string
HomeDir string
RunnerDir string
TmpDir string
// Instructions is the rendered instruction text from
// /etc/steadmesh/manifest/instructions.md (Bootstrap.Instructions only
// lists the ordered refs).
Instructions string
// Bootstrap is the platform bootstrap (identity, guidance, recovery).
Bootstrap runtimeapi.Bootstrap
// ToolCommand is the steadmesh-tools binary.
ToolCommand string
// Model is the seat's model selection; nil when the profile has none.
Model *ModelEndpoint
// SandboxEnv is added to the environment of harness processes by access
// plugins: proxy settings for the egress gateway (HTTPS_PROXY, NO_PROXY).
SandboxEnv []string
// MCPServers are extra stdio MCP servers access plugins provide (the
// browser). Harnesses expose them next to the platform tools.
MCPServers []MCPServer
// HarnessConfig is the harness profile's free-form config.
HarnessConfig map[string]string
// ExtraEnv is passed to harness subprocesses (e.g. STEADMESH_* for tools).
ExtraEnv []string
}
Environment is what the platform supplies to a harness (§7, §7.2).
type Event ¶
type Event struct {
Kind string `json:"kind"`
// ExecutionID and MessageID correlate the event to its delivery.
ExecutionID string `json:"execution_id"`
MessageID string `json:"message_id"`
// CorrelationID links related events, e.g. a tool_use id.
CorrelationID string `json:"correlation_id,omitempty"`
Data json.RawMessage `json:"data,omitempty"`
Time time.Time `json:"time"`
}
Event is one structured harness event (§7.1 events).
func (Event) ToExecutionEvent ¶
func (e Event) ToExecutionEvent() runtimeapi.ExecutionEvent
ToExecutionEvent converts to the wire form.
type EventBus ¶
type EventBus struct {
// contains filtered or unexported fields
}
EventBus is a buffered event channel that can be closed safely while emitters are blocked.
func NewEventBus ¶
NewEventBus returns a bus with the given buffer size.
type ModelEndpoint ¶ added in v0.2.0
type ModelEndpoint struct {
// Connection is the model connection key.
Connection string
// ID is the model the harness must request; the proxy rejects others.
ID string
// API is the protocol to speak (API* constants).
API string
// Settings are validated model.settings (Descriptor.Settings).
Settings map[string]string
// BaseURL is the forwarder base for the connection, without /v1. The API
// paths sit below it: /v1/messages, /v1/responses, /v1/chat/completions.
BaseURL string
// APIKey is a placeholder for harnesses that insist on a key. The
// forwarder replaces whatever credential the harness sends.
APIKey string
}
ModelEndpoint is how a harness reaches its model. Requests go to the seat runner's local forwarder, which adds the seat's current token on every request and sends them to the platform model proxy; the proxy injects the connection's credential. No model credential enters the sandbox.
type QuiesceResult ¶
type QuiesceResult struct {
// Interrupted is true when the in-flight turn had to be interrupted.
Interrupted bool `json:"interrupted"`
// SafePoint describes the boundary reached, e.g. turn_boundary.
SafePoint string `json:"safe_point"`
// SuspensionSupported is false for adapters that cannot suspend a live process.
SuspensionSupported bool `json:"suspension_supported"`
}
QuiesceResult reports how Quiesce reached its safe point.
type RecoveryDescriptor ¶
type RecoveryDescriptor struct {
// Session is the last harness checkpoint recorded by the platform.
Session *runtimeapi.Checkpoint
Handoff *runtimeapi.Handoff
PendingMessages int
UnknownOperations []runtimeapi.Operation
// Note is the platform's recovery note, if any.
Note string
}
RecoveryDescriptor is what StartOrResume restores from.
func RecoveryFromBootstrap ¶
func RecoveryFromBootstrap(b runtimeapi.Bootstrap) RecoveryDescriptor
RecoveryFromBootstrap builds a descriptor from the platform bootstrap.
type ResumeResult ¶
type ResumeResult struct {
Mode string `json:"mode"`
SessionID string `json:"session_id,omitempty"`
// Note is a visible recovery note, e.g. why native resume was not used.
// It never claims byte-for-byte continuation of a lost session.
Note string `json:"note,omitempty"`
}
ResumeResult reports how StartOrResume restored the seat.
type Setting ¶ added in v0.2.0
type Setting struct {
Description string
// Values are the allowed values; empty means any non-empty string.
Values []string
}
Setting describes one model.settings key a harness accepts.
type TurnGuard ¶
type TurnGuard struct {
// contains filtered or unexported fields
}
TurnGuard serialises turns and implements the Quiesce and Stop semantics shared by adapters that run one turn at a time.
func (*TurnGuard) Begin ¶
Begin starts a turn. The returned context is cancelled when ctx is, or when Quiesce or Stop interrupts the turn. end must be called exactly once.
func (*TurnGuard) Quiesce ¶
func (g *TurnGuard) Quiesce(ctx context.Context) QuiesceResult
Quiesce stops new turns and waits for the active one; at ctx expiry the turn is interrupted and Quiesce waits for it to unwind.
type TurnResult ¶
type TurnResult struct {
MessageID string `json:"message_id"`
Status string `json:"status"`
Error string `json:"error,omitempty"`
SessionID string `json:"session_id,omitempty"`
// Output is the harness's final text for the turn. It is not delivered to
// anyone; agents reply through the messages tools.
Output string `json:"output,omitempty"`
Duration time.Duration `json:"duration"`
// Claim is the agent's own statement about business completion, if the
// adapter can identify one. It is informational and agent-owned.
Claim *Claim `json:"claim,omitempty"`
// Recovery is set when this turn started a new session in place of a
// native resume.
Recovery *ResumeResult `json:"recovery,omitempty"`
}
TurnResult is the technical outcome of one delivered message.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package all registers every built-in harness adapter.
|
Package all registers every built-in harness adapter. |
|
Package claudecode is the Claude Code harness adapter (design §7, ADR-0001).
|
Package claudecode is the Claude Code harness adapter (design §7, ADR-0001). |
|
Package codex is the Codex harness adapter.
|
Package codex is the Codex harness adapter. |
|
Package conformance is the §7.1 harness adapter conformance suite.
|
Package conformance is the §7.1 harness adapter conformance suite. |
|
modelstub
Package modelstub is a scripted model endpoint speaking the Anthropic Messages, OpenAI Responses and OpenAI Chat Completions APIs, streamed and not.
|
Package modelstub is a scripted model endpoint speaking the Anthropic Messages, OpenAI Responses and OpenAI Chat Completions APIs, streamed and not. |
|
Package fake is a deterministic harness adapter for infrastructure tests.
|
Package fake is a deterministic harness adapter for infrastructure tests. |
|
Package pi is the adapter for the Pi coding agent (pi.dev, @earendil-works/pi-coding-agent).
|
Package pi is the adapter for the Pi coding agent (pi.dev, @earendil-works/pi-coding-agent). |