KDCube
← Engineering
KDCube Engineering · Concept

One Conversation in the Harness: the Life of a Turn at Scale

One conversation, bound to one agent, traced end to end through KDCube's agent harness: how its next turn finds a machine, rebuilds exactly its own context there, works in a disposable room, runs generated code in a cell, and leaves durable results behind — at multi-user scale.

29 August 2026Engineering14 minConceptThe Relay
agent runtimemulti-user isolationconversation continuityisolated executionturn workspacecontext timelinedurable artifactory

When agents serve many users, scale and security become the same problem. Scale wants any conversation to continue anywhere, at any moment. Security wants every turn to see its own user's data and nothing else.

This article follows one conversation through KDCube's agent harness, end to end: how its next turn finds a machine, how the agent rebuilds exactly its own context there, where its files live while it works, what its generated code is allowed to touch, and what survives when the turn ends. One conversation, C1, bound to one agent, agent A, inside one app, app A — traced through a runtime that serves many users, many agents, and many apps on one shared pool of workers.

Everything here is the shipped mechanism. The documentation links at the end are the contracts each section paraphrases.

00Highlights

ConceptThe takeaway
ContinuityDurable state belongs to the conversation, in its own artifactory outside every worker. A worker's memory and disk carry nothing between turns.
The turnA turn is where scale and security meet: any free worker may run it, and everything it can reach was bound to its identities before any model output.
Context timelineThe agent's context is a timeline of the conversation's events, each with a stable reference. Bytes stay put; the timeline carries pointers, not copies.
Turn logAt turn end the harness stores the turn's timeline rows as the turn log: the ordered record of what happened, with small artifacts inlined.
WorkspaceThe workspace is a fresh directory tree on the executing machine's filesystem, populated only by what the agent pulls or produces, disposed at turn end.
ResolutionA reference only locates an object. Whether it resolves is decided by the identity bound to the turn, on every call.
Isolated executionGenerated code computes over the turn's workspace and returns results. It has no network, no shared storage, no credentials, and no way to publish.
DurabilityOnly the harness makes things durable: the turn log, the hosted file, the project's next version ref.

01The setting: continuity cannot live in a worker

Picture the deployment this story runs in: several machines, each running a pool of workers. Every worker can serve any app's agents. User 1 is in conversation C1 with agent A of app A; hundreds of other conversations, other users, other agents run beside it on the same pool.

The next turn of C1 may run on any of those workers. Turn 41 ran on machine B. Turn 42, this article's subject, runs on machine A. Turn 43 will take whichever worker is free.

Three familiar approaches to carrying context across turns fail here:

  • Pin the conversation to one process. The process's memory holds the context — and the conversation now lives and dies with that process. No horizontal scale, no recovery.
  • Share a readable directory between agents. Continuity becomes “read the files” — and one user's prompt can walk into another user's files. The directory is the breach.
  • Copy everything into every turn. History, attachments, project state, replayed into each new process. Startup cost and model context grow with the conversation, without bound.

KDCube's answer is the harness this article walks through: durable state belongs to the conversation, in stores addressed by stable references, and each turn rebuilds exactly what it needs, where it runs.

02An event finds its agent

Everything a user sends — a prompt, a follow-up, a steer — travels as an addressed event: to app A, agent A, conversation C1. The event bus is sharded; per conversation, events are ordered and durable until consumed. The event arrives in C1's own event lane.

If no live turn is working the lane, the app is pinged through on_reactive_event, and a turn starts for the target agent on whichever worker takes it. From that moment the lane has an owner: the app's lane listener drains the lane into the running turn — the opening prompt first, then whatever arrives while the turn runs — as the agent's lifecycle can take events, round by round.

AN EVENT FINDS ITS AGENT User 1 sends event · prompt | follow-up | steer to: app A · agent A · conv C1 EVENT BUS · sharded · ordered per conversation · durable until consumed C1 EVENT LANE APP A · one of the apps on_reactive_event ping when no live turn: a turn starts lane listener drains events into the running turn, in order this turn turn 41 · machine B made report.xlsx · saved the project TURN 42 · machine A continues C1: fix the project, extend the report turn 43 · any machine other users' turns run beside these
The event finds its agent; the turn finds a machine.
THE CONTRACT

A turn's events reach that same turn, on that same machine, exactly once.

A follow-up can redirect work in progress. A stop goes to turn control. An attachment arrives as a bounded preview plus a reference — the bytes stay in storage until the agent asks for them. A consent grant closes the loop on a gated tool: the tool asked, the user approved in Connection Hub, and the agent retries within the same turn.

03The context timeline: what the agent sees

The agent does not receive a transcript dump. It reads the context timeline: the conversation's events in order, each with a small context and a stable reference.

