Nano BPM Advanced Research Prototype Whitepaper Web console Docs REST API Falcon protocol

Nano — An Advanced Research Prototype Engine

Status: Advanced Research Prototype. Nano is a distributed BPMN engine that speaks the Camunda 8 API. It is a research engine, not a product; it implements a bounded, honestly-stated subset of Camunda 8 that is expanding continuously.

Nano is built for a single use-case: the orchestration of software-delivery epics across networks of hundreds of agents. It is used internally at Camunda by Camunda engineers. It is not an official product of Camunda. The engine also runs as a drop-in local-development replacement for c8run — one small binary that gives you the Camunda 8 API to build and test against — but that compatibility is a means, not the thesis. This paper is about the thesis.

The emerging problem

There is a new problem in software engineering, and it is not "how do I make one agent write better code." It is: how do you go from fast-pair programming with an LLM to orchestrating hundreds of agents?

Boris Cherny's Steps of AI Adoption maps the progression. It moves from a single supervised pair — one engineer, one agent, every change reviewed (Step 1: Assisted) — to an engineer juggling ~10 agents across worktrees (Step 2: Parallel), to a manager-of-managers running ~100 (Step 3: Supervised autonomy), to a VP steering ~1,000+ by intent and monitoring by exception (Step 4: AI-native). The unlock at the top is that a quarter-long migration becomes a workflow you kick off and check on.

Step 1 is a tooling problem — a better editor, a faster model, a tighter loop. Everything past it is an orchestration problem. As the agent count climbs, the bottleneck stops being how fast can one agent code and becomes how do a hundred of them run reliably — durable loops that survive crashes and restarts, self-verification (tests, build, lint, review) before a human sees a diff, review convergence against an automated reviewer, fan-out with back-pressure so a thousand agents don't stampede, and monitoring by exception instead of by babysitting. That is a process-orchestration problem. It is the problem Nano is built for, and it is the reason a durable process engine — not another chat surface — is the right substrate for Steps 2 through 4.

Loops vs. graphs vs. agent networks

The current discourse names two units of agentic engineering. Loop engineering is getting one agent's iterate–verify–repeat cycle right: the prompt, the tools, the self-check, the stop condition. Graph engineering is wiring those loops into a workflow — steps, branches, and waits composed into a single process. Both are real, and Nano does both well; but both hold one agent or one process in view. Steps 2–4 are past that. When one engineer is steering ~10, then ~100, then ~1,000+ agents, the unit that has to be engineered is the network: many graphs and many agents, running at once, fanning out, coordinating over shared work, converging, and escalating by exception.

Unit What you engineer In view Where it runs out
Loop one agent's iterate–verify–repeat cycle a single agent it can't coordinate a second agent
Graph loops wired into one durable workflow a single process instance many concurrent graphs sharing work and contending for agents
Agent network many graphs + many agents as one system the whole fleet — (this is the frontier)

Nano's subject is therefore agent network engineering and agent network orchestration: authoring, running, observing, and steering the entire network as one durable, inspectable system — with the capability-addressed workforce and the app-tier coordination plane described below as its machinery — rather than hand-tending a loop or a lone graph. Loop and graph are what you engineer inside a node; the network is the thing you now orchestrate.

New abstractions need new primitives

Each rise in the level of abstraction in application development has been marked by a new first-class verb — the one operation the environment makes primitive. Nano tells the lineage as a sequence of families, each told apart by that primitive — and Nano is the next entry in it:

Lineage Primitive Noun Verb Answers
Delphi / CRUD state at rest the record mutate "what is"
IDE / editor state as artifact the file transform, then run "what did I make"
Process engine state in motion the instance directed evolution over time "what is happening, and what will happen next"
Nano / agent graph motion under agency the agent graph orchestration toward intent — direction reasoned at runtime, at network scale "what outcome am I steering toward, and how does a network of agents get there"

The third row was already genuinely new. A CRUD app photographs the world and throws away how a record reached its state; a process engine's substrate is the trajectory — the event log is not audit bolted on, it is the ontology. "Directed evolution of state" decomposes into three irreducible primitives:

The fourth row is what happens when the director is promoted from a drawing to a mind. A normal process is directed evolution whose graph is drawn in advance; an agentic process is directed evolution whose direction is reasoned at runtime. Same verb — "state evolves under control toward an end" — but the director moves from design-time to run-time, and the authoring act changes with it: you no longer draw every path, you declare the intent and a network of agent-directors discovers the path, steering by intent and monitoring by exception (the Step-4 unlock). Orchestrating hundreds of agents is therefore not a gadget bolted onto an editor — it is the process-engine primitive taken one level up: a network of reasoning directors over one durable, observable, crash-surviving substrate. That is Nano's primitive, and Steps 2–4 need it the way OLTP needed transactions.

This is not a projection — it is what Nano Workforce already does today. Hand it a GitHub issue and a planning agent (senior:plan) decomposes it into levelized tasks; a parallel multi-instance fan-out drives one implementation agent (senior:feature) per task, one PR each; every opened PR is enrolled into a durable convergence-loop that runs multi-round review against an automated reviewer (senior:pr-review), parking on a durable message-catch between rounds so agent slots and job timeouts are never held hostage to review latency; a converged PR flows into a merge-loop that clears dependencies, auto-fixes failing CI (senior:fix-ci), and merges queue-aware — escalating to a human only when an agent is stuck or a round cap is hit. It is a Nano Urban app: four explicit BPMN processes (plan-fanout, convergence-loop, merge-loop, retro), executed by the engine, so the whole lifecycle survives restarts, latency, and failure. The agents are decoupled external workers you "hire" (any coding-agent CLI harness, e.g. the GitHub Copilot CLI): the app owns the orchestration, the agents do the work, and neither names the other. This is where the primitive stands now — agent graphs orchestrated over durable processes; the fully closed Step-4 loop (where most agents are kicked off by other agents, at thousands of concurrent workers) is the trajectory this opens, not a claim of arrival.

