# State Without a Landlord: Durable Workflows Without a Single Owner

A durable workflow survives crashes, deploys, and `sleep("7d")`. It can do that because the running process never holds the state. The journal does. Every step's input and output are recorded, and on resume, the orchestrator re-executes from the top and reads each result back from the log instead of running the step again.

This means the journal is the one thing you absolutely cannot lose. Right now, it exists in just one place: a vendor’s managed store, a cloud service, or your own database. Whoever runs that store has the only official copy. The workflow cannot continue without them, and switching providers needs their cooperation.

We call this role a landlord. This is just a technical term. Most operators in this position are capable, trustworthy, and affordable. We are one of them. [Platformatic World](https://blog.platformatic.dev/durable-workflows-kubernetes-version-safe) is our self-hosted Kubernetes environment for [Workflow SDK](https://github.com/vercel/workflow), and its journal is managed by a single administrative domain, just like other production Worlds.

Our new paper, [State Without a Landlord](https://arxiv.org/abs/2609.17645), explores what happens if the journal becomes an authenticated, append-only log that is shared among everyone involved in the workflow.

The paper covers two main points:

*   **An observation:** a durable workflow journal is already, structurally, a peer-to-peer log.
    
*   **A proposal:** a P2P World for Workflow SDK, where storage, queuing, and authentication resolve to swarm primitives instead of one operator's infrastructure.
    

One point describes the current reality. The other outlines what could be built on top of it.

This is an architecture proposal, not an implementation. Each claim in the paper is marked as established, proposed, or open, and the last section lists experiments that could disprove it.

* * *

## **Why code portability is not enough**

Vendors of durable execution often claim there is "no lock-in," and at the code level, that’s true: the same workflow can run anywhere. But things are different for workflows that are already running.

For example, imagine a procurement workflow between two companies. Your team gets a vendor quote, and both ACME’s manager and director need to approve it before the order is placed. The approval period lasts 14 days, so the workflow is idle most of the time.

Someone needs to host the workflow, and everyone else must trust that host’s record. This leads to four main issues, listed from least to most serious:

*   **State lock-in:** Switching providers mid-run means you have to finish every workflow first, which is impossible for long-running or sleeping workflows. If you can only move code but not state, portability only works for new projects.
    
*   **Availability coupling:** In theory, a workflow could resume anywhere, but in practice, it can only resume where its journal is accessible. So, a system designed to survive failures still relies on a single piece of infrastructure.
    
*   **Unverifiable history:** The journal is just rows in someone’s database. Anyone with access can change a step’s result, and replaying the workflow will recreate the altered state.
    
*   **Multi-party runs need a landlord:** For example, ACME’s approval exists only as a row in your database, or your approval exists only in theirs.
    

Human-run systems can handle this because people work slowly and resolve disputes outside the system. Agent-based systems can’t. When autonomous agents from different organizations run workflows, you can’t assume the parties are known ahead of time, that disputes are rare, or that runs are short. These workflows need state that is shared, independently verifiable, and portable between executors.

This is a peer-to-peer replication problem, and it has already been solved twice by communities working on other problems.

* * *

## **The journal is already a P2P log**

Durable execution relies on three things. The journal is the workflow: together with the code, it fully defines the state. The journal is append-only, with just one writer per run. Replay is deterministic, so anyone with the right code and journal can take over as executor.

[Hypercore](https://docs.pears.com/), the log underneath the Pear stack, has the same shape. A core is identified by a public key. Only the holder of the private key can append. Every block is signed and covered by a Merkle tree, so any peer can replicate any subset and verify it without trusting the peer that served it. A writer that rewrites history produces two signed blocks at one sequence number, which is cryptographic proof of its own misbehaviour.

When you compare them, the similarities are structural:

<table style="width: 676px;"><colgroup><col style="width: 260px;"><col style="width: 416px;"></colgroup><tbody><tr><td colspan="1" rowspan="1" colwidth="260"><p>Run journal</p></td><td colspan="1" rowspan="1" colwidth="416"><p>Hypercore</p></td></tr><tr><td colspan="1" rowspan="1" colwidth="260"><p>Executor identity</p></td><td colspan="1" rowspan="1" colwidth="416"><p>Core keypair: the append key is the right to advance the run</p></td></tr><tr><td colspan="1" rowspan="1" colwidth="260"><p>Executor rewrites history</p></td><td colspan="1" rowspan="1" colwidth="416"><p>Fork proof: silent in a database, evidence in a core</p></td></tr><tr><td colspan="1" rowspan="1" colwidth="260"><p>Resume after crash</p></td><td colspan="1" rowspan="1" colwidth="416"><p>Replication plus replay, by any authorized peer</p></td></tr><tr><td colspan="1" rowspan="1" colwidth="260"><p>Hooks and approvals</p></td><td colspan="1" rowspan="1" colwidth="416"><p>Autobase over each respondent's own core</p></td></tr><tr><td colspan="1" rowspan="1" colwidth="260"><p>Large step payloads</p></td><td colspan="1" rowspan="1" colwidth="416"><p>BitTorrent v2 objects, referenced by infohash</p></td></tr><tr><td colspan="1" rowspan="1" colwidth="260"><p>"Where is run X?"</p></td><td colspan="1" rowspan="1" colwidth="416"><p>DHT topic derived from the run key</p></td></tr></tbody></table>

The single-writer rule is crucial. Trying to let multiple masters update workflow state would create a consistency nightmare, which is where many decentralization ideas fail. Durable execution already avoids this. Only one executor advances a run, and everyone else just reads until there’s a clear handoff. Hypercore uses a keypair to enforce the same rule that today’s engines enforce with a lease row in a database.

The same goes for determinism. Autobase needs a deterministic apply function over ordered inputs. Developers who already avoid using `"Date.now()"` in workflow code have accepted this rule.

* * *

## **Two planes, joined by hashes**

![](https://cdn.hashnode.com/uploads/covers/63f78b3e207712e9dab049ad/ae86363c-ec3c-4692-8e1d-e11e50a92ec4.png align="center")

This architecture separates live coordination from bulk distribution:

*   **Coordination plane:** Hypercore and Autobase journals. Small, live, signed, totally ordered.
    
*   **Distribution plane:** BitTorrent v2 swarms. Large, immutable, content-addressed.
    

A journal shouldn’t include a 2 GB model checkpoint or a container image directly. Instead, it holds a 32-byte infohash, and the actual data moves through infrastructure that’s been tested for decades in tough conditions. Facts point to data by hash, but the data itself doesn’t carry authority.

The workflow bundle and the engine build are pinned the same way. The run manifest names both by infohash, so replaying against the wrong code version becomes structurally impossible instead of operationally avoided. We built [Platformatic World](https://blog.platformatic.dev/durable-workflows-kubernetes-version-safe) around that exact hazard on Kubernetes. Content addressing removes it at the data-model level.

* * *

## **Resuming a run you did not start**

If the executor crashes while the procurement run is waiting on ACME, a standby or any participant with the right keys can resume it in five steps:

1.  **Fetch.** Join the DHT topic for the run, replicate the journal from any peer holding it, and verify every block against the Merkle root.
    
2.  **Pin code.** Read the bundle infohash from the manifest, fetch it from the swarm, and verify it by content address.
    
3.  **Authorize.** Succession has one path: an `epoch.open` record in the run's coordination channel, grounded in a voluntary handoff, a fork proof, or a lapsed liveness challenge, and finalized by the run's indexer majority.
    
4.  **Replay.** Replay the orchestrator against the verified chain and pass two gates before acting.
    
5.  **Advance.** Append new step records to a fresh epoch core. Every replica sees the run resume, and sees who resumed it.
    

There are two checks in step 4 for a reason. A hash of the state, built from the journal, is a pure function of the journal itself. Any engine reading the same log gets the same hash, so matching hashes don’t tell you anything about the engine. The paper introduces a next-intent record: at each pause, the executor commits to the next call its replay will make, including the call site, call index, and argument hash.

A resumer first checks the transcript hash, which catches differences in schema or decoding. Then it replays and checks its own next intent, which catches engines that agree on history but are about to make a different call. If there’s a mismatch at either step, the resumer stops before making any changes.

* * *

## **Fencing by topology, not by promise**

No capability record in another log can stop a key from signing. If handoff means sharing the run core's secret key, the predecessor keeps it forever. Fork detection is evidence after the fact, not revocation.

So a run isn’t just one Hypercore. It’s a chain of epoch cores, with one single-writer core for each executor’s time in charge. An epoch ends with a closure certificate that commits to the authenticated tree root, not just the length, because a dishonest core could have two signed trees at the same length. After the certificate is finalized, the old key can still add to its own core, but those entries appear after the finalized length. Anyone following the chain sees these as post-close writes by a fenced writer; they’re evidence, not state. This is the classic fencing-token pattern, applied to log structure.

Four invariants carry the safety argument:

*   **I1. Unique succession.** An epoch has at most one finalized successor.
    
*   **I2. Unique history.** A finalized epoch prefix identifies exactly one authenticated history.
    
*   **I3. Durable means survivable.** Every acknowledgment that can survive a failover also survives any allowed epoch transition.
    
*   **I4. Fence before fire.** No executor starts an external effect until its epoch is the finalized chain head and the effect’s intent record is durable.
    

Liveness eviction doesn’t assume that silence means failure. An unresponsive executor could be dead, disconnected, or just slow, and no group of witnesses can always tell the difference. Eviction is based on a timeout certificate: a quorum of indexers each confirm, using their own timers, that a challenge wasn’t answered. This allows an epoch to close. It’s not proof of a fault; the goal is to limit any mistaken eviction so it can be fixed and never cause corruption.

* * *

## **Durability is a dial with stated prices**

In a centralized World, durability is confirmed by a database commit behind the scenes. In the P2P World, it’s an explicit policy set for each run:

`ack: "local" | { replicas: number } | "survivable"`

*   **"local"** commits on local append. Hosted-World latency, no protection against executor loss or false eviction.
    
*   **{ replicas: k }** commits when k replicas hold the block. Crash durability, but the entry can still be orphaned by a legitimate epoch closure.
    
*   **"survivable"** commits when an acknowledgment certificate from the indexer set is finalized in the coordination view. It is the only level invariant I3 protects, and it costs a coordination-finality round trip. Effect-bearing steps default to it.
    

The certificate threshold is a = max(ceil((N+1)/2), N - q + 1) for N indexers and finality quorum q. The second term guarantees every certificate intersects every finality quorum. The first guarantees that certificates on two conflicting branches cannot both exist under crash faults.

The P2P World is slower than a local database in microbenchmarks, as expected. But it offers joint custody, verifiability, and executor portability features you can’t get from a local database at any speed. The trade-off is clear and priced per run, not hidden.

* * *

## **What signatures can’t prove**

Signatures and Merkle proofs confirm authorship and order. They never establish truth. A malicious executor can append a valid, non-forking `step.end` recording an outcome that never happened, and every peer will verify and preserve the lie.

The threat model states which guarantees hold where:

*   **T1, crash-only.** The design target. No lost or corrupted state given surviving replicas; resume by any authorized keyed peer; divergence detected at resumption seams.
    
*   **T2, rational or misbehaving participants.** Evidence, not prevention: fork proofs, certificates, audit trails.
    
*   **T3, Byzantine indexer majorities and network adversaries.** Out of scope, with the degradations stated.
    

The paper discusses two more limitations in separate sections.

Exactly-once external effects aren’t possible in any World, centralized or not. The process is: record the intent, make it durable, make the call with an idempotency key based on (runId, seq, attempt), and record the outcome. If a successor finds a `step.begin` without a `step.end`, it repeats the same call, and an idempotent target gives the same result.

Resuming a run means running its code. Node.js isn’t a sandbox, and neither is Bare. In the procurement flow, if ACME’s standby resumes the run, ACME ends up running your step code on their own infrastructure. The proposed solution is step ownership: no one ever runs another party’s effectful code. Foreign steps are handled like hooks, and the owner’s signed result is used at finality. The orchestrator just replays under the determinism profile, making it the only shared code and the part that can be sandboxed in an isolate or WASM.

* * *

## **Workflow code stays the same. The engine does not.**

The procurement flow is written exactly as it would be against a hosted World:

```typescript
"use workflow";
export async function procurement(req: PurchaseRequest) {
 const quote = await fetchVendorQuote(req);                 // "use step"
 const approval = await hook<Approval>("acme-signoff", {
   grantedTo: [ACME.managerKey, ACME.directorKey],          // other org's keys
   quorum: 2,                                               // both must sign
   deadline: "14d",
 });
 if (!approval.granted) return await notifyRejection(req);  // "use step"
 return await placeOrder(quote, approval.receiptRef);       // "use step"
}
```

In a hosted World, hook(...) creates a callback URL, and the host’s database records who called it. In the P2P World, it adds a `hook.await` with ACME’s keys. The approval that lets the run continue is ACME’s own signed entries on their own cores, ordered by Autobase and only acted on at finality. No organization hosts the other’s approval.

"Code unchanged, only a new World" is just a hypothesis, and the paper measures the gap. The real @workflow/world contract covers much more than storage and queues. The architecture also needs features that no World interface currently provides: stable call-site IDs, call-index generation, standard argument hashing, exposing the next suspension intent during replay, and a determinism profile that goes beyond just avoiding `Date.now()` and `Math.random()`. These require changes to the compiler and runtime.

The accurate claim is that the workflow source code stays the same. The SDK, compiler output, and execution engine underneath do not.

* * *

## **No flag day: the Mirror World**

No one adopts a new state layer all at once. The adoption path has three phases of shifting custody, not three separate rewrites:

1.  **Mirror.** A World decorator writes every journal entry to the hosted store and to a run core. The hosted store stays authoritative. Participants obtain verifiable replicas and an exit path that does not require the vendor's cooperation.
    
2.  **Custody flip.** Run cores become authoritative, per run or per application. The flip is reversible by mirroring in the opposite direction, because export and import have collapsed into one operation: replication.
    
3.  **Native.** P2P World only. The vendor is one competitor in markets for fungible roles: superpeers, blind replicas, wake services, capability gateways.
    

![](https://cdn.hashnode.com/uploads/covers/63f78b3e207712e9dab049ad/a1ce1af6-bb1e-414b-9377-610068ccc118.png align="center")

Phase 1 acts as insurance, and insurance comes with costs: extra latency from writing in two places, extra egress and storage for mirrored cores, key distribution before any encrypted data moves, and a job to reconcile any differences from dual writes. The paper lists these costs instead of ignoring them.

The idea behind phase 3 applies to us as much as anyone: centralized infrastructure can speed things up, but it shouldn’t own the state. Speed, wake reliability, observability, and indexes all remain as services on an open platform. What disappears is the position of exclusive control.

* * *

## **What would falsify it?**

A good proposal should list the experiments that could disprove it. Here’s the agenda, ordered by how much each item affects the main claims:

*   **Minimal prototype.** One run as an epoch chain, one executor, one cold standby. Success means a standby on a different machine, then on a different engine build, resumes a suspended run through the two-gate check with zero manual control, and a deliberately skewed engine is stopped by the intent gate.
    
*   **Fencing validation.** Implement the epoch chain against real Hypercore semantics and attack it: post-close appends from a fenced predecessor, racing successors, `epoch.open` under partitioned indexers, closures racing certificate finalization. The deliverable is a safety argument grounded in observed behaviour, or a documented failure that revises the design.
    
*   **Coordination finality measurement.** Autobase time-to-checkpoint against indexer count and connectivity, and the latency the finality gate adds to approvals and epoch transitions. The design assumes these costs are acceptable. The measurements decide.
    
*   **World conformance.** Implement the exact versioned @workflow/world contract, run the upstream suite, and publish the results either way.
    

Problems where even the design isn’t settled are listed as open: step-ownership execution, effect-truth attestation, Byzantine-tolerant coordination, custody-proof hardening, erasure-aware control flow, and network-observer privacy.

* * *

## **What the paper changes**

Durable execution means your workflow survives even if your infrastructure fails. The paper goes further: the run should also survive your provider, your counterparty’s database, and any dispute about whose record is correct.

**For workflow authors**, nothing changes in the source code. "use workflow" and "use step" stay the same, and the determinism rules you already follow are what the P2P layer needs.

**For operators**, custody becomes a clear policy rather than a side effect of deployment. Durability level, failover set, retention, and liveness tier are all set in a signed manifest, and the mirror phase gives an exit path before any authority changes.

**For multi-party and agent systems**, the run’s history is no longer just one party’s database. Approvals are the approver’s own signed entries. Checkpoints are portable receipts for the transcript, not for the whole world. Disputes start with evidence, not arguments over whose logs to trust.

**For vendors**, including us, the business shifts from owning state to serving it faster and more reliably than anyone else.

Exclusive storage custody isn’t required for durable execution. The landlord’s storage was never the main support. The prototype tests whether scheduling, fencing, credentials, availability, and finality can be managed through evidence and flexible roles.

You can find the paper at [arxiv.org/abs/2609.17645](https://arxiv.org/abs/2609.17645). Read it, challenge it, and let us know about any failure cases.