THE CONTEXT TIMELINE · HOW AGENT A SEES C1 ··· earlier events omitted t41 · made report.xlsx → conv:fi:conv_c1.turn_41.files/report.xlsx t41 · project saved → conv:fi:conv_c1.turn_41.git/projects/parser t42 · prompt · "fix parser, extend report" t42 · attachment.pdf → conv:fi:conv_c1.turn_42.user.attachments/… t42 · report.xlsx → conv:fi:conv_c1.turn_42.files/report.xlsx t42 · completion · summary → conv:ar:… bytes stay put · every row carries a stable reference · new rows pin in as the turn runs at turn end the harness stores the framed t42 rows as the turn log: conversation store · turn_42/
Rows, not copies. The framed t42 rows become the turn's log.

The timeline is a composite in two senses. Physically, every tool the harness provides speaks these references and produces reference-pinned entries: a pull, a file produced by code execution, an arriving attachment — each becomes a row as it happens. Conceptually, it is the context of the agent: what the model is fed, no matter whose model loop runs above it.

Two properties do the heavy lifting:

  • Bytes stay put. A row like t41 · made report.xlsx → conv:fi:conv_c1.turn_41.files/report.xlsx tells the agent the file exists and where — the reference names the conversation, the turn that produced it, and the path. The version is in the address: turn 41's report and turn 42's report are different references to different immutable objects. Nothing is copied into the context.
  • The timeline is kept compact by its owner. For the native KDCube ReAct agent, the running timeline is the presented view, and the agent's own compaction and pruning policies govern it. An integrated agent — Claude Code, LangGraph, or any other agent wrapped by the harness — keeps its own transcript by its own technology; the harness does not manage it, but the same tools speak the same references into it.
pull(reference)resolve a reference and fetch its bytes into the workspace, read-only, per object
checkoutcopy pulled or lineage material into the current turn's editable zone
readrender a record or a bounded preview without materializing bytes
runexecute generated code in the isolated cell, over this turn's workspace only
publishhost a selected file for the user — through the harness, never from the cell

04The turn workspace: a room on this machine

When the agent needs bytes — to inspect a file, to edit a project — the harness gives the turn a workspace: a fresh directory tree on the executing machine's local filesystem. It is born nearly empty and is disposed when the turn finishes. All workers on a machine share that filesystem; the workspace directory is the turn's own room in it.

THE TURN WORKSPACE · A ROOM ON THIS MACHINE machine A's local filesystem · disposed when the turn finishes exec_20260828T1402_ab12/ ├─ out/workdir/ │ ├─ turn_41/ pulled history · read-only │ │ ├─ files/report.xlsx │ │ └─ git/projects/parser @turn_41 │ └─ turn_42/ this turn’s writes │ ├─ attachments/attachment.pdf │ ├─ git/projects/parser/ · checked out, edited │ └─ files/report.xlsx·v2 · made by isolated Python └─ work/ internal exec scratch pull(reference) resolves and fetches bytes, read-only, per object · history keeps its turn path checkout a local copy of pulled or lineage material into this turn's editable zone born nearly empty · populated only by what the agent pulls or produces
Nothing appears in the tree by default; the agent decides what becomes local.

The project state deserves a note: for Git-mode projects, the version id is the turn. Each successful turn publishes one immutable ref; @turn_41 in the tree names exactly the state turn 41 left. The current turn's project directory is a sparse local repo over that lineage — history available, worktree populated only with what the agent materializes.

THE SEAM

Pull crosses into the conversation's stores; checkout is a local copy inside the room.

05The gate: a reference only locates

Every pull crosses one gate: authorized resolution. The reference only locates the object; whether it resolves is decided by the identity already bound to the turn — bound by the runtime before any model output, and unchangeable by anything the model reads or generates.