Decomposition vs. integration

The deeper reason a chat surface cannot hold Steps 2–4 of Boris Cherny's Steps of AI Adoption is structural, and it is an old pendulum: application platforms swing between decomposition (split the concerns into independent services, each owning one thing) and integration (hold the concerns together so the seams between them vanish). The two mature expressions of the process-engine primitive each landed on opposite ends, and each holds only half of the picture:

Camunda owns only motion, so — as a structural consequence of its decomposition, not a missing feature — it cannot own the domain: it disclaims the resting substrate, and half a bridge spans nothing. The same fault line reappears one level up in the agent story: a frozen, Camunda-8-compatible job protocol (exact job-type string, matched 1:1) is the right decomposed contract for stock clients, but it deliberately provides none of what a network of agent-workers needs — a vocabulary for what work exists, visibility into what the crew is doing, or a plane to coordinate on.

The naïve fix — hand-wire an atomic job type per model, per task — is exactly the decomposition trap: it explodes combinatorially and couples every model to every machine, because a novel model then means editing worker capabilities fleet-wide across hardware that lives apart. So Nano does not address agents as atomic job-type endpoints; it addresses them as a network, by capability. An agent is hired with a profile — a rank and a set of capabilities — and a derived rank × capability matrix yields the job-type tokens it will service (rank alone, rank + one capability, rank + all), so a process can target a worker at any granularity without anyone hand-wiring a token per task (the concrete mechanism is c8ctl nano hire/assign/work; assign unions in new capabilities and a running worker reconciles its pollers live). Above the engine's plain 1:1 routing, a single app-tier agentic channel then carries everything a network needs and the frozen engine must never learn: registration and heartbeat (supply and presence), demand × supply (what work exists vs. who serves it, and on which machine), a shared blackboard for coordination, and live relay terminals to watch and steer each agent — multiplexed over prioritized QoS lanes so a stdout firehose can never head-of-line-block a heartbeat. Agent networks, in other words, are a first-class plane, not glue hand-wired one atomic job type at a time.

Nano's bet is integration where it counts. Because it embeds the engine and owns the application's datasource, it is the first system for which a first-class domain — the bridge between state-in-motion and state-at-rest — is even possible, while the engine underneath stays untyped and Zeebe-faithful so switch-over parity is preserved. The method itself becomes a process: OOP unified data and behaviour, but the behaviour was an ephemeral method — a stack frame that runs and returns. Here the behaviour is a durable, directed, temporal process. Order.fulfill() is not a function; it is a process instance that lives — it waits, is observable mid-flight, survives a crash, carries its own history. A domain object's methods are lifecycles. For an agent network, that same integrated substrate is what turns "a hundred agents each in their own terminal" into "a hundred directors over one durable, observable process," which is the only version of Step 4 that a human can actually steer by intent.

That bet is concrete: Nano is one vertically-integrated stack, owned end to end rather than assembled from independently-decomposed products, so the seams between the layers disappear:

Layer What it is What it owns
Nano Workforceapplication Agent-powered SDLC orchestration. Hire agents and coding harnesses, then run plan → implement → review → test → merge → QA → retro as durable graphs. The end-to-end epic across a network of agents.
Urbanapplication framework Author Nano apps as code or model. Go code-first and Urban derives the executable model, job types, message correlation, and a generic worker from your code; go model-first and the authored BPMN model is the source of truth. Either way, one source of truth — no hand-wired orchestration. The domain and its reconciliation — no drift between code, model, and workers.
Nano StudioIDE The RAAD (Rapid Agent Application Development) environment: a polyglot IDE to scaffold, run, and inspect agent applications, with live traces and the web console in one place. The authoring and observation loop on the workstation.
Nanoengine · foundation The load-bearing runtime, in Rust, Camunda 8-compatible. Durable by default: on restart a graph resumes at the exact step it left off; journal-committed steps are never replayed. Small enough to start on a Raspberry Pi. Motion — the durable, event-sourced execution substrate.

Each layer would be a decomposed product on its own — an engine here, an IDE there, a framework and an app bolted on top. Nano integrates them so the domain, the motion, and the director are reconciled by construction, not hand-wired by the maker. That is the difference between an engine you integrate against and a substrate you build on — and it is what makes steering hundreds of agents by intent tractable.

The sections that follow describe the engine that makes this substrate real: its footprint and durability, the transport that carries agent-workers at scale, and the honestly-bounded scope.

Features

The Falcon transport

Falcon is an optional native transport, offered alongside the standard API, never in place of it. A Nano cluster speaks the full Camunda 8 REST surface, so an unmodified Camunda 8 client works unchanged. Falcon is the "faster if you opt in" path.

It is a single persistent, bidirectional, credit-metered WebSocket per client that carries both directions of work on one connection: a demand-pull lane where a worker advertises how many jobs it can take and the server pushes only that many, and a submission lane where instance creation draws on credits fed from the engine's own processing headroom — so under load the server simply withholds credits and the client stalls its intake, with no 503/retry storm. Job delivery and instance admission thus share one backpressure account rather than each fending for itself. WebSocket (rather than gRPC) was chosen because it rides ordinary HTTP(S) that existing proxies, gateways, and firewalls already handle, and needs no per-language stub generation.

Scope and status

Nano is an Advanced Research Prototype. It deliberately keeps Camunda 8's client-facing semantics and Zeebe's battle-tested execution model, and revisits only a few choices underneath a fixed, compatible contract. It is usable today for local development against the subset it implements; it is not a general replacement for a production Camunda 8 deployment.