Where kslate fits
kslate is the record your agents share, plus the gateway that checks every write to it. It sits under the runtime that hosts and runs your agents, and on top of Postgres. kslate does not run agents, call models, pass messages, or decide what work needs doing.
flowchart TB
subgraph rt["agent runtimes (hosting, invocation, tools, messaging)"]
direction LR
kagent["kagent Agents"]
dapr["Dapr Agents"]
symp["Sympozium"]
end
subgraph ks["kslate"]
direction LR
gw["gateway: version · premise · lease · scope · identity"]
rec["records: fields, versions, history, checkpoints"]
gw --- rec
end
pg[("Postgres")]
kagent -->|"HTTP/JSON · MCP · gRPC"| gw
dapr -->|"HTTP/JSON · gRPC"| gw
symp -->|"HTTP/JSON"| gw
rec --> pg
The arrows only point down. Your runtime calls kslate. kslate never calls your runtime. An agent finds out that a field changed by reading the record again, either itself or through a sidecar.
What your runtime does
- Runs the agent process and makes its model calls.
- Decides when an agent runs and what input it gets.
- Gives agents their tools. kslate can be one of those tools, over MCP or a client library.
- Passes messages between agents, if your system does that.
- Decides what tasks exist. kslate lets an agent claim a task. It does not decide what the tasks are.
What kslate does
- Keeps one record per task, with typed fields and a version per field.
- Checks every write:
- the version the writer read
- the
based_onit declared - the lease on a task
- the writer’s role and identity
- that evidence is present where the class requires it
- Returns the current state to the writer when it rejects a write.
- Keeps a history of every write and every rejection. You read it with
blame,history,claimsandresume. - Stores a checkpoint per role and reports which fields changed since.
- Expires records after their TTL, and archives them if you ask.
What neither does
Settle disagreements. If two agents disagree, both writes are recorded with their author and version. If one relied on a decision that changed, kslate rejects that one. Deciding who is right is up to the agents or an operator.
Check the world. kslate checks that evidence is present. It does not check that evidence is true. If something changes in your cluster and nobody writes it to the record, kslate does not know.
With each runtime
kagent. You have two options, both in the kagent guide.
Add a RemoteMCPServer so an Agent calls kslate as a tool. Or add the
kslate-reconciler sidecar to the Agent’s pod, so an unchanged container
is driven from the record. On the sidecar path, the agent’s identity is
its pod’s ServiceAccount, checked with TokenReview. Classes are
SharedContext resources, and the controller mirrors their roles into
RBAC.
Dapr Agents. A Dapr-hosted agent calls the HTTP/JSON or gRPC API. It uses an API key, or a projected ServiceAccount token inside a cluster. kslate replaces nothing in Dapr. It is not one of Dapr’s building blocks. It is a record the agents read and write.
Sympozium. The same shape. Sympozium runs and coordinates the agents. kslate holds the record they act on and checks how they write to it.
Frameworks with their own shared board. This is the one case where kslate would replace a component rather than sit under one. An adapter would point the framework’s board at kslate, and the benchmark would measure what that substitution costs. Neither the adapter nor the run exists yet.
DeLM is the framework that run is planned against. Of the four runtimes
on this page it is the only one whose agents already share a board, so
swapping that board for kslate changes one thing and leaves the rest of
the framework alone. The other three keep their own machinery and call
get, put and append through the gateway, so there is no board to
swap and nothing controlled to compare.
The target is accuracy and cost per task within noise of the framework’s own board. No number exists yet.
What kslate is not
Not a message bus. Agents do not send each other anything through kslate. A write to a field is visible to the next agent that reads it. There is no delivery, no subscription, and no ordering beyond field versions.
Not a database. query filters a class by exact field values, with a
limit. There are no joins, ranges or text search. If you need those, keep
your own index. Use kslate for the fields agents act on and must not act
on when stale.
Not a scheduler. kslate does not run agents or decide who runs next. An agent acts when a field it reads has changed, which it learns by reading.
Not a referee. If two agents disagree, kslate records both writes with their authors and rejects whichever relied on something that had changed. It does not pick a winner.
Not a fact checker. Evidence is checked for presence, not truth. kslate knows what was written, not what is true.
One binary everywhere
Off Kubernetes you run kslate serve --policy contexts.yaml --identity apikey --apikeys keys.yaml --postgres $DSN. On Kubernetes you run the
same binary with --policy k8s-crd --identity k8s-sa. The checks are the
same code. The error bodies are the same on HTTP/JSON, gRPC and MCP.