Everyone is building AI factories, and the term already means three incompatible things. This page is about the part almost nobody is working on: the join. Parallel agents are the easy half. What decides whether a factory compounds or merely churns is whether two things built in ignorance of each other can be combined — and whether the system can refuse when they can't.
01 · Vocabulary
There is no single answer, and that is the first thing worth knowing. As of 2026 the phrase is used for at least three distinct referents: an infrastructure plant that converts compute and data into model workloads; an agent-native delivery system that runs the software lifecycle end to end; and a production architecture concerned with how independently produced work is joined. They are not competing definitions of one thing — they are three different layers, and a claim at one layer says almost nothing about the others.
| Sense | Who uses it this way | The unit it optimises | What it does not address |
|---|---|---|---|
| Infrastructure plant | NVIDIA and the hardware ecosystem | Tokens per watt. GPUs, networking, storage, deployment. | Whether the software produced on top of it is correct, or composable with anything else. |
| Delivery system | Factory.ai — Factory 2.0, June 2026 |
The lifecycle loop. Signals in, triage, build, test, review, secure, ship, monitor, signals out. | Join geometry. The loop is described as interconnected; what makes two concurrent outputs safe to merge is not the subject. |
| Production architecture | This page | The join. What an assembly must carry so a merge can be checked rather than hoped for. | Everything the other two are good at. This layer needs both of them and replaces neither. |
Everyone is building workers for the factory. — the differentiation this page argues for: [&] is working on the laws, the assembly interfaces, the provenance and the control system that let the factory operate as one machine. If that sounds narrow, it is. It is also the part that decides whether the other two compound.
An earlier draft of the [&] homepage led with "Build the factory that builds the software." That draft was discarded on discovering that Factory.ai's own Factory 2.0 announcement already states that engineers will be responsible for building the factories that build the software. Leading with a competitor's published sentence is not positioning, it is collision. The differentiator had to be the layer, not the slogan — which is how this page ended up being about joins.
02 · The move it borrows
Instead of carrying one car body down a single line through every stage in sequence, an unboxed process builds major sections — front, rear, cabin, underbody — in parallel on separate sub-assembly lines, then joins them in a final merge. Tesla presented it at Investor Day on 1 March 2023 with stated targets of roughly 50% lower production cost and 40% less factory footprint. Those are targets announced for a future vehicle programme, not audited results, and this page treats them as such.
one object, every stop, in order
Total time = the sum. Making any one stage 10× faster moves the total by the width of that stage. This is the shape agents inherited, and mostly did not change.
many sections at once, one merge
Total time = the slowest section, plus the join. The saving is real and so is the bill: the join now has to actually work, because every incompatibility that used to surface gradually now arrives at one instant.
The analogy is worth exactly one thing, and it is not the cost figure. It is this: Tesla could only unbox because the interfaces between sections were settled before the sections were built. The bolt pattern, the tolerances, the mating surfaces — fixed in advance, so the merge is mechanical rather than negotiated. Remove that and unboxing produces four sections that do not fit, faster than before.
03 · Why parallel agents alone do not compound
Two independent reasons. First, Amdahl's law: the speedup from parallelising is bounded by the fraction of work that stays serial, so a pipeline with a serial merge step has a hard ceiling no number of agents can pass. Second, and more damaging: parallelism does not remove defects, it removes the delay before you meet them all at once. Eight concurrent workers produce eight opportunities for incompatibility that arrive simultaneously, at the merge, with no gradient of partial integration to catch them early.
The most careful public study of multi-agent failure is Why Do Multi-Agent LLM Systems Fail? (Cemri, Pan, Yang et al.). Built by Grounded Theory over 150 execution traces with six expert annotators to κ = 0.88, then extended to a corpus of 1,600+ annotated traces across 7 MAS frameworks, 4 models and 3 task types. It identifies 14 unique failure modes clustered into 3 categories.
36.9% inter-agent-misalignment share and a 79% "specification and coordination"
figure. Neither appears in the paper's abstract. They were checked against the source for this page
and cut, exactly as two other figures were cut from the composition masterclass for the same reason. If
you find them in a primary source, send it — we would rather cite the number than the caution.
| MAST category | What it covers | Is this a model problem? |
|---|---|---|
| System design issues | The architecture of the multi-agent system itself — roles, decomposition, control flow. | No. A better model runs the same broken architecture faster. |
| Inter-agent misalignment | Agents holding incompatible views of the task, the state, or each other's output. | No. This is precisely the join problem, observed in the wild. |
| Task verification | Failure to check that what was produced is what was required. | No. This is the absence of a verification station. |
Three categories, and none of them is "the model was not capable enough." That is the strongest available argument for the factory framing, and it does not require a single contested percentage to make: the taxonomy's own top-level structure is entirely architectural.
04 · Run it yourself
This is a model, not a measurement — it is arithmetic you can check by hand, not telemetry from a running system. It computes three things for n parallel work items at per-item success probability c. Watch what happens to the third metric when you unbox without checking the joins.
| Shape | Wall clock | Ships correct | Ships wrong, silently |
|---|---|---|---|
| BOXED | n | c^n | 1 − c^n |
| UNBOXED open | 1 + j | c^n | 1 − c^n |
| UNBOXED checked | 1 + J(d) + R(d) | c^n + (1 − c^n)·d | (1 − c^n)·(1 − d) |
| Term | Definition | What it says |
|---|---|---|
J(d) | j · (1 + k·d/(1 − d)) | What it costs to achieve detection completeness d: contract expressiveness, specification work, evidence obligations, dependency knowledge. Divergent as d → 1. |
R(d) | (1 − c^n)·d | Rework on what the join actually caught. Nothing is reworked that was never detected. |
total(d) | 1 + J(d) + R(d) + E·(1 − c^n)·(1 − d) | Wall clock plus what the escapes cost. This is the only one of the four with a minimum, and d* is where it sits. |
d* | argmin total(d) | The optimal amount of join geometry for this line. Scanned over d ∈ [0, 0.95] in the page, not solved. |
d a control was right and incomplete: dragging it from 10% to 100% was free.
Nothing charged for the thing that actually buys detection. With completeness free, the model's advice
is "set d to 1", which is not advice — it is the assumption restated.
J(d) makes completeness cost something, and the shape d/(1 − d) is a claim this
page is willing to defend: the last few percent of the failure surface are defects a contract cannot
express at all, so buying them is not expensive but impossible. That is why the slider stops at 95%
rather than running to a 1 the model would have to pretend is reachable.
d = 0,
so "how much join geometry?" is unanswerable until an escaped defect costs something. Give it a price
E and there is a computable d* — tighter is not better, it is a trade with an
optimum. That is the software analogue of a manufacturing tolerance, and it is the actual research
target: how much structure must independently fabricated assemblies expose before the cost of
formalising the interface exceeds the integration cost it removes?
d = 1 is only defensible for the class of defect the contract can express: a type mismatch,
a missing certificate, an unmet floor. Those are decidable, so detection really is total for them.
It is emphatically not true for a semantically wrong but type-correct result — a join that type-checks
cannot tell you the function computes the wrong thing.
d to 0 and UNBOXED-checked becomes
UNBOXED-open exactly. Everything between those ends is where the engineering lives — and
§05.1 is a live example of the contract expressing less than this page claimed.
The result worth sitting with: BOXED and UNBOXED-open ship wrong at exactly the same rate. Unboxing without checked joins does not make the work better. It makes it arrive sooner, in bulk, with the same defect population — which reads as a win on every dashboard that measures throughput and on none that measures correctness. The checked column trades silent wrongness for rework time. That trade is the product.
05 · The unit that moves down the line
Enough to answer, without running it: what does this require, what does it now guarantee, what state was it built against, who sanctioned it, what does it claim, and what evidence backs the claim. Strip any one and the merge becomes a guess. A diff carries none of them. That is why "many agents opened many pull requests" is not a factory — it is the boxed process with more hands.
| Field | Why the join needs it | Status in compose.mjs |
|---|---|---|
| requires / guarantees | The bolt pattern. A hand-off is feasible iff the producer's feeds_into intersects the consumer's accepts_from — but only when both are declared. | fail-open when undeclared — typeMatch() checks declared pairs correctly; Brick() defaults a missing contract to '*', so an undeclared interface is waved through. See §05.1. |
| certificate | Absent ⇒ 0̲. An uncertified part fails closed rather than being trusted by default. | running — UNCERTIFIED_COST() |
| cost class | Composite cost decides allow / budget_check / escalate. An uncertified composite can never be poly. | running — composeCost() |
| confidence / latency | The CC2 semiring: confidence multiplies, cost sums, latency maxes. Composition can only ever lower confidence. | running — composeQ() |
| world | Two assemblies built against different machine states are not obviously combinable. | specified, not wired — carried, never gated on |
| authority | A capability with no sanction behind it is a suggestion. The field is sanitised by normValue() and read by nothing in the join. | specified, not wired |
Three of the six are honest gaps. The marriage station on the homepage lets you set a world mismatch and shows you precisely this: the pair composes today, and the mismatch surfaces later in a world that no longer matches its parts. That is the demo refusing to flatter itself.
typeMatch() opened with if (out === '*' || inn === '*' || out == null || inn == null) return true;
— so an absent contract was compatible with everything. Brick() then made that the default:
accepts_from: o.contract?.accepts_from ?? '*'. An otherwise-certified assembly could omit its
interface entirely and receive the most permissive interface in the algebra.
| hand-off | before | now |
|---|---|---|
declared foo → declared foo | CHECK ✓ correct | unchanged |
declared foo → declared baz | REFUSE ✓ correct | unchanged — now names itself contract-mismatch |
| ⟨missing⟩ → typed | ACCEPT | REFUSE 0̲ contract-undeclared · CD1 |
| typed → ⟨missing⟩ | ACCEPT | REFUSE 0̲ contract-undeclared · CD1 |
| ⟨missing⟩ → ⟨missing⟩ | ACCEPT | REFUSE 0̲ contract-undeclared · CD1 |
explicit null field → typed | ACCEPT | REFUSE — null is an absence, not a declaration · CD5 |
explicit '*' → typed | ACCEPT | unchanged — an explicit wildcard is a claim · CD2 |
| identity brick → anything | ACCEPT | unchanged — idBrick() declares '*' · CD4 |
(⟨missing⟩ & declared) → typed | ACCEPT | REFUSE — & no longer launders an absence · CD3 |
The distinction that fixed it is small and consequential: an explicit '*' is a declaration
of universal compatibility; an absent field is the absence of a declaration. Collapsing the second into
the first is precisely the failure this stack names elsewhere — absence of evidence must stay distinguishable
from evidence of absence. It was collapsed, in the runtime, in the operator the whole factory is arranged around.
Two things about how it was closed are worth more than the fix. The five laws were written
against the unfixed code first, and four came back red — a fix whose test was written afterward proves
the fix, not the defect. And one of the five, CD2, was green from the start on purpose: an explicit
'*' must keep composing, or "missing ≠ universal" degenerates into "refuse everything" and the
distinction has no content. The identity laws survive for the same reason — none() and
idBrick() declare '*', so they make the universal claim rather than being
handed it by an absence. CD4 states both halves, including the half that narrows the law's domain:
id |> a is a for a declared a, and 0̲ for an undeclared one.
CD6, and it
stayed xfail until the question underneath it was ruled rather than patched.
& unioned both its operands' contract ends, and |> asked only for a
non-empty intersection. So a coalition handed off on behalf of a member that could not have
handed off itself:
A.feeds_into=['nope'] C.accepts_from=['session@3'] →
A |> C is 0̲ — correctB with feeds_into=['session@3'] →
(A & B) |> C composes, and A's output reaches C unchecked.
X |> A refuses, X |> (A & B) composes,
and X's output reaches an A that cannot accept it.
It is recorded as an xfail law rather than fixed, and that is deliberate. Closing it requires
answering a question nobody has ruled: what does a coalition's contract mean? Three answers are sound.
Union + subset — the coalition emits what any part emits, and a hand-off is safe iff the producer's
feeds_into is a subset of the consumer's accepts_from; outputs join, inputs
meet. Meet — the coalition's contract is the intersection of its parts, which makes
& contract-narrowing rather than widening and refuses some legitimate fan-in. Routed
hand-off — keep today's permissiveness, but require the certificate to record which member the
hand-off routed to. Each changes what & means. The law is stated in the form all three satisfy,
so whichever is ruled, it promotes out of the gap list without being rewritten.
Both defects point at the same missing research layer. Not more composition algebra — the algebra for declared parts is fine. What is missing is the semantics of partially specified composition: what a join should do when a part has not said what it is (now: refuse), and what it should do when a coalition says more than its members can individually honour (now: the wrong thing).
Factories move quickly because their interfaces don't negotiate at assembly time. — and the corollary that makes it hard: the interface has to be settled before the two halves exist, by something neither of them controls. In software that something is a protocol, which is why [&] is a specification before it is a product.
06 · The floor
Every cell is a real repository, protocol or product. The rung is the evidence rung —
spec → in_tree → live_local → live_deployed → external — and it is read from the same stored
table the portfolio nav renders. A cell with no recorded rung shows ?, never a flattering
spec. An invented status is worse than a missing one, because it stops the question
being asked.
Read the six ? marks as the roadmap. Note especially that WORLD (WRL + TRVM) — the cell
the entire Worldware argument rests on — is one of them. That is not an oversight in the diagram; it is the
state of the work, and a page that hid it would fail its own falsification table.
The full floor plan, cell by cell →
07 · Intelligence
Because the properties that make output trustworthy are not properties of the generator. The world it was built against, the authority behind it, the evidence, and whether it joins — none of those live inside the weights, and none of them improve when the weights do. A better motor turns the same machine faster. The intelligence commoditises; the arrangement is what compounds.
This is the same argument the sibling masterclass makes as "the model is ~10%, the harness is the product" — moved up one level. There, the harness is the product. Here, the harness is a cell, and the product is the arrangement of cells. Both statements are about the same observation: the durable engineering is outside the model, and it survives the model being swapped. Read the harness argument →
08 · The category
A proposed category, not a product and not a brand: software whose unit of composition is a world rather than an application. Each rung of the ladder below is named for what it operates. The pattern is the useful part — every time the unit got larger, the previous layer stopped being the thing you reasoned about and became the thing you stood on.
world is
the persistent, machine-sized environment — 10 GB to 10 TB of a real machine, its state, its
history and its rules. It is not "any bounded system you would like to call a world," and it is not
a metaverse. The word was conflated with a much smaller thing exactly once in this project, the error was
recorded, and four terms were frozen to stop it recurring:
Worldware is not claimed as a mark. The word has a prior meaning: it was coined in the 1990s by Steve Ehrmann of Educom's software task force to describe general-purpose software — word processors, CAD, email — that also gets used for teaching. That sense is dormant and unrelated, and we are not competing with it. Two adjacent candidates were considered and dropped for being actively owned: Terraware (Terraformation's forest-management platform, with a US trademark application) and UltraWare (a Dutch software company, a UK Ltd, and a former Rockwell Automation product). The category is the useful part; the word is borrowed, and stated as borrowed.
Worldware is what the factory produces. ComputeDriven is how you drive it. The deeper treatment of what changes when the thing you version is a machine rather than a repository is its own masterclass — Worlds That Pay For Themselves →
09 · The section every page like this should have
A page arguing that unverified claims are the disease cannot ship a list of verified-sounding claims. Here is the honest inventory, in the order that would most damage the argument if you found it yourself.
| Missing | Status | Why it matters to the thesis |
|---|---|---|
A coalition could hand off on behalf of a member that could not (CD6) |
closed 2026-08-22 | Found while writing the falsifiers that closed the row below it, and it was worse: it needed nothing to be undeclared. & unioned both contract ends while |> asked only for a non-empty intersection. Closed by ruling rather than patch — Option U: outputs join, inputs meet, hand-off is a subset test. Closing it exposed CD7: one wildcard cannot mean both "may emit anything" and "passes through unchanged", so the identity is now typed α → α. §05.1. |
| The join was fail-open on an undeclared interface | closed 2026-08-22 | Displaced the world join when an outside reviewer found it, and was closed the same day, falsifier-first: five laws written against the unfixed code, four red. A missing contract was defaulted to '*' and composed with anything — the exact inverse of formalize the joins. It now refuses as 0̲ contract-undeclared, an explicit '*' still composes, and the identity laws survive because the identity bricks declare the wildcard. Left in the inventory because the closure is the evidence. §05.1. |
| The world join | specified, not wired | The Worldware claim says the unit of composition is the world. The compose runtime does not gate on the world field. Until it does, the claim is an architecture, not a running property. Back at the top of the open list now that CD6 is closed — it is the largest thing here that is specified and not wired. |
| The authority join | specified, not wired | Sanction is carried through normValue() and read by nothing in the join. A capability with no checked authority is currently joinable. |
| Coalition admissibility in composition | specified, not wired | The rung primitives exist — canEnsure at strategic.mjs:70, common knowledge at epistemic.mjs:68 — and the compose runtime never calls them. The pieces are built; the wiring is not. |
| Semantic defect detection at the join | out of scope | The simulator's d = 1 holds only for contract-expressible defects. A type-correct, semantically wrong result passes every gate described on this page. |
| Measured throughput of a running line | not measured | The simulator is arithmetic, not telemetry. No claim on this page is supported by a benchmark of the factory actually running end to end, because that benchmark does not exist yet. |
| A rung for six of 16 cells | unrecorded | RESEARCH, METROLOGY, WORLD, EVIDENCE, DEPLOY, PROOF have no stored evidence rung. Several of the six are load-bearing for the Worldware argument specifically. |
| CP5 / CP6 / CP7 | declared open | Three composition laws do not hold. They print FALSIFIED in red by design and the build fails if one starts passing. CP7 reproduces in your browser. |
10 · The ending this page has to have
Every row names a claim, its honest status, the command that exercises it, what you should see, and
the specific observation that would falsify it. Commands carry their directory: run from
the repository root and they fail with MODULE_NOT_FOUND, which on a page whose contract is
run the command would be the worst available defect.
| Claim | Status | Command | Expected | What kills it |
|---|---|---|---|---|
| 210 enforced laws stand behind the join, derived not typed | running | cd AmpersandBoxDesign/box-and-box && node test/laws.mjs && node test/compose-laws.mjs |
109 kernel + 101 compose, both totals printed by the suites themselves | A total on this page that no suite prints. The published and printed counts drifted apart once before; that is why nothing here is hand-typed. |
| The join refuses on contract mismatch rather than degrading — when both sides declare one | running | The marriage station — set A's guarantees to something B does not accept |
0̲ — REFUSED, naming the failing gate |
A surviving composite with a lowered score instead of a zero. Or a thrown exception rather than a value. |
| An UNDECLARED contract composes with anything — the inverse of what this page argues | open defect | cd AmpersandBoxDesign/box-and-box && grep -n "accepts_from: o.contract" compose.mjs |
accepts_from: o.contract?.accepts_from ?? '*' — a missing field becomes the most permissive interface in the algebra |
Nothing yet — this row is the defect, not a claim. It dies when Brick() stops defaulting a missing contract to '*' and the three ⟨missing⟩ rows in §05.1 return 0̲ or hold. Reproduce it in the marriage station by selecting ⟨undeclared⟩. |
| At zero detection, a checked join is indistinguishable from an unchecked one | running | §04 — set detection to 0%, compare UNBOXED-checked against UNBOXED-open | Identical in both metrics: same silent-wrong rate and same wall clock, because there is no rework when nothing was caught | Any divergence. The rework term is (1 − c^n)·d; if it were independent of d the model would charge time for defects it never detected — which is what it did until this slider exposed it. |
| An uncertified part fails closed | running | cd AmpersandBoxDesign/box-and-box && grep -n "fail-closed" compose.mjs |
UNCERTIFIED_COST with resourceDecision: 'annihilate' |
Any path where a missing certificate yields a composable brick. Or a default that supplies one. |
The world field is NOT gated on by composition |
specified, not wired | cd AmpersandBoxDesign/box-and-box && grep -n "world" compose.mjs |
No output. The field is carried by the algebra and never read by the join. | Any hit, which would mean this page understates what ships. Equally fatal: us describing the world join as running while this grep stays empty. |
| The unrecorded-cell count is derived, not typed | running | View source, §06 script — every count on this page is computed from the CELLS array at load |
The hero stat, the §06 heading and the §09 row all move together if a cell's rung changes | Any of those three disagreeing. A first draft of this page hand-typed "six" while the array held seven — ComputeDriven was marked ? when it is place 1 and carries no product rung at all. That is the drift this row exists to catch. |
| Cell rungs match the stored property table | running | grep -n 'rung:' ampersand-nav/src/amp-nav.js and compare against §06 |
Every rung on this page is the stored value; unrecorded ones render ?, never spec |
Any cell here showing a rung that is not the stored value. If this page and the nav disagree, the nav is right and this page is stale. |
| The simulator is arithmetic you can check by hand | running | Set n=6, c=0.95. Compute 0.95⁶ by hand. |
0.7351 — matching "ships correct" for BOXED and UNBOXED-open exactly | Any divergence between the printed metric and the formula table in §04. The formulas are published so this row can exist. |
| MAST's three categories are all architectural | external | Read the abstract of arXiv:2503.13657 | system design · inter-agent misalignment · task verification — and no failure-rate percentage | A percentage in the abstract that we said was not there. Or a fourth category that is about model capability. |
| No benchmark supports the throughput argument | not measured | Ask us for one. | We do not have one. §09 says so before you can catch us. | Nothing — this row is the concession. It becomes falsifiable the day we publish a number, and then it moves to running. |
Absence of evidence must remain distinguishable from evidence of absence, and every consequential
transformation must expose why it occurred.
— the [&] doctrine. It is why 0̲ is a value that carries a reason rather than an exception that carries a stack trace, and why §09 exists at all.