The Runtime Protocol: What Outsiders Can Depend On
Dashboards, approval flows, and monitoring cannot depend on your prompt or your framework's internals. Give them stable objects — Thread, Run, Step, Event, Checkpoint.
Sooner or later other systems will depend on your agent system: an orchestrator triggers it, a dashboard displays it, an approval flow inserts a gate in its middle, monitoring reads its cost and causality. Those systems cannot depend on your prompt — that is written for the model and changes with every version. Nor can they depend on your framework's internals — those are written for you and vanish when you swap frameworks. What they need is a contract of stable objects and state transitions: the Runtime Protocol.
The protocol governs the outside; the runtime governs the inside
Keep two things apart. The runtime handles internal scheduling, persistence, permissions, and execution. The protocol defines the objects, operations, and state transitions external systems can depend on. A framework is not automatically a protocol — a framework implements the protocol through an adapter agent-trend-2026.
This split decides the cost of your next framework migration. Dashboards, monitoring, and approval flows hooked onto protocol objects do not change a line when you move from LangGraph to an in-house runtime. Hooked onto framework internals, every migration becomes a full-chain rebuild. MCP became the de facto standard for tool integration through the same move: it fixes the boundary and the semantics and does not care how you implement them mcp-spec.
Twelve stable objects
| Object | Responsibility |
|---|---|
| Agent | Capability provider, version, permissions, invocation entry |
| Thread | Long-lived context, participants, session boundary |
| Run | One execution, budget, state, cancellation boundary |
| Step | Observable execution units: model, tool, gate, handoff, subtask |
| Message | Content exchanged by users, agents, tools, and the system |
| Event | State, message, tool, artifact, error, and approval increments |
| Artifact | Files, reports, structured output, code diffs, evidence packs |
| Checkpoint | Recoverable state, version, pending actions |
| Interrupt | Persistent state of waiting for input, authorization, or approval |
| Workspace | Boundary of files, code, browser, and execution environment |
| Trace | Causality, cost, and audit relations between Runs and Steps |
| Error | Failure class, recoverability, suggested action |
The pairs that are easy to confuse deserve the attention. Thread versus Run is session versus execution: a Thread carries the long-lived context, and a Run is one execution inside it, with a budget and a cancel boundary. Interrupt expresses "waiting for input" or "waiting for approval" as a persistent state rather than an in-memory flag — it survives a process restart, which is what gives events consumed only at safe points a place to land. Error must carry a failure class and recoverability, because "is a retry worth it" is the first question of any recovery decision — the entry point of classify failures before counting them.
Five hard rules for the protocol
- Stable IDs: Thread, Run, Step, Event, Artifact, and Checkpoint all carry stable IDs;
trace_id/event_id/run_id/step_idare built in otel-genai. - Clear ownership: every Event, Artifact, Error, and Approval belongs to a concrete Run, and the causal chain stays traceable.
- Versioned: the protocol schema, the state machines, and the error codes all carry versions, so consumers evolve by version instead of being broken by your upgrade.
- Transport-agnostic: the same semantics run over HTTP, a message queue, or a CLI; different transport bindings implement one protocol.
- First-class objects: Workspace and Artifact are managed as first-class objects; files and outputs are not the runtime's private property langgraph-platform.
Do not leak framework internals into the protocol
What does not belong in it: the framework's Nodes and Reducers, the model's private reasoning. The moment an external system starts consuming those, you have promoted implementation details into contract — every internal refactor becomes a breaking change, and the more outsiders hook on, the tighter you are locked in.
To judge whether an exposure belongs in the protocol, ask one question: after the framework is replaced, would the consumer still need it? If yes, it is protocol semantics — it goes in. If no, it is an implementation detail — it stays in the runtime. This is long tasks need handoff artifacts and terminal states at a different scale: the handoff package frees the next session from depending on the last conversation; the protocol frees external systems from depending on your internals. Replacability is not a claim you make — it is proven by nothing on the outside having to move.
