Help us shape the future of Go! Take the 2026 Go Developer Survey

sessions

module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: MIT

README

agentsessions

A neutral, open contract — and working reference implementation — for durable agent sessions. Create, run, suspend, resume, fork, and replay an agent session, with a Bring-Your-Own-Harness SPI on top and a pluggable compute backend underneath.

It is the narrow waist for agent runtimes: producers plug in on top (an issue tracker, a chat platform, a custom app), compute plugs in underneath (pod, Kata, Cloud Hypervisor, agent-substrate), and the core knows about neither. Build an agent once; run it managed, self-hosted, or in CI — with the same identity, provenance, and suspend / resume / fork, and no rewrite when it moves.

Why it exists

Agents are becoming durable, long-running, mostly-idle workers. They need a runtime that can hold session state, suspend to free compute, resume in place, fork to explore in parallel, and attribute every action — independent of which framework wrote the agent or which cloud runs it. Kubernetes has no durable-session primitive, and most agent runtimes bind you to one framework, one compute model, or one vendor. agentsessions makes this layer an open, vendor-neutral contract anyone can implement and target — plus a reference implementation that proves the contract holds.

Neutral core, adapters on both edges

  • Producers plug in on top as adapters that map their world onto sessions and attach context via Origin + annotations. No producer-specific fields in the core.
  • Compute plugs in underneath via the Runtime SPI. No kernel-isolation technology is assumed; the same session runs on a plain pod or on agent-substrate.
  • Identity is OIDC-neutral (issuer / subject / principal).

The three contracts

  • Sessions (api/session.proto) — client-facing lifecycle: create / list / exec / suspend / resume / fork / replay / approve.
  • Harness (api/harness.proto) — Bring-Your-Own-Harness: the host drives one execution; the harness streams typed events over the Harness.Connect gRPC stream. Implement it directly, or adapt an agent framework with a thin shim.
  • Runtime (api/runtime.go) — compute / sandbox: create / snapshot / restore / stop on pod, Kata, Cloud Hypervisor, agent-substrate, or any backend that implements the SPI.

One neutral wire form (api/*.proto) with a Go SPI (api/*.go). The Event type is shared by the session log and the harness stream. See docs/architecture.md.

What's proven

This is not a paper contract. The load-bearing claims are demonstrated end-to-end, and the determinism guarantees are exercised by a replay-conformance suite (conformance/):

  • Runs on a plain pod, survives pod death, resumes by replay — no memory snapshot. Exec a turn on one incarnation, kill it, and a different one reconstructs the session byte-identically from the durable journal (sqlitelog/), invoking the model zero times.
  • Tamper-evident, language-neutral provenance. Every event is hash-chained with a canonical form (RFC 8785 JCS over proto3-JSON, canon/), so the chain is not Go-specific — a non-Go verifier reproduces the Go hash (hack/verify_chain.py).
  • Bring-your-own-harness, out of process. The harness runs behind the Harness.Connect gRPC stream (harnesswire/); the host mediates the model over the wire, so the determinism guarantees hold across the process boundary and a harness never touches a provider SDK on the replay path.
  • Runs on real agent-substrate — both capability tiers, green in CI. The conformance suite runs against a real ate-system in kind (not a mock), with both tiers on a micro-VM. STATELESS_REPLAY: byte-identical replay. REQUIRES_MEMORY_SNAPSHOT: drive → suspend (memory snapshot) → restore → the in-RAM state continues, with the chain verifying across the snapshot boundary — what a plain pod structurally cannot do. Fork fans a stateful session out to k children from one checkpoint and each continues independently. CanPlace gates the tiers, and the neutral core imports zero substrate code (a CI gate asserts it). See docs/substrate-conformance.md.

How it behaves

  • Resumability defaults to STATELESS_REPLAY — history is replayed into the harness on resume / fork, so a session runs on any runtime (even a plain pod). Stateful harnesses opt into REQUIRES_MEMORY_SNAPSHOT, which the host schedules only on a memory-snapshot-capable runtime.
  • Capability matching: a harness declares Capabilities, a runtime declares RuntimeCapabilities, and CanPlace places a harness only on a runtime that satisfies it — degrading honestly instead of resuming wrong.
  • Tool calls default to IN_HARNESS_REPORTED (fast path, reported for audit); sensitive tools opt into host-mediated execution (CONTROLLER_MEDIATED), with crash-mid-tool at-most-once re-drive. A REQUIRES_APPROVAL parks a STATELESS_REPLAY execution at a durable host-owned request. RPC/SDK Approve commits a decision only; call Resume separately. CLI approve and deny do both. Executors still need durable deduplication on session UID plus idempotency key; approval is not authorization and has no policy hook, timeout or expiry.
  • Recovery: Resume re-drives interrupted executions. An existing current approval-bearing execution also recovers through no-input Exec, using its recorded inputs/config/harness rather than request overrides. Other inputless Exec calls keep ordinary new-turn behavior.
  • Approval status: Get/List and final paused Exec frames expose pending_approval at their captured last_seq. Decisions clear that reference, but new inputs stay blocked until a receipt commits. Execution and compute axes remain independent. Retained snapshots and unresolved requests have no expiry; Cancel returns UNIMPLEMENTED. See approval recovery for SDK/CLI examples.
  • Permanent soft deletion: DeleteSession / agentctl delete --session <uid> hides the UID from List and refuses Exec, Fork (including historical forks), Resume, Suspend and Approve (including exact retries). Get and raw Replay remain audit reads; UID, metadata and journal are retained forever, without cascade or erasure. PENDING acknowledges durable intent only: actors, snapshots and fork-child pins remain retained indefinitely. No Stop or cleanup is attempted; ownership and reclamation belong to #88. See deletion semantics and admission limits.

Documentation

The same docs are published, rendered and searchable, at sessions.agent-primitives.dev, along with a walkthrough of how a turn runs and a recording of the full lifecycle on a real cluster.

The sources live in docs/:

  • Concepts: the mental model: sessions, typed events, the log, fences, resumability.
  • How you use it: what you implement, what you call, and what it deliberately does not provide.
  • Quickstart: exec / replay / fork / suspend / resume and verify the chain, locally.
  • Writing a harness: plug your agent into the api.Harness SPI.
  • Tool executors: route CLI-registered harness tools to operator-run Unix sockets.
  • Architecture: how the neutral core is built.
  • Running on agent-substrate: both capability tiers, green in CI.
  • Observability: structured request-flow logs and correlation.
  • Security posture: what is protected, what is not, and how to deploy it.
  • FAQ: what this is, what it is not, and how it behaves.
  • API reference: every message, field, enum, and RPC in agentsessions.v1, generated from the .proto comments.

The normative rules of the protocol (session lifecycle, event log, provenance chain, harness wire protocol, runtime contract, conformance classes) are in the draft specification.

Repo layout

Path What
api/ The wire proto (*.proto) + Go SPI (*.go): Sessions, Harness, Runtime, Event.
controller/ Single-writer, event-sourced core: drives one session, mediates the model, enforces the determinism invariants.
eventlog/, sqlitelog/ The durable event log: CAS + fencing token + hash chain (in-memory reference + sqlite backend).
canon/ Language-neutral canonical serialization (RFC 8785 JCS) for the hash chain.
observability/ Structured operation logging and gRPC request-correlation helpers.
harnesswire/ Bridges the in-process api.Harness SPI and the out-of-process Harness.Connect gRPC stream.
placement/ The Placer: wires Sessions to the Runtime SPI, mints/binds fences, gates via CanPlace. The Registry routes a session to the harness it names.
runtime/local, runtime/remote, runtime/substrate Runtime backends: a filesystem-only local backend, an attach-by-address backend for a harness you run yourself, and agent-substrate.
harness/echoagent, harness/counteragent, harness/chatagent Reference harnesses: STATELESS_REPLAY echo, REQUIRES_MEMORY_SNAPSHOT counter, and a history-aware chat harness.
model/openai Model provider for OpenAI-compatible endpoints; no vendor SDK, so any compatible service works.
session/ The Sessions gRPC service: the client-facing seam over the log and the Placer.
client/ Go client SDK: dialing, the session frame, pagination, and stream draining.
cmd/agentsessionsd The Sessions server: a TCP entry point over the journal and the harness registry.
cmd/agentctl Client CLI (create / list / get / exec / replay / fork / suspend / resume / approve / deny / delete).
conformance/ The replay-conformance suite (the neutral determinism checks).
integrations/substrate/ The substrate ControlClient adapter — a separate module so the core stays substrate-free.
deploy/substrate/, .github/workflows/substrate-e2e.yml Manifests + CI for the real-substrate conformance.

Container images

ghcr.io/agent-primitives/sessions/agentsessionsd:v0.2.0
ghcr.io/agent-primitives/sessions/harnessnode:v0.2.0

v0.1.x images stay at ghcr.io/aramase/agentsessions.

Multi-arch, built from the tagged source with no Dockerfile. agentsessionsd is the Sessions server; harnessnode is the in-sandbox harness the substrate manifests in deploy/substrate/ reference. The server runs as uid 65532, so mount its journal path writable.

Install

go install github.com/agent-primitives/sessions/cmd/agentctl@v0.2.0
go install github.com/agent-primitives/sessions/cmd/agentsessionsd@v0.2.0

v0.1.x stays at the module path github.com/aramase/agentsessions.

Signed archives for linux/darwin on amd64/arm64, with checksums and SBOMs, are on the latest release.

Try it

go build ./...
go test ./...                       # unit + replay-conformance suite
go test ./conformance/ -v           # just the determinism checks

For a narrated end-to-end walkthrough (exec, replay with zero model calls, fork, suspend / resume, and independent chain verification), follow docs/quickstart.md.

The real-substrate conformance (both tiers) runs in the substrate-conformance workflow (.github/workflows/substrate-e2e.yml), on every pull request that can affect it and nightly. See docs/substrate-conformance.md to reproduce it.

Ecosystem

agentsessions defines the session contract and composes with existing OSS at its seams:

  • Tools: MCP — ToolCall mirrors an MCP tool call
  • Agent-to-agent: A2A
  • Event envelope: CloudEvents — Origin = source / subject
  • Durable engine: Durable Task / Dapr — event-log / state backends
  • Telemetry: OpenTelemetry GenAI
  • Compute backends: agent-substrate, agent-sandbox, Kata, Cloud Hypervisor, pods
  • Harnesses: any agent framework via the Harness SPI, or a custom agent

API stability

agentsessions.v1 is a proto namespace, not a stability promise. The v1 names the schema, the way k8s.io/api/core/v1 does; it does not mean the schema is finished.

The Go module is pre-1.0 and makes no backward-compatibility guarantee. Both the wire contract and the Go SPI may change, and both have changed recently: the harness SPI gained a context.Context, two RPCs were removed, and ExecRequest.expected_last_seq became optional. Pin a commit if you need stability today.

What CI does enforce:

  • buf lint on every change.
  • buf breaking against the most recent release tag. This armed itself at the first release and now fails the build when the schema breaks against that tag.
  • The checked-in generated code and the API reference must match the protos, so the published contract cannot drift from the schema.

Breaking changes are called out in CHANGELOG.md. The contract is still pre-1.0, so it can break between releases; what the gate buys you is that it cannot break silently.

Status

Working reference implementation (Go 1.26). The Sessions API, the single-writer event-sourced controller, the durable hash-chained log, BYOH over Harness.Connect, the Runtime SPI with local + substrate backends, the replay-conformance suite, and real-substrate conformance across both capability tiers all run today. Session-level suspend and resume use the Placer for both resumability tiers. Snapshot(EXTERNAL) makes compute cold while retaining the handle needed to restore it; Stop remains destructive teardown, not part of suspension. The conformance suite exercises both Placer roundtrips; see the Substrate test coverage for the live tests and verification boundaries.

Not built: authentication, authorization, and transport security; a managed control plane; enterprise identity and provenance; and confidential or GPU snapshots.

Directories

Path Synopsis
api
Package api defines the agentsessions contracts: the Sessions control-plane API, the Harness BYOH SPI, and the Runtime compute SPI.
Package api defines the agentsessions contracts: the Sessions control-plane API, the Harness BYOH SPI, and the Runtime compute SPI.
Package canon defines the language-neutral canonical serialization for the event log's tamper-evident hash-chain.
Package canon defines the language-neutral canonical serialization for the event log's tamper-evident hash-chain.
Package client is the Go client for the Sessions API.
Package client is the Go client for the Sessions API.
cmd
agentctl command
Command agentctl is the client-facing CLI for agentsessions — the top seam a user or GitHub drives.
Command agentctl is the client-facing CLI for agentsessions — the top seam a user or GitHub drives.
agentnode command
Command agentnode is the co-located agentsessions node used for the pod resume demo: one binary running the controller + the echo harness + the durable sqlite journal.
Command agentnode is the co-located agentsessions node used for the pod resume demo: one binary running the controller + the echo harness + the durable sqlite journal.
agentsessionsd command
Command agentsessionsd serves the Sessions API over TCP.
Command agentsessionsd serves the Sessions API over TCP.
harnessnode command
Command harnessnode is the harness packaged to run INSIDE a compute sandbox (a substrate actor, or any runtime).
Command harnessnode is the harness packaged to run INSIDE a compute sandbox (a substrate actor, or any runtime).
Package conformance is the replay-conformance suite: the CSI/CRI-style neutral checks that any host/backend/harness combination must pass, run here against the REAL stack (the persistent sqlitelog backend + the controller + the echo harness).
Package conformance is the replay-conformance suite: the CSI/CRI-style neutral checks that any host/backend/harness combination must pass, run here against the REAL stack (the persistent sqlitelog backend + the controller + the echo harness).
Package controller is the single-writer, event-sourced core of agentsessions.
Package controller is the single-writer, event-sourced core of agentsessions.
Package eventlog is the reference in-memory event log for the agentsessions walking skeleton.
Package eventlog is the reference in-memory event log for the agentsessions walking skeleton.
harness
chatagent
Package chatagent provides a text-only conversational reference harness.
Package chatagent provides a text-only conversational reference harness.
counteragent
Package counteragent is a REQUIRES_MEMORY_SNAPSHOT api.Harness: it holds an in-RAM counter whose state is, by design, NOT reconstructable from the event log.
Package counteragent is a REQUIRES_MEMORY_SNAPSHOT api.Harness: it holds an in-RAM counter whose state is, by design, NOT reconstructable from the event log.
echoagent
Package echoagent is a trivial STATELESS_REPLAY api.Harness: it feeds the last input to the model through the host-mediated sink and lets the recorded completion be the output.
Package echoagent is a trivial STATELESS_REPLAY api.Harness: it feeds the last input to the model through the host-mediated sink and lets the recorded completion be the output.
Package harnesswire bridges the in-process api.Harness SPI and the out-of-process Harness.Connect gRPC stream, in both directions:
Package harnesswire bridges the in-process api.Harness SPI and the out-of-process Harness.Connect gRPC stream, in both directions:
integrations
substrate module
internal
agentsessionsd
Package agentsessionsd is the agentsessionsd server: it serves the Sessions API over TCP.
Package agentsessionsd is the agentsessionsd server: it serves the Sessions API over TCP.
ctxlock
Package ctxlock provides cancellation-aware serialization for invocation sinks.
Package ctxlock provides cancellation-aware serialization for invocation sinks.
modelconfig
Package modelconfig constructs the OpenAI-compatible client shared by repository-owned hosts.
Package modelconfig constructs the OpenAI-compatible client shared by repository-owned hosts.
version
Package version reports the build's identity.
Package version reports the build's identity.
model
openai
Package openai is a model provider for OpenAI-compatible Chat Completions endpoints.
Package openai is a model provider for OpenAI-compatible Chat Completions endpoints.
Package observability provides structured operation logging and gRPC request correlation.
Package observability provides structured operation logging and gRPC request correlation.
Package placement wires the Sessions layer to the Runtime compute SPI.
Package placement wires the Sessions layer to the Runtime compute SPI.
runtime
local
Package local implements the agentsessions api.Runtime compute SPI as a filesystem-only backend — the honest "plain pod" counterpart to runtime/substrate.
Package local implements the agentsessions api.Runtime compute SPI as a filesystem-only backend — the honest "plain pod" counterpart to runtime/substrate.
remote
Package remote is a Runtime backend for a harness somebody else is already running.
Package remote is a Runtime backend for a harness somebody else is already running.
substrate
Package substrate implements the agentsessions api.Runtime compute SPI on top of agent-substrate (the "actors on pre-warmed workers" runtime that memory-snapshots RAM+disk).
Package substrate implements the agentsessions api.Runtime compute SPI on top of agent-substrate (the "actors on pre-warmed workers" runtime that memory-snapshots RAM+disk).
Package session implements the client-facing Sessions gRPC service, backed by the durable sqlitelog journal and the event-sourced controller.
Package session implements the client-facing Sessions gRPC service, backed by the durable sqlitelog journal and the event-sourced controller.
Package sqlitelog is the persistent, single-writer event log backing agentsessions on durable storage.
Package sqlitelog is the persistent, single-writer event log backing agentsessions on durable storage.
Package wire converts between the hand-written api domain types (the SPI programmed against internally) and the generated protobuf wire types in api/genpb.
Package wire converts between the hand-written api domain types (the SPI programmed against internally) and the generated protobuf wire types in api/genpb.

Jump to

Keyboard shortcuts

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