KDCube is an agentic platform — an app can run many agents: build your own, bring Claude Code, or mix them. ReAct is our resident agent, the one we ship and run ourselves: built to work robustly in a distributed, isolated runtime, with its own skills, tools, and a real file workspace. Apps aren't forced onto it — it's just the agent we make first-class. Today's entry is about a small improvement to how ReAct understands and controls that workspace.

Inside a conversation it works in turns, and inside a turn it takes small steps: act, see the result, then decide the next move. To do real work it reads files, edits them, and runs code. Two facts make its workspace tricky, and one simple rule makes it safe.

Fact 1 — the workspace is rebuilt every turn

Every turn can start on a different machine with an empty workspace. The only thing carried in is the conversation timeline (which we cache). So nothing you produced last turn is sitting on disk now — only a reference to it survives across turns.

Fact 2 — the workspace is semantically rich, not a flat folder

The agent doesn't see one undifferentiated folder. It understands kinds of workspace — each with its own meaning, storage, and lifecycle — and puts each thing where it belongs:

TURN_<CURRENT>/ — ONE WORKSPACE, MANY KINDS files/ continuous projects — code, the whole project tree git · versioned outputs/ ad-hoc files, reports, exports, binaries object storage snapshots/ story / wizard state snapshot store attachments/ · external/ user uploads, rehosted event data hosting cnv: task: mem: … objects owned by other systems proxy · fetch first Putting a project in versioned files/ vs a one-off export in outputs/ is the agent's competence — control, not just storage.

Knowing that a project belongs in versioned files/ while a one-off export belongs in outputs/ is part of the agent's competence — that's control, not just storage.

The one rule — pull first

Because every reference is virtual until you ask, to use anything you first pull it. That turns a pointer into real local bytes for this turn — even for proxies. Only then can the agent work with it:

fi:report.md cnv:conversation-7 task:issue-42 an attachment virtual pointers — nothing on disk yet react.pull materialize the bytes locally, for THIS turn — works for proxies too now it physically exists in the workspace react.read explore it — bring itinto the agent's timelineas blocks the model sees react.checkout an editable copy in thecurrent turn — for whenyou will edit it exec (code) work with it like afilesystem, in code —when that tool is wired All three need the bytes local — so they all start with a pull.

A logical ref (fi:…, cnv:…, an event, an attachment) is only a pointer. pull makes it real and local. read brings it into the agent's timeline as blocks it can actually see; checkout gives it an editable copy in the current turn; code execution lets it work with it like a filesystem. All three need the bytes to be local — so they all start with a pull.

The live view — always in front of the agent

The timeline is the durable, cached record of the conversation. But some things change every single round and must not be cached: the budget, live user interrupts, and what is in the workspace right now. So the agent keeps a small, always-on live view in front of it — a designated area of heightened attention for the immediate, volatile signals it must not lose track of, recomputed each round.

Where the live view sits

Everything the agent sees arrives as one ordered input. First a stable envelope: its instructions, then the catalog of tools it can call and the skills it can run. Then the timeline of events, oldest → newest — history, this turn's request, and the progress so far. And always at the very tail, the live view.

The agent knows its attention board — the volatile, immediate signals — lives there, last, on every round. The front of the input is stable and cacheable; the live view is recomputed each round, so it can change between rounds, not just between turns.

WHAT THE AGENT SEES — ONE ORDERED INPUT, LIVE VIEW ALWAYS LAST Instructions runtime + this app's + domain instructions (+ optional suffixes) Tool catalog the tools this agent can call Skill catalog the skills this agent can run Timeline — oldest → newest history this turn's request progress so far oldest The live view ALWAYS LAST the volatile, immediate-signals attention board the agent always sees stable prefix · cacheable volatile tail · never cached · recomputed every round The front of the input is stable and cacheable; the live view is recomputed each round, so it can change between rounds, not just between turns.
One ordered input — the stable envelope first, the live view always last.

What we improved today

The live view now shows the agent a live map of its workspace, in two halves:

  • LOCAL — exactly what is materialized on disk this turn. If it's here, the agent just reads or edits it.
  • REMOTE — the top-level projects from its latest committed work, ready to pull, with a single anchor that tells it precisely how to build the pull link for any of them.
THE LIVE VIEW · [WORKSPACE] — A LIVE MAP, REBUILT EVERY ROUND LOCAL on disk THIS turn — read / edit it directly turn_…15-36-43/ current · EDITABLE files/ weather_cli/ weather.py formatter.py README.md outputs/ snapshots/ pull make it local REMOTE not local until pulled latest committed turn — the single anchor turn_2026-06-22-15-36-43 that one anchor builds every pull ref: fi:turn_<anchor>.files/<project> projects you can pull: weather_cli analytics_dashboard At a glance: what is already local versus what it still has to pull — so it pulls before it reads, edits, or runs code.

Before, the agent could see a reference to a file it made last turn and wrongly assume it was still on disk — then fail the moment it tried to use it. Now it can tell at a glance what is already local versus what it still has to pull, so it pulls before it reads, edits, or runs code — and stops tripping over the very objects it should have fetched first.

KDCube Shorts · 22.06.2026