Skip to content

Provide an optional durable Agent state kernel #98

Description

@ScriptedAlchemy

Summary

Turn the full RSC example's handwritten cross-process state kernel into an
optional, reusable framework capability. Stateful applications define typed
events and state transitions; Agent Bundle supplies revisions, idempotency,
atomicity, migrations, snapshots, subscriptions, and driver boundaries.

Simple plugins remain stateless. No daemon is required.

Problem

The RSC runtime example proves shared hook/MCP state with an append-only JSONL
file, but it makes the application implement:

  • cross-process locking and owner settlement;
  • idempotency keys and monotonic state versions;
  • partial-write repair and corruption detection;
  • snapshot reconstruction and bounded history;
  • cancellation and mutation deadlines;
  • storage path identity and test isolation.

That is useful experimental evidence, not an acceptable framework authoring
burden.

Authoring model

export default defineState({
  schema: z.object({
    actors: z.record(ActorSchema),
    notices: z.array(NoticeSchema),
  }),
  initial: { actors: {}, notices: [] },
  events: {
    actorObserved: ActorObservationSchema,
    noticePublished: NoticeSchema,
  },
  reduce(state, event) {
    // Pure, deterministic transition.
  },
});

Routes access a request-bound state handle:

const { state } = await agent();
const snapshot = await state.dispatch('actorObserved', observation, {
  idempotencyKey: event.id,
});

Kernel contract

The state kernel owns:

  • atomic transactions and compare-and-swap;
  • monotonic revisions and exact-revision snapshots;
  • idempotent event dispatch;
  • schema validation and explicit migrations;
  • corruption detection and fail-closed recovery;
  • cancellation, size, time, and retention budgets;
  • subscriptions/change cursors;
  • deterministic test reset and isolated state roots;
  • observability that excludes state contents by default.

Storage drivers

Ship one production-capable local, cross-process driver suitable for desktop
agent plugins. Its implementation should use a maintained transactional store
rather than expanding the example's custom JSONL machinery into a database.

Expose a driver interface for Postgres, Redis, Convex, remote HTTP services,
or an existing authority such as TraceDecay's Rust daemon. External drivers
must preserve the kernel's revision, idempotency, transaction, and error
semantics; a disconnected adapter is not a completed integration.

In-memory storage is test-only and must never be labeled durable.

Process model

Every short-lived hook or MCP process may open the same durable store. A
long-running worker is optional and required only for applications that need
continuous background execution. The state API never implies that Agent Bundle
has started a daemon.

When a selected host reliably starts and retains a generated local MCP process,
the framework may co-locate the runtime/state worker with that process even when
the application exposes no public tools. That is an adapter-declared lifecycle
optimization, not a portable assumption: a tool-less MCP registration is not
considered a persistent service unless the real host lifecycle proves it.

The kernel does not promise autonomous retry, expiry, or timer execution from a
short-lived process. Those behaviors run on the next admitted invocation, a
connected long-lived surface, or an explicitly configured worker.

React integration

An RSC request reads one exact state revision. React cache may deduplicate
reads within that request but cannot become durable storage. A subscription or
new state revision triggers a new render; it does not mutate a completed Server
Component instance.

Acceptance criteria

  • Two independent processes safely update and read one state instance.
  • Duplicate idempotency keys produce one committed transition.
  • Retained exact revisions remain stable across later writes within the
    configured retention policy.
  • A killed writer cannot leave a successful but corrupt state.
  • Migrations are explicit, resumable or rollback-safe, and directly tested.
  • The driver survives process restart and reports typed unavailable/corrupt
    states.
  • An external driver can satisfy the same conformance suite.
  • Stateless projects include none of the state runtime or storage dependency.

Design references

Stack position

Full meta-framework stack

MCP process as an optional runtime and state host

Agent Bundle does not need a mandatory daemon to provide a useful stateful
runtime. A host-managed generated MCP server is already a potentially
long-lived process. It may host:

  • the RSC/Flight render dispatcher used by MCP tools and hook/event clients;
  • request-context providers and process caches;
  • a volatile state driver for process-lifetime coordination;
  • a configured durable driver or adapter to an external authority.

This does not mean that MCP itself stores state or that an MCP process is
durable. Hosts may restart the process, launch more than one instance, isolate
workspaces, or omit MCP entirely. State declarations therefore choose an
explicit lifetime:

type AgentStateLifetime =
  | 'request'
  | 'process'
  | 'workspace-durable'
  | 'external';

Process state is useful for warm caches, ongoing work, and consecutive events,
but it is lost on restart. Cross-process, cross-worktree, cross-thread, or
cross-host coordination requires a durable/shared driver. The compiler and
Workbench expose the effective lifetime, runtime instance identity, and
degraded states rather than allowing application code to infer durability from
the presence of an MCP server.

Acceptance must include a real MCP-hosted runtime serving tool and hook Flight
requests, restart behavior for process state, multi-instance behavior, and a
durable-driver proof where state is claimed to survive the process.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmeta-frameworkAgent Bundle compiler-coupled meta-frameworkruntimeRuntime context, state, rendering, or execution

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions