Multi-agent Collaboration with Tuple Spaces

Nature uses two entirely different architectures to coordinate complex behavior. The first is direct message passing, routing signals point-to-point along established connections, the way neurons fire across synapses. The second is stigmergy: coordinating agents that cannot or will not talk to each other directly by leaving traces in a shared medium. An ant does not message the other ants; it deposits a pheromone, and the next ant that passes is influenced by the trace. Coordination lives in the medium, not in the participants.

Today's multi-agent frameworks almost exclusively emulate the neural path: their agents send each other messages, a transcript accumulates, and a control loop decides who speaks next. But the stigmergic alternative, agents reading and writing a shared space of facts and coordinating by what is there, has a fifty-year formal pedigree. It is not one idea but three stages of one idea: the tuple space is stigmergy made formal, and dao.space is that formal stigmergy made durable. This piece walks the lineage and shows what each stage contributed.

Stage One: The Blackboard Model (1970s AI)

The shared-state coordination idea was born in classical AI, in speech understanding. Hearsay-II (1971 to 1976) had to combine the opinions of many specialists, a phoneme recognizer, a syllable hypothesizer, a syntax module, a semantics module, into a single answer. Rather than wire the specialists to call each other, it gave them a shared workspace called the blackboard, and let each read what the others had written and contribute when it had something to add.

The blackboard model, as later codified by Penny Nii, has three parts:

  • The blackboard itself, a shared, structured workspace where partial solutions accumulate.
  • Knowledge sources, independent, self-contained specialists, each with its own expertise, that watch the blackboard and contribute opportunistically.
  • The control shell, a scheduler that watches the state of the blackboard and decides which knowledge source fires next.

The breakthrough was the decoupling. Knowledge sources never address each other directly; they communicate only through the shared board, so a specialist can be added, removed, or replaced without rewiring the others. That property is the whole reason the pattern keeps getting rediscovered, by the current generation of LLM agents, among others.

The limitation was the third component. The control shell is a central scheduler, the one place that decides who acts. Scale the system up and the scheduler becomes the bottleneck; it is also a single point of coordination that every participant depends on. In biological terms, the blackboard was almost stigmergy: a shared medium that agents transform rather than address each other through, but it kept a scheduler, and a central authority deciding who acts is orchestration, not stigmergic emergence.

Stage Two: Linda and the Tuple Space (1985, Parallel Computing)

In 1985 David Gelernter generalized the blackboard into a coordination language called Linda, and in doing so removed the central bottleneck. A Linda system has a shared tuple space, a bag of typed records, and four operations: out writes a tuple, in reads and removes one, rd reads one without removing it, and eval spawns work. Most importantly, in and rd match associatively, by pattern rather than by address, and they block until a matching tuple appears.

The decisive change is what Linda dropped: there is no control shell. Coordination is not scheduled by anything; it emerges from the data structure itself. A producer drops a tuple and walks away; a consumer that arrives an hour later finds it. Producers and consumers are decoupled in time, in space, and in reference, what Gelernter called generative communication. The blackboard's central scheduler is gone, and with it the controller bottleneck. This was true stigmergy at last, coordination emerging purely from the accumulated state of a shared medium, with no authority anywhere; the medium just had not been built to last.

The idea was compelling enough that Sun Microsystems canonized it as JavaSpaces (part of Jini) in the late 1990s, bringing the tuple space to enterprise distributed systems. JavaSpaces added a crucial innovation Linda lacked: mobile code. By taking advantage of Java's dynamic class loading, it allowed agents to drop objects containing both state and behavior directly into the space for others to download and run. But the tuple space lost the distributed-systems war to message-passing channels anyway, and for a reason that connects straight back to the blackboard's old weakness. Associative matching still has to happen somewhere. In most Linda implementations (including JavaSpaces), the tuple space was a centralized server that did the matching. In theory, the controller was gone. In practice, the bottleneck didn't disappear; it just moved from a central scheduler deciding who acts, to a centralized matcher evaluating patterns. Channels won because routing by address is cheaper, and more obviously scalable, than matching by pattern.

Tuple spaces were also never built for the setting agents now face: durable facts, many concurrent writers, content-addressed identity across writers, and participants who do not trust each other. They were a coordination formalism for cooperative parallel processes inside one trust domain. The idea was right; the engineering around it was thin.

Stage Three: dao.space, the Tuple Space Combined with Datomic

dao.space keeps the tuple space's controller-free, associatively matched shared state, and finishes the job the tuple space left half done by borrowing from a different tradition entirely: Datomic. Datomic is a database built on the same Lisp lineage, and it carries one discipline the tuple space never had: a strict separation of transactor, storage, and query into three boundaries. dao.space treats those boundaries as swappable interfaces rather than fixed deployment roles. Grafting that discipline onto the tuple space is what resolves the limitations of both prior stages, and what turns the stigmergic medium from something ephemeral into something that lasts: durable stigmergy.

Fundamentally, a dao.space is not a monolithic worldwide server. They operate like email servers: decentralized, independently operated, and federated. A single space enables stigmergy among its local agents, but once content-addressed identity is fully load-bearing, it will enable stigmergic coordination across other spaces. Agents will be able to leave traces that propagate or are queried across boundaries, weaving a global stigmergic medium out of independent nodes.

Where Datomic's three boundaries land on the tuple space:

  • Transactor (write), decentralized. Datomic has one transactor. Here every agent appends atomic transactions to its own local dao.stream and publishes covered indexes into an explicit DaoJing intake pool. There is no shared write surface or global clock; each writer owns its log.
  • Storage, deliberately dumb. This is the move that finally kills the matcher bottleneck. dao.jing observes its supplied intake pool and materializes each opaque payload under an address derived only from its content. Its backend is a plain-data handle with explicit put-content and get-content functions, not a mutable root store. It does not know what a datom is. It does not match. The tuple space's centralized matcher is dissolved into opaque blobs.
  • Query (read), embedded in every reader. Matching and Datalog are a pure library each interpreter links and runs in process, pulling B-tree segments lazily from storage and building its own index. The matcher that centralized in Linda is now distributed across every reader, so reads scale infinitely by simply adding readers, exactly as a Datomic peer does. The index-once refinement lets each stream's owner persist its own B-tree segments and readers merge them, so the work is done once and reused by many.

Taken together, these three boundaries dissolve the old centralized matcher into the stigmergic medium itself: writers deposit, readers interpret, and the store just holds, like pheromones on a substrate.

Three more ideas come along, and each one closes a gap the tuple space never closed:

  • Facts are immutable datoms with time. A datom is a five-tuple (e a v t m), entity, attribute, value, a time point, and a metadata slot for provenance and policy. Where Linda's tuple was a generic bag of typed fields, dao.space narrows and names the slots, so every fact carries identity, time, and provenance by construction. Storage is an append-only log, so history is never overwritten and as-of queries time-travel to any point. The tuple space's destructive in becomes an append; current state is a read-side query over accreted facts. Who asserted what, and when, is part of the data, not a reconstruction.
  • Content-addressed identity. Datomic identifies facts immutably; dao.space extends the idea so that two streams can agree they mean the same entity by a join on shared values, never by assuming id 1025 means the same thing everywhere. Independent sources stay separate database inputs with stream-local ids, so equal ids across streams never merge implicitly; readers join across streams deliberately, on shared values. (Corrected August 15, 2026: an earlier version of this paragraph described a folded namespace slot.)
  • The code itself is data. JavaSpaces pioneered mobile code in the tuple space, but the dropped objects were opaque: serialized bytecode you download and run, not data you can query. dao.space takes the next step: the code itself is transparent, queryable data. yin.vm AST and continuations (paused executions) are stored as datoms in the exact same tuple format, so the medium holds computation and not just data. An agent can suspend and another can read its continuation and resume it; computation migrates through the store the way facts do, a coordination primitive no message-passing framework offers. This is executable stigmergy, and it deserves its own treatment elsewhere. The point here is that dao.space is not merely a fact store but a store of resumable computation.

Then dao.space adds one move Datomic never had to make. Datomic assumes a trusted transactor and a single operator; agents do not have that luxury. So dao.space adds a trust boundary that the tuple space and Datomic both lack, stated as "share governed computation, not data". When it is safe to ship the datoms, public mode lets a reader embed the library and pull streams directly, with only coarse per-stream access in the POSIX tradition. When it is not safe, the topology inverts: the reader submits a governed interpreter, a confined AST wrapped in a cryptographically authenticated capability, that runs scoped to the authorized datoms and returns only the bounded result. The owner is the mediator by default; a multi-party-computation circuit removes even that. The unit of sharing is a governed computation over an immutable log, not a row the recipient can copy.

What Coordination Looks Like in Practice

The payoff is that multi-agent coordination collapses into queries over accumulated facts, with no coordinator and no protocol to build. The canonical example is work claiming. A worker finds posted tasks that nothing has claimed, and claims one by appending a fact. No broker, no message-format negotiation, no leader election. This is stigmergy, agents coordinating by leaving traces in a shared medium, the way ants coordinate through pheromone trails.

;; find posted work no one has claimed: a join and negation over the whole store
(query/q '[:find ?w ?task
           :where [?w :work/posted true]
                  [?w :work/task ?task]
                  (not [_ :work/claims ?w])]
  space)