AUTHORIZED RESOLUTION · A REFERENCE ONLY LOCATES pull(conv:fi:conv_c1.turn_41.…) a reference of this conversation pull(another user's reference) pasted by a prompt, perhaps AUTHORIZED RESOLUTION the reference locates the object; the identity bound to the turn decides, on every call via the registered resolver bytes arrive, per object into this turn's workspace ✕ denied in place no bytes · no second path a prompt cannot widen what resolves
Same gate, two verdicts — decided by the bound identity, not by the reference.

Each reference resolves through its registered resolver — conversation references resolve against this conversation's artifactory; owner references (a task, an external object) resolve through their own providers. In every case the resolution runs as the turn's bound user. A prompt can paste any reference it likes; a reference naming another user's object produces no bytes, and there is no mount, no shared root, no second path around the gate to try instead.

THE RULE

A prompt cannot widen what resolves.

06Isolated execution: computation without authority

The agent edits the parser, adds a test, and needs to run code — and to rebuild the Excel report, it generates Python for that too. Generated code is the least trusted text in the whole system: it was shaped by model output, which was shaped by user input.

So it runs in a cell. Isolated Python executes the agent's generated code over this turn's workspace only: no network, no shared storage root — only the turn's own tree — no user, provider, or platform credentials, and no way to publish, host, or commit anything.

ISOLATED EXECUTION · COMPUTATION WITHOUT AUTHORITY THE AGENT edits · generates code · decides what to run run ISOLATED PYTHON · the cell runs the agent's generated code over this turn's workspace only ✕ network ✕ credentials ✕ publishing returns created files stay in the turn's filesystem the run and its result pinned into the context timeline storage and provider operations stay outside the cell, in the trusted runtime, under the bound identity
Results come back as facts: files in the room, rows on the timeline.

The results come back in the pattern the whole harness follows: created files land in the turn's filesystem, and the run itself — output, errors, produced artifacts — is pinned into the context timeline as rows with references. The agent reads the result, may edit and run again; the loop is ordinary work inside an extraordinary boundary. Storage and provider operations stay outside the cell, in the trusted runtime, and run under the bound identity.

THE BOUNDARY

Computation happens inside the cell; authority never does.

07The artifactory: where the conversation durably lives

Everything durable about C1 lives in one logical place this article calls the conversation's artifactory — outside every worker, addressed by stable references, and scoped: every user and every conversation has its own, with no path from one into another. It has three parts.

THE CONVERSATION ARTIFACTORY · USER 1 · C1 outside every worker CONVERSATION STORE blob folders, one per turn: turn_40/ turn_41/ turn_42/ turn log · the ordered events, each with a reference · prompt, completion, summary, tool calls inlined · + event/stream files PostgreSQL index · one row per item: ptr → turn log embedding search_tsv …/turn_42/… [0.2,…] 'exec':9B… hybrid, cross-conversation search GIT PROJECT VERSIONS turn_39 turn_40 turn_41 one immutable ref per successful turn · published host-side by the runtime HOSTED ARTIFACTS blob · indexed too user attachments what User 1 sends published files what the agent pushes; the user gets a link every user and every conversation has its own artifactory · reached only through authorized resolution · no path between them
Three stores, one scope: this user, this conversation.

The conversation store holds the turn records. The blob side (object storage; a filesystem on a single-node setup) keeps one folder per turn. Its centerpiece is the turn log: the ordered sequence of the turn's events, each with its reference — and with the small artifacts inlined: the prompt, the completion, the summary, tool calls and their results. Inlining matters operationally: retrieving a turn's transcript is one object fetch, never a scatter of small reads. Beside the log sit the turn's event and stream files and, for the native ReAct agent, the persisted running timeline.

The PostgreSQL side is the index, and it is exactly that — an index, without the content. A row points at its turn log and carries what search needs: an embedding and a search_tsv full-text vector. Prompts, summaries, and completions are indexed this way, which is what makes hybrid, cross-conversation search work: semantic and lexical retrieval find the turn; the turn log is fetched for the content. Attachments and produced files are indexed as rows too.

Git project versions are the second store: the project's text state, one immutable ref per successful turn, published host-side by the runtime. A later turn checks out @turn_41 and, on success, the lineage gains turn_42.

Hosted artifacts are the third: the blob home of files as files — the attachments User 1 sends, and the files the agent publishes for the user. Both are indexed in the same PostgreSQL index.

08Turn end: what survives

The turn ends, and the room is disposed — the workspace directory, the local scratch, everything on machine A. What survives is exactly what went through the harness:

  • The turn record, automatic. The harness stores turn 42's rows of the context timeline as its turn log in the conversation store. Future timelines are built from it.
  • The published file, the agent's push. The agent selected report.xlsx from the turn's files; it is hosted, and the user gets a link. Files the agent does not push vanish with the room.
  • The project's next version, on success. The runtime's host-side Git publishes the immutable ref turn_42.
THE MONOPOLY

Only the harness makes things durable: the turn log, the hosted file, the project's next ref.

09The next turn, anywhere

Turn 43 starts on whichever worker is free — a different machine, or the same one, or a laptop running the whole setup beside other applications; the mechanism does not change with the fleet size. Its context timeline is built from the conversation store and now points at turn 42's report and the project ref turn_42. Its agent selects again: pull what this turn's work needs, check out what it will edit, run what it generates, in a fresh room.

Nothing was carried by a worker. Everything was carried by the conversation.

10By construction

What this arrangement gives every app on the platform, without per-app effort:

  • Scale. Any free worker can run the next turn — multi-machine, multi-user, multi-agent, multi-app, or one regular laptop.
  • Isolation. Another user's data has no path into the workspace or the executor. A malicious prompt cannot widen what resolves and cannot exfiltrate what it never gets.
  • Self-proof. The harness is open source: the resolver, the workspace mounts, what is shared into the isolated cell, and the executor profile are all there to inspect. The boundary is verifiable, without a promise in the loop.

11Related articles and documentation

KDCube articles:

Documentation:

KDCube Engineering
№ 2026-08-29 · kdcube.tech