;; claiming is an append, not a destructive take
(ds/put! log {:db/id (random-id) :work/claims ?w :work/by worker-id})

It is worth being precise about what this does and does not guarantee, because the naive version hides a familiar race. Two workers can run the claim-finding query before either appends, and both then append a claim to the same task. That is not a bug the storage layer papered over; it is a real consequence of check-then-act over an append-only log. The resolution is the ultimate expression of stigmergy: there is no lock, and no cas! over a shared stream to force exclusion at write time. Both claims are simply recorded immutably in their respective owners' logs.

The conflict is resolved entirely on the read side. Because the semantics of exclusion are external to the stream and live in the agents' interpreters, arbitration is just another query rule. The downstream interpreter sees both claims and applies an explicit winner rule over a genuinely comparable value, or another deterministic convention of its choosing, deterministically yielding exactly one winner. Per-stream transaction counters are not a shared clock, so ordering the two claims by their local t would be arbitrary, not meaningful. (Corrected August 15, 2026: an earlier version said readers sort claims by timestamp and break ties by worker ID; t is stream-local, so the winner rule must use a genuinely comparable value.) The storage layer does not need to understand what a claim is, nor does it need to enforce hard exclusion. The coordination emerges purely from how the agents interpret the accumulated traces. Contrast a message-passing world, where the same race is resolved by a central coordinator agent you now have to build, operate, and recover from failure.

That example shows the model working as designed.

Bootstrapping Direct Links

While dao.space provides pure stigmergy, the broader datom.world architecture does not force you to choose one path exclusively. It supports both the neural and the stigmergic models, and uses the latter to bootstrap the former. Agents can, and do, establish direct message-passing lines by opening dedicated streams that the other agent tails. The strict invariant is that two agents never write to the same stream. If 1,000 agents want to talk to one agent, they don't fight over a shared inbox; they append to 1,000 distinct single-writer streams, and the recipient lazily merges them all on the read side. The only time cas! is used is by a single writer advancing its own pointer, purely for mechanical safety: protecting the stream from concurrent write corruption if a network retry duplicates a request or a split-brain partition spawns a zombie duplicate of the agent.

Because a dao.stream is itself represented by datoms, dao.space acts as the decentralized discovery mechanism. Agents use the stigmergic medium to leave traces declaring their existence, their capabilities, and the addresses of their streams. Other agents query the space to discover them, and then seamlessly switch to direct, point-to-point neural interaction when tightly coupled coordination is needed. Stigmergy provides the shared substrate; the direct topology emerges dynamically from the traces.

Where the Lineage Is Not Yet Finished

The gap between the arc above and what is built is worth stating plainly so the lineage does not oversell:

  • Content-addressed identity, the part of the Datomic inheritance meant to make cross-stream identity gauge-invariant rather than stamped, is only partially realized. Datom frames are hashed via pr-str, not the canonical byte encoding the spec mandates, and the index still allocates integer entity ids. The content hash is not yet a portable join key.
  • Controlled mode, the trust boundary that goes beyond both tuple spaces and Datomic, is specified but out of scope for v1. v1 ships public mode only.
  • Lower-level lazy B-Tree restoration now runs on every platform, and query uses it: current views over published indexes are answered lazily, fetching only the slices a query touches. History and time-bounded reads still walk eagerly. (Corrected August 15, 2026: this bullet previously said the lazy B-tree pull lacked a Dart target; lazy restoration is cross-platform now. Updated August 18, 2026: the then-remaining gap, that query did not use the lazy path, is closed for current views.)

None of this changes the API or the boundaries. It sets the order of work after v1, and most of it is finishing the Datomic inheritance rather than inventing anything new.

More on the storage boundary in the writeup on building a distributed database on immutable streams, and on separating representation from interpretation in the semantics piece.

The Bet

The shared-state coordination idea has now been reinvented three times. The blackboard gave it shared state but kept a controller. The tuple space removed the controller but left matching centralized, and never solved durability, multi-writer consistency, or trust. dao.space takes the controller-free tuple space and finishes it with Datomic's storage, query, and time-travel disciplines, plus a trust boundary of its own. Each stage fixed what the one before could not.

This is a bet: that multi-agent systems will grow into needing accountable, decentralized shared truth, and that the current ecosystem is still in the phase where a transcript plus a vector index is enough. dao.space is what that bet looks like when you build it out instead of just placing it. It is early. The hardest part, content-addressed identity that makes cross-stream joins gauge-invariant, is unfinished, and controlled mode is specified rather than shipped. But the lineage is honest about where it stops. When agent systems finally hit the wall that long-lived, multi-tenant, mutually distrusting participants always hit, the substrate they reach for will look like this, and it will have a fifty-year-old idea at its core.

Related: