A deterministic actor foundation for executable topology
Every other page on this site documents what WallRiderLang is. This page documents what it is for, what it is not, and the ordered list of things that do not exist yet. Nothing here is frozen, nothing here is implemented, and every code block on this page is verified by the test suite to be rejected by today's toolchain.
- WRL Core 0.1.2, the writable surface. Five roles, one texture, no behaviours. Its actor surface is narrow, and the frozen extract says so.
- The authored design. A serious actor model with mailboxes, behaviour blocks, capabilities, supervision, live-state migration and message compatibility — written down in full, tier-marked, and published at Design draft. It is designed, not built.
- The topology direction. This page. It goes past what conventional actor runtimes model, because it is about giving relationships domain meaning rather than giving processes better plumbing.
The order matters. (1) is what you can run, (2) is what the language is designed to be, (3) is what it is for. A review that scores (1) and concludes about (3) — or quotes (3) and implies (1) — is scoring the wrong artifact.
The reframing
WRL has been graded, reasonably, against the conventional actor model: processes, mailboxes, behaviour loops, supervision trees. Against that ruler the writable surface scores badly, and the score is correct. There are no arbitrary behaviours, no writable asynchronous mailboxes, no supervision, no selective receive, no process lifecycle, and nothing resembling the operational tooling that Erlang/OTP has accumulated over three decades of running telephone switches.
Two qualifications keep that from being the whole story, and neither is a softening of it.
First: the part that is built is the part actor systems find hardest. Deterministic replay, canonical event ordering, a within-period fixpoint, content-addressed identity, and a film that reconstructs a run exactly are not conveniences an actor runtime adds later — they are properties most actor runtimes gave up permanently in exchange for scheduling freedom, and cannot recover without redesigning from the bottom. WRL has a small actor surface sitting on an unusually strong deterministic foundation. That is a rarer position than a large actor surface on a nondeterministic one, and it is the reason the ceiling is high even though the floor is low.
Second: the actor model is designed, it is just not built. Mailboxes with declared capacity and overflow policy, behaviour blocks that canonicalize to the same bytes as the drawn form, capability walls, deterministic supervision, verified live-state migration and content-addressed message compatibility are all specified in the authored draft. That is a substantial design, and it is a different kind of gap from a blank page — but it would overstate it to call the remainder mere implementation. Several questions an actor operating system has already answered are still genuinely open here: placement (which host runs which identity, and who decides), partitions (what a period means when the fleet splits), fairness (what the scheduler owes a starved identity when order is canonical), lifecycle (spawn, hand-off and retirement under replay), and operations (upgrade, observation and intervention on a running system). Those are design questions, not typing exercises, and the answers may move the draft.
But the ruler still measures the wrong thing. Erlang is an actor operating system: it is superb at keeping large populations of processes alive, supervised and upgradable. It is deliberately indifferent to what those processes mean. A road network, a power grid or a robot fleet can be modelled in Erlang perfectly well — the topology lives in process state, ETS tables, maps, registries and external databases. What Erlang does not do is make that domain topology a native canonical language artifact: a thing the language names, seals, diffs and hands you as evidence. It is expressible; it is not first-class.
WRL's bet is the opposite one:
The topology is the program. The network of identities, the relations between them, the guarantees those relations carry, and the authority that governs them are the source text — not a data structure the source text builds at run time.
That is a different category of language, with different competitors, and it is the frame the rest of this site should be read in.
One identity, many networks
Many specialist tools privilege exactly one network. A traffic simulator knows roads and vehicles. A circuit simulator knows components and nets. An actor runtime knows processes and messages. A robotics middleware knows nodes and topics. Each is excellent inside its domain, and each was built by people who had no reason to model the others.
Heterogeneous tools do exist, and the claim here is not that nobody has ever combined two domains — co-simulation frameworks, Ptolemy's hierarchical directors [5] and Modelica's multi-physics libraries [2] all do. The claim is narrower: combining them over one durable identity, with a content-addressed name for the whole assembly and a replayable film of the run, is the part that is rare.
A real drone is simultaneously a participant in many networks:
| Layer | The relation it contributes |
|---|---|
| Physical / spatial | the drone occupies an airway segment |
| Communications | the drone streams telemetry to a fleet controller |
| Command | the controller dispatches the drone |
| Authority | an operator is permitted to reroute it |
| Fault | its failure escalates to a supervisor |
| Energy | it draws from a charger and depletes a battery |
| Economic | a delivery fulfils a contract and incurs cost |
| Evidence | a signed observation is accepted under a policy |
In practice that drone is often represented separately in each system that touches it — as a ROS node, a routing entity, a battery model, an authorization subject, a maintenance record, a process, a simulation object — with a different identifier in each. How many representations there are depends entirely on the deployment, so the number is not the point. The point is that every pair of them is a chance to disagree, and keeping them aligned is an integration cost paid continuously rather than a modelling problem anyone finished solving.
The thesis is that they should be one durable identity participating in several typed topologies, and that the whole assembly — world, policies, run, and outcome — should have a single content-addressed name.
Design-sketch notation, to make the shape concrete. This is not WRL Core 0.1.2 and the toolchain refuses it:
profile wrl.mobility.v1
[drone:d7](battery=82, payload=4kg){pose, telemetry, command}
[airway:a12](capacity=6, altitude=120){occupancy}
[fleet:west]{telemetry}
[operator:dispatch]{command}
[charger:c3]{power}
[supervisor:safety]{fault_in}
[d7] --occupies--> [a12]
[d7] ~~telemetry~~> [west]
[dispatch] ==command==> [d7]
[d7] !!fault!!> [safety]
[c3] --power--> [d7]
The spelling is not the point and will change. The point is that
d7 appears once, and five different networks are
declared over it — spatial, asynchronous-communications, authorization, fault,
and energy — in a document that can be hashed, diffed, replayed and audited as a
unit.
Where this actually is today
A single number here would be dishonest in both directions, because the five questions people actually mean when they ask "how good is it" have five different answers. Scored out of ten, generously enough that the low ones cannot be blamed on a harsh grader:
| What is being scored | Why | |
|---|---|---|
| WRL Core's writable actor surface what you can type today | 3.5/10 | five fixed roles, one texture, no behaviours, no mailbox, no spawn. This is the number a hands-on reviewer will reach, and it is right |
| The implemented deterministic runtime foundation what the small surface sits on | 7.5/10 | content-addressed worlds, canonical ordering, within-period fixpoint, byte-exact replay, an independent oracle. Rare and hard — and frozen and demonstrated for the Core fixture, which is a smaller claim than "finished": it has not been shown at fleet scale, under partition, or across hosts of different architectures |
| The full authored actor-model design what the language is designed to be | 8.7/10 | mailboxes with capacity and overflow, behaviour blocks, capability walls, deterministic supervision, verified migration, message compatibility — all written, none running |
| Topology-native actor-system potential the ceiling if the thesis is right | 9.7/10 | few actor-oriented systems combine a first-class relation with canonical identity, replay evidence and capability topology — the pieces exist separately in graph databases, modelling languages and actor runtimes, and the combination is what is unoccupied. A ceiling, not a result |
| Production operations maturity vs OTP running it in anger | 2/10 | no distribution, no hot upgrade in production, no observer, no tracing, no thirty years of operators. This one is not close and will not be soon |
Feature by feature
The same judgement at higher resolution. A score here is how well the language handles the concern in principle, given what is designed and what is grounded — not whether you can type it today. The "writable" column is what you can type today, and the two disagree on purpose.
| Concern | Writable now | Note | |
|---|---|---|---|
| Stable identity | 9.5 | yes | identity is structural and content-addressed, not a runtime handle |
| Semantic replay | 9.5 | yes | a film reconstructs a run byte-exactly; verified against an independent oracle |
| Immutable messages | 9.5 | partly | values are immutable by construction; the asynchronous carrier is not writable |
| Error / value / fault ladder | 9.5 | partly | three distinct outcome kinds, not exceptions; fault state exists, escalation does not |
| Owned state | 9 | yes | single-writer per cell is a static check, not a convention |
| Same-period vs later delivery | 9 | no | the distinction is frozen in the texture family; only -- is writable |
| Bounded mailboxes | 9 | no | capacity and overflow policy are part of the port type, not runtime configuration |
| Quiescence | 9 | yes | defined precisely, and distinguished from termination |
| Capability / effect walls | 9 | no | no effect happens invisibly; every crossing is a named, recorded wall |
| Live-state migration | 9 | no | a verified route with recorded evidence, not an improvised upgrade script |
| Explicit backpressure | 8.5 | no | overflow is a declared policy with an outcome, never a silent drop |
| Deterministic supervision | 8.5 | no | designed to replay identically, which conventional supervision does not |
| Behaviour blocks | 8.5 | no | required to canonicalize to the same bytes as the drawn form — a testable law |
| Message compatibility | 8.5 | no | content-addressed message types; an unknown hash is an outcome, not a crash |
| Dynamic process lifecycle | 6 | no | the hard case for sealed identity; §D9 now derives topology from immutable ledger facts and admits novel identities by sealed rule — placement and partition behaviour remain open |
| Selective receive | 5 | no | no design; it interacts badly with canonical ordering and needs one |
| Distributed placement | 4 | no | merge laws exist; placement, partition and consensus do not |
| Scheduler implementation | 4 | n/a | the reducer is correct and unoptimised; no preemption, no fairness work |
| Operational tooling | 2 | no | the honest floor. No observer, no tracing, no live introspection |
Two patterns in that table are worth naming. Everything scoring 9 or above is a property of the identity and evidence machinery, which is the part that is built. Everything scoring below 6 is a property of a running distributed system, which is the part that is not. The language is strong exactly where meaning is decided and weak exactly where operations happen.
The gap, restated as a table
| The claim | What exists today |
|---|---|
| Many typed layers over one identity | One layer. Two edge kinds, both signal-ish. |
| Four route textures carrying guarantees | One writable texture, --. The other three are frozen meanings with no surface. |
| Attributed, weighted relations | None. An edge carries a kind and two endpoints. |
| Programmable behaviour | None. Five fixed roles with fixed reactions. |
| Dynamic topology | None. The world is static for the length of a run. |
| Supervision | Fault state exists. Supervision does not. |
| Domain profiles | One profile, forge.world.core.v1. |
| Content-addressed worlds and replayable films | This part is real, tested, and shipping. |
So the honest summary is: the mechanism is built and the ambition is not. What exists is a small, complete, property-tested demonstration that a topology can be canonicalized, sealed, replayed and independently checked. Everything on this page is an argument about what that mechanism should be pointed at next.
The six pillars
Six design decisions follow from the thesis. Each is stated in spec language in Core 0.1.2 Part II; here is the argument for each. The first five are about what a world means; the sixth is about what to build next, and is the one most likely to be argued with.
1 · The layers are node-aligned, because identity is not per-layer
Multilayer networks are a studied formalism, not an improvisation. In the standard treatment a multilayer network is a set of node-layer tuples plus intra-layer and inter-layer edges, where layers may be structured along several aspects — edge type, time, and so on — and inter-layer edges commonly get different semantics from intra-layer ones.1 A recurring cost in that literature is bookkeeping: the same entity appears once per layer as a replica, and the replicas have to be tied together by explicit coupling edges.
WRL's durable identity removes that cost by construction:
A WRL world is a node-aligned multilayer graph. An identity is not replicated per layer; the layers are aspects of one identity. There is therefore no such thing as an inter-layer coupling edge betweend7-in-the-road-layer andd7-in-the-comms-layer, because there is oned7.
This is the single largest structural advantage available to the language, and it is a direct consequence of a decision already frozen in §4: identity is a first-class construct kind, not a per-graph label. It also constrains the design — see what would falsify this, because node-alignment is a real assumption and it can be wrong.
2 · Not every link is a directed route
WRL Core has exactly one connection concept: a directed edge from a source port to a destination port, with at most one edge landing on any input. That rule is correct for owned actor state — it is what makes "conflicts dissolve" true — and it is wrong as a universal wiring law. Two large domains break it immediately.
Electrical and hydraulic connections are not directed. In Modelica a connector distinguishes potential variables, which are set equal across a connection, from flow variables, which are constrained to sum to zero at the connection point — Kirchhoff's laws expressed as a connection semantics.2 Nothing in that is a message from a sender to a receiver. Voltage and current are solved together over the connected set.
Buses have many drivers on purpose. Hardware description languages solved this long ago and the solution is instructive: VHDL provides unresolved types, where more than one driver on a signal is a compile error, and resolved types, where a declared resolution function computes the signal's value from all its drivers — which is how three-state buses are modelled.3
- owned port — at most one writer, statically enforced. Today's rule, unchanged.
- resolved terminal — many drivers, one value, via a resolution function named by the profile.
- acausal connector — no direction at all; potential variables equalized, flow variables summed to zero, solved as a system.
3 · Textures encode guarantees, and must not be asked to encode domains
There is an obvious-looking move here that would be a mistake: since
--, ~~,
== and !! are so
readable, keep inventing textures — one for roads, one for power, one for
money.
That collapses under its own weight, and the reason is visible in any mature messaging stack. ROS 2 exposes a channel's behaviour as a set of independent QoS policies — reliability, durability, history, depth, deadline, lifespan and liveliness — which can be combined to be as strict as TCP or as loose as UDP.4 Those are seven orthogonal axes on a single channel. No glyph vocabulary survives that, and a language that tried would need several thousand arrows.
So the frozen four stay four, and they keep the one job they are good at:
| Texture | Answers exactly one question |
|---|---|
-- | does it settle inside this period? |
~~ | is it asynchronous — observable no earlier than the next period? |
== | does it require evidence accepted under a named policy? |
!! | is it a failure path that engages supervision? |
Everything else — domain, direction, cardinality, capacity, cost, units,
geometry, schema, reliability, policy — becomes named typed attributes on
the relation, whose legality is pinned by the profile. A power connection is a
solid relation in the power domain that happens to be
acausal; those are three independent facts and the texture carries only the
first.
4 · Walls are where the model of computation changes
If a world can contain roads, circuits and message queues, then it contains several models of computation — continuous time, discrete events, synchronous reaction, dataflow. That problem has a known good answer.
Ptolemy II makes the semantics of a model a component in the model: a director implements a model of computation, and a composite actor may be opaque, so its local director need not be the same as the director above it. That is what makes hierarchical heterogeneity work, with directors for process networks, discrete events, dataflow, synchronous/reactive and continuous time.5
WRL already has the construct this requires, and it is not an actor. It is a wall — the boundary family that gates, commits and seals (§10):
A wall may enclose a sub-world under a different profile. The wall, and only the wall, is where the model of computation changes; the enclosing world does not need to understand the enclosed one, only the wall's contract.
The outer world does not learn SPICE. It learns that a wall named
amp3 accepts a stimulus, produces a signed result,
and takes one period to do it. Whether the inside was solved by nonlinear
transient analysis or by a lookup table is not the outer world's business — and
that is precisely the property that makes composition survive contact with real
solvers.
5 · Derives seal the answer, not the search
This is the pillar that decides whether "auditable" is true or decorative, and it turns on an asymmetry between two kinds of external engine.
Simulators can be re-run. SUMO fixes its random sequence from a seed and is deterministic by default, so the same configuration produces the same behaviour; the seed is an option and the default is a fixed value.6 An engine like that can be sealed the ordinary WRL way: hash the inputs, the engine profile and the seed, and verify by replaying.
Optimizers frequently cannot. The OR-Tools routing solver is sensitive to the order in which variables and constraints are created — non-deterministic map iteration in the caller has been enough to produce non-deterministic results and run times — users report substantial run-to-run variability in solution quality on identical problems, and the solver does not honour a time limit while it is still inside its first-solution heuristic.7 None of that is a defect; it is what heuristic search is like. But it means a route plan cannot be verified by re-running the search.
One consequence has to be stated because it is the most tempting thing to overclaim. Feasibility is checkable in roughly the cost of reading the plan. Optimality is not checkable at all without redoing the search. So a sealed plan may honestly carry:
feasible under constraintsC; objective value 412; produced by solver profileS
and it may never carry optimal. A film that says "this plan satisfies every capacity and time window, and here is the arithmetic" is a smaller claim than "this is the best plan", and it is the one that can be independently checked by a party who does not trust you.
6 · The next primitive is a relation, not another actor feature
Everything above converges on one conclusion about sequencing, and it is the least intuitive claim on this page: the next thing to build is not a better actor.
The pull towards actor features is strong and it is the wrong pull. Spawn, selective receive, a supervision tree and a distribution layer would each close a visible gap against Erlang, and each would leave the language competing on Erlang's ground with thirty fewer years of work. Meanwhile the thing few actor-oriented systems offer — a relation that is itself a typed, attributed, checkable, sealed object — would still not exist here.
Concretely, the near-term work is the shape argued in
Core Part II §D8: broaden the runtime's third entity
from a binary directed Edge to a general
Relation, with today's route as its simplest
specialisation.
RelationAllocation { world_id, issuer, nonce }
RelationRevision { domain, kind, endpoints, orientation,
texture?, attributes, policy, provenance }
Endpoint { terminal, role }
relation_id = H("WRL_RELATION" ‖ world_id ‖ issuer ‖ nonce)
current_revision = fold over the ledger prefix — derived, never stored
The split into a stable relation_id and a
content-addressed revision is §D8.1, and it
is what lets two physically distinct but identical relations — parallel cables,
a redundant link, two lanes of one segment — be told apart, revised and failed
independently. The name comes from an allocation rather than from the
event that creates the relation, because
deriving it from the event is circular:
the event id is a hash over its arguments, and the id would be one of them. The
revision carries no back-pointer to its predecessor, so lifecycle history has
exactly one home — the ledger — and two
relations that reach the same value by different routes share one revision id.
texture? is optional because an acausal relation has
none.
Three unusual capabilities fall out of that one change, and none of them is reachable by improving actors:
| Falls out | Because | Rare elsewhere because |
|---|---|---|
| Multi-participant relations — a bus, a net, a shared segment | endpoints is a set, not a pair, and each one carries a role — the tail-and-head structure of a directed hyperarc. This is also the link graph of a bigraph,9 where a link joins any number of ports | actor runtimes model connection as addressing, and an address has one target |
| Acausal relations — potentials equal, flows sum to zero | orientation admits a value that names no source, which is what a physical connection actually is2 | message passing presupposes a sender; a wire does not have one |
| Domain-checked attributes — capacity, cost, impedance, units | attributes are typed by the world's profile, so capacity=3 has a unit and a range and can be checked before the run | graph databases got here first for storage10 — but they do not seal, check, or replay |
And the reason to do it before the actor features rather than after is ordering, not preference. Typed ports, supervision, effect walls and domain profiles all need to know what a connection is. Building them against a binary directed arrow means rebuilding each of them when the arrow generalises — which is the same argument §D3 makes for why attributed relations must precede any domain profile.
--sig-->
route still serialises to byte-identical canonical output. If it does not, every
published sem- id on this site moves, and the change
stops being an extension and becomes a version break. That constraint is
§D8's central obligation and the first thing an
implementation should test.Consequences
Expressing a graph is not implementing its laws
The distinction that keeps this project honest:
Read the following as two separate questions per domain — can WRL describe this network, and can it compute what the network does — because the answers are very different:
| Domain | Describable today | What computing it needs |
|---|---|---|
| Generic directed graph | mostly — no weights or attributes | attributed relations |
| Digital logic | netlist shape only | bit vectors, clock domains, delays, tri-state resolution, unknown/high-Z values |
| Analog circuit | no — connections are acausal | multi-terminal nets, units, continuous time, DAEs, a nonlinear solver |
| Road network | topology only | weights, capacity, geometry, lanes, continuous position between vertices |
| Vehicle / drone fleet | topology only | behaviours, async telemetry, dynamic membership, tasks, reservations, an external router |
| Electric grid | topology only | phases, power flow, protection models, an analysis engine |
| Logistics network | topology only | attributes, time windows, an optimizer and its checker |
| Organizational / authority network | partly — the shape suits it | == and the permission/instance split (§16.2) |
| Auditable cyber-physical twin | the evidence half is real | everything above, plus effect adapters |
What four domains actually demand
The previous table names what each domain needs in prose. This one crosses the four domains that matter most against the thirteen capabilities they draw on, because the useful information is in the overlap: a capability demanded by all four is infrastructure, and a capability demanded by one is a profile's business.
■ required · ▨ needed for realistic use · · not essential.
| Capability | Fleet | Circuit | Grid | Robotics | Status |
|---|---|---|---|---|---|
| Attributed relations | ■ | ■ | ■ | ■ | §D8 — sketched |
| Typed quantities and units | ■ | ■ | ■ | ■ | drafted, ungrounded |
| Safety invariants | ■ | ▨ | ■ | ■ | static checks exist; runtime invariants do not |
| Discrete-event time | ■ | ■ | ▨ | ■ | built — this is the period cycle |
| Dynamic topology | ■ | · | ▨ | ■ | §D9 — sketched |
| Geometry and coordinate frames | ■ | · | · | ■ | nothing. Not even a frame concept |
| Reservations and resources | ■ | · | ▨ | ■ | affine resources are drafted |
| External solver interface | ■ | ■ | ■ | ▨ | pillar 5 — derives, sketched |
| Topology deltas | ■ | · | ▨ | ■ | needs §D9 first |
| Uncertainty | ▨ | · | ▨ | ■ | nothing, and it fights determinism — see below |
| Resolved terminals | · | ■ | ■ | · | §D8 — sketched |
| Acausal connectors | · | ■ | ■ | · | §D8 — sketched |
| Continuous time | · | ■ | ■ | ▨ | nothing. Needs a solver wall (pillar 4) |
Three readings of that table, in decreasing order of comfort.
The top four rows are unanimous, and only one of them is built. That is a clean answer to "what next": attributed relations, units, invariants. Nothing domain-specific competes with a row that every domain needs.
The split is real and it is diagonal. Fleet and robotics want dynamic topology, geometry and reservations; circuit and grid want resolved terminals, acausal connectors and continuous time. Almost nothing in the bottom half is shared. This is the strongest argument for profiles rather than construct kinds — a language that put all thirteen in the core would be a language nobody could learn, and one that picked a side would be a single-domain tool.
The specialists, and what not to rebuild
Each of these is the right answer to a question WRL should not be trying to answer:
| Question | Right answer | WRL's role |
|---|---|---|
| What does this transistor circuit do? | ngspice / the SPICE family | seal the netlist, the model IDs, the solver profile and the result |
| How does this multi-physics system behave? | Modelica | supply the acausal connector semantics; own the surrounding authority and evidence |
| What happens to this distribution feeder? | OpenDSS | unify the electrical model with the comms, fault, crew and market models |
| How does traffic actually flow? | SUMO | seal the scenario and seed; replay the film |
| What is a good vehicle route? | OR-Tools or a specialist solver | be the derive boundary and the checker (pillar 5) |
| How do robot components interoperate? | ROS 2 / DDS | declare why a message is permitted, what it may affect, and what proves it happened |
| How do I keep a million processes alive? | Erlang/OTP | nothing — use Erlang |
| How do I mix models of computation? | Ptolemy II | borrow the director idea; add identity, policy and replay (pillar 4) |
The target is not to beat any of them at their own question. It is to be the language in which their answers compose into one verifiable world: same identities, one canonical topology, one authority model, one replayable record.
Four demonstrations
Arguments about a language are cheap. These four are the specific things that, if they worked, would demonstrate the thesis — and if they cannot be made to work, would refute it. They are written in design-sketch notation. None of them parses; each names the capabilities it is waiting on, and the test suite checks on every run that today's toolchain still refuses it.
A · Autonomous delivery fleet
The flagship, because it is the only one that exercises every layer at once. One drone participates simultaneously in spatial occupancy, communications, command authority, energy, fault, evidence and economic fulfilment — and the whole assembly has one name.
profile wrl.mobility.v1
[drone:d7](battery=82%, payload=4kg, frame=wgs84)
{pose, telemetry, command, fault_out, power_in}
[airway:a12](capacity=6, altitude=120m){occupancy}
[fleet:west]{telemetry_in, dispatch}
[operator:kim](role=dispatcher){command_out}
[charger:c3](watts=400){supply}
[supervisor:safety](on_fault=land_now){fault_in}
[contract:ord991](due=14:30, penalty=12.00usd){fulfilment}
; spatial — an attributed relation against a finite capacity
[d7] --occupies(cost=1, until=lease(6))--> [a12]
; communications — does not settle this period
[d7] ~~telemetry(rate=4hz, loss=ok)~~> [west]
; authority — a command carries evidence that it was permitted
[kim] ==command(cap=reroute.v1)==> [d7]
; energy — acausal: the charger does not "send" watts
relation electrical acausal {c3.supply, d7.power_in}
; fault — escalation, not an exception
[d7] !!fault(class=gps_loss)!!> [safety]
; economic — the delivery discharges an obligation
[d7] --fulfils(units=1)--> [ord991]
The demonstration is not that this can be drawn. It is that
d7 is written once, and the seven statements
about it are checked together, sealed together, and replayed together.
| The question it answers | What passing would prove |
|---|---|
| Can a static check catch cross-layer nonsense? | that a12 is at capacity while d7 is still committed to ord991 is a contradiction between the spatial and economic layers. No single-domain tool can see it, because no single-domain tool holds both |
| Does one identity really cost less than seven? | the integration bug class disappears rather than moving. If the layers still need reconciliation, node-alignment bought nothing |
| Is the film evidence? | an operator can hand a regulator one file that reconstructs the flight, the authorisation, the energy draw and the contract state — with no trusted runtime in between |
B · A resolved digital bus
The smallest demonstration, and the sharpest, because it is entirely falsifiable. A single-writer signal, a multi-driver resolved bus, high impedance, contention, a deterministic resolution function, and verified timing — with a right answer that hardware engineers already know.
profile wrl.digital.v1
; an OWNED terminal: exactly one writer, today's frozen rule
[reg:r0](width=8){q: owned<bits8>}
[gate:g0]{a: in<bits8>, y: owned<bits8>}
[r0] --sig--> [g0].a
; a RESOLVED terminal: many drivers, one named function.
; the resolution table is part of the sealed document —
; a bus whose resolver came from the runtime would break §11.
[bus:b0](width=8, resolve=std_logic){d: resolved<logic8>}
[driver:u1](oe=true) {y}
[driver:u2](oe=false){y} ; drives Z, high impedance
[driver:u3](oe=true) {y}
[u1] --drive--> [b0].d
[u2] --drive--> [b0].d
[u3] --drive--> [b0].d
| Case | Required outcome |
|---|---|
| Two drivers on an owned terminal | static error before the seal — the rule frozen in §0, unchanged |
| Three drivers on a resolved terminal, one enabled | legal. The value is the enabled driver's; the two Z contributions are absorbed by the resolution function |
| Two enabled drivers disagreeing | legal to write, and resolves to X — contention is a value, not a crash, exactly as in std_logic3 |
| The same world sealed on two machines | identical sem- id, because the resolution table is in the document |
| REACT settling a resolved terminal | one pass, because the resolution is a pure, total, deterministic function of one canonically ordered driver map, with a declared value for the empty map. It needs no algebraic laws at all: §D2.1 keeps idempotence for §9's join, where it makes redelivery harmless, and keeps associativity and commutativity only for a profile that opts into folding the driver set. Demanding any of them here would forbid "two enabled drivers is a fault" and "the strongest driver wins", which are ordinary bus rules |
C · A microgrid
The hardest of the four, because it needs an acausal electrical network solved inside a wall while five other layers proceed on the ordinary period cycle around it.
profile wrl.power.v1
; inside this wall the model of computation is not message
; passing — it is a system of equations (pillar 4)
wall electrical solver=power_flow.v1, tolerance=1e-6 {
[bus:b1](nominal=400V){pin}
[pv:solar](rated=50kW){pin}
[battery:bess](soc=61%, rated=120kWh){pin}
[feeder:f4](length=1.8km, r=0.31ohm){pin_a, pin_b}
; no writer, no direction: potentials equal, flows sum to zero
relation electrical acausal {b1.pin, solar.pin, bess.pin, f4.pin_a}
}
; outside the wall, ordinary WRL, ordinary periods
[scada:ops]{telemetry_in, dispatch}
[relay:p22](trip=overcurrent(1.2pu, 200ms)){fault_out}
[crew:team3](skills=hv){assignment}
[market:da](interval=1h){commitment}
[f4] ~~telemetry(rate=1hz)~~> [ops]
[ops] ==dispatch(cap=setpoint.v1)==> [bess]
[p22] !!fault(class=overcurrent)!!> [ops]
[ops] --assigns(eta=40min)--> [team3]
[bess] --commits(mwh=0.4, price=?p)--> [da]
What makes this a genuine test rather than a bigger picture: the electrical layer does not settle by passing values. Everything else does. A single world therefore contains two models of computation, and the wall is the only place they meet.
| The question it answers | Why it is hard |
|---|---|
| Can a solver live inside a period without infecting it? | the solve must be a deterministic function of the sealed inputs. A tolerance, an iteration order or a starting guess that varies makes the film unreproducible |
| Can a protection trip cross from the solved layer to the discrete one? | the relay reads a solved quantity and produces a discrete event, so the wall must define a crossing direction and a settlement order |
| Do the crew and market layers stay honest? | an assignment and a market commitment are obligations over the same identities as the physics. Today they live in three unrelated systems |
D · A road-network derive
The complete pillar 5 loop, end to end, and the one that decides whether "auditable optimisation" is a real category. A sealed road world, a fleet, a set of orders and a set of constraints go in; an untrusted external solver proposes; a deterministic checker accepts or refuses; the accepted plan is dispatched; execution produces a film.
profile wrl.logistics.v1
; inputs are sealed BEFORE the solver is asked anything
[roadnet:metro](source=#osm.metro.v3, edges=88214){graph}
[fleet:north](vehicles=12, capacity=1400kg){assignment}
[orders:batch7](count=340, windows=hard){demand}
[rules:law](max_shift=9h, rest=45min){constraint}
; the solver is an ORACLE. Its output is a claim, not a result.
derive plan by=solver(or_tools.routing.v9, seed=7, limit=30s)
from {[metro], [north], [batch7], [law]}
check feasibility.v1 {
; each of these is cheap to verify and expensive to find
every order served exactly once
every vehicle within capacity
every window respected
every shift within law.max_shift
objective recomputed from [metro].edge_costs
}
; only a CHECKED plan may be dispatched
[plan] ==dispatch(cap=fleet.command.v1)==> [north]
or_tools.routing.v9
seed 7. It may never say optimal. Feasibility is checkable in
about the cost of reading the plan; optimality is not checkable without redoing
the search. A language that let a derive stamp "optimal" on an unverifiable
result would be laundering a heuristic into evidence, which is worse than having
no derives at all.| The question it answers | What passing would prove |
|---|---|
| Can an untrusted engine participate in a sealed world? | a solver that is non-deterministic run to run7 can still contribute to a byte-exact film, because the film records the answer and the check, not the search |
| Is the checker actually cheaper than the search? | if it is not, derives collapse — either they seal unverifiable claims, or verification costs as much as solving and nobody runs it. This is falsification condition 2 |
| Does a third party need to trust the operator? | a regulator re-runs the checker against the sealed inputs and reaches the same verdict without the solver, the operator, or the runtime |
The dependency ladder
The spec insists its promotion order is "steered, not merely preferred" (§16) because each step supplies something the next one needs. The same discipline applies to everything on this page. Here is the ordering, with the reason each step cannot move earlier:
data-step
and data-capabilities, and the conformance suite
requires that every registered capability be delivered by exactly one rung
and that the rung number match the step the registry prints. An earlier version
of that check read only the printed numbers, and a reviewer demonstrated it was
decorative: swapping the steps of supervision and
dynamic-topology in the registry and re-sorting the
rows left the suite entirely green. That is precisely the dependency error this
ladder exists to prevent — promoting the fault route before the supervision floor
it requires — so the check was passing over the one bug it was written to catch.
It now fails by name. A commit message in this repository claimed the earlier
version was "the check that would have caught this commit's own bug"; it would
not have, and the overstatement is recorded here rather than quietly
corrected.| # | Step | Why it cannot come sooner |
|---|---|---|
| 1 | Typed ports and message schemas | every later feature has to say what flows; without this, attributes and behaviours are untyped strings |
| 2 | ~~ async route + mailbox surface | already §16 step 2. Telemetry is asynchronous; a fleet without it is a diagram |
| 3 | Profile mechanism — ProfileSchemaV1: relation kinds, attribute types, units, bounded resources and finite resolution tables | needs the type system from step 1, and nothing later. An earlier version of this row said "resolution functions", which need the expression notation from step 5 — a cycle in a ladder whose entire claim is that it is a dependency order. §D6.1 restricts the kernel to declarations, so the step is deliverable where it stands |
| 4 | Attributed relations (weight, capacity, units) and resolved terminals | needs step 3 to say what capacity=3 means, or "cost" is a name with no arithmetic and no unit |
| 5 | Behaviours | needs the expression notation, which §13 still lists as Experimental in its entirety |
| 6 | == verified route | §16.1: needs claimant, target, operation family and named policy all enforced — nothing less is a verified route |
| 7 | Supervision floor + !! | §16 step 6 is explicit: the fault route may only follow a supervision floor that actually exists |
| 8 | Dynamic topology | identities joining and leaving is meaningless without a lifecycle, and a lifecycle without supervision leaks. It also needs step 4's bounded resources before an escrowed attach can be safe under partition |
| 9 | Effect adapters (walls to ROS, devices, APIs) and the solver wall | a command that leaves the world needs step 6 to authorize it and a film to record it. Acausal relations settle here, because they settle in a solver |
| 10 | Derive boundary + checkers | needs attributes (4) to state constraints and effects (9) to matter |
| 11 | Production domain profiles — mobility, electrical, logistics, robotics | a profile pins roles, ports, units, laws and film schemas — it can only pin things that exist |
supervision too. The ordering was wrong, not the
reason.
It also had a cycle. Attributed relations were step 3 and domain profiles step 10, but §D8 says relation attributes are validated by a profile — so step 3 depended on step 10. The fix is that these were always two capabilities wearing one name: the mechanism for declaring kinds, types and units, and the production packages written with it. The mechanism is early because everything typed needs it. The packages are late because they can only pin things that already exist. The resolved bus can then be built against a small conformance profile without freezing the digital-circuit domain to get there.
[worker:w1]: freezing a decision about principals as
a side effect of shipping a demo. If a fleet profile is written before step 1,
its choices become precedent regardless of whether they were ever
sanctioned.What would falsify this
An honest direction document names the observations that would sink it. These are the five that would.
1 · If identity turns out to be per-layer after all normative statement
Node-alignment (pillar 1) assumes one identity is the right granularity across every layer. That assumption fails if layers need to version independently — if a drone's communications identity can be replaced (new radio, new certificate, new address) while its physical and contractual identity persist. If that turns out to be the common case rather than the exception, WRL needs per-layer replicas and explicit coupling edges, and the largest claimed advantage over conventional multilayer tooling evaporates.
2 · If checking is not cheaper than solving normative statement
Pillar 5 assumes a plan's feasibility can be verified far more cheaply than the plan can be found. That is true for routing with capacity and time-window constraints. It is not obviously true for every interesting derive — constraint systems exist whose solutions are no easier to check than to compute. Wherever that holds, the derive boundary provides paperwork rather than verification, and should say so instead of implying otherwise.
3 · If profiles cannot compose without a central registry normative statement
Pillar 4 assumes a wall can join two profiles knowing only their contracts. If in practice every cross-profile wall needs global knowledge — shared units, shared time bases, shared numeric conventions negotiated in one place — then "one world, many domains" degrades into a monolith with a plugin directory, and the composition claim was never real.
4 · If broadening the relation moves every published id normative statement
Pillar 6 assumes a general
Relation can serialise a plain directed route to the
same canonical bytes today's edge produces. Eliding defaulted fields is
not enough to achieve that, and §D8 now
says so: the frozen form names objects where the general form names terminals,
and calls the container edges rather than
relations, neither of which is a default that can be
omitted. The compatibility mechanism is therefore a normative legacy
projection — relations of exactly the frozen shape are encoded in the old
form — and the condition is whether that projection is total over the
published corpus. If some pinned world contains a route the projection
cannot cover, every sem- id ever published moves,
the change is a version break rather than an extension, and the ordering of the
entire ladder has to be reconsidered. This is still the cheapest condition on
the list to test, and it should still be tested first.
5 · If admission cannot be decided from sealed rules and recorded evidence normative statement
§D9 admits identities the document never enumerated by sealing an admission rule — trust roots, identity scheme, schema, checker, quota policy — rather than a roster of participants. A vehicle belonging to another operator can therefore join a sealed world mid-run, because what was sealed was the test it has to pass, not the list it has to be on. That construction fails if real federation requires consulting live external state at admission time — a revocation service, a broker's current view, a quota held somewhere else — which cannot be captured as evidence a replay can re-read. Then admission is not a function of the seal and the ledger, the film stops being self-contained, and the guarantee degrades to "it was true when we looked".
The first real test
Two different things get called "the first test", and separating them is the last piece of honesty this page owes.
The demonstration that would validate the thesis is demonstration A: a single world in which one identity participates in road, communications, dispatch, energy and fault topologies at once; executed across a multi-machine TRVM run; calling an external route solver through a derive; producing a film a third party can check without trusting the machine that produced it. That demonstration needs a production mobility profile, which is step 11 — the last rung — and the work between here and there is steps 1 through 10: typed ports, an async surface, the profile mechanism, attributes on relations, behaviours, a verified route, a supervision floor, dynamic topology, an effects boundary and the derive wall. None of it is glamorous and none of it can be skipped.
The demonstration that should be built first is demonstration B, the resolved digital bus. It is the smallest thing that is not already true: no solver, no continuous time, no new phase in the period cycle, and no new profile machinery beyond one resolution table. It exercises exactly one half of §D8 — many drivers meeting at one terminal — and every case in it has an answer that hardware engineers settled decades ago. That is what makes it valuable: it can fail in a recognisable way, which demonstration A cannot do for years.
The strongest version of WRL is not Erlang with prettier arrows. It is a language for living networks — where identities persist, topology has meaning, routes declare guarantees, walls declare authority, derives compute plans, periods order change, and films let someone else check the whole thing.
The last clause is the one that is already true. The rest is the roadmap.
References
- Kivelä, Arenas, Barthelemy, Gleeson, Moreno & Porter, “Multilayer networks”, Journal of Complex Networks 2(3), 2014 — node-layer tuples, aspects, and the intra-layer / inter-layer edge distinction.
- Modelica
Language Specification, ch. 9 “Connectors and Connections”, and
Modelica.UsersGuide.Connectors
— potential variables equalized,
flowvariables summed to zero. - VHDL
std_logic/std_ulogicand resolution functions — resolved vs unresolved types and multiple drivers. - ROS 2 documentation, “Quality of Service settings” — reliability, durability, history, depth, deadline, lifespan and liveliness as independent policies.
- Ptolemy II: Heterogeneous Concurrent Modeling and Design in Java — directors as models of computation, opaque composite actors, hierarchical heterogeneity.
- Eclipse
SUMO documentation, “Randomness” — deterministic by default from a fixed
seed;
--seedand--random. - google/or-tools issue #1331, “Highly variable, non-deterministic results in VRP”; #2212, time limit not respected inside the first-solution heuristic; and or-tools-discuss, “Deterministic solvers” — model ordering affects results.
- Unison, “The big idea” — definitions identified by a hash of their syntax tree; names as metadata over immutable hashes.
- R. Milner, The Space and Motion of Communicating Agents, Cambridge University Press, 2009 — a bigraph is a place graph and a link graph over one node set; links are hyperedges; reaction rules reconfigure structure and may create or destroy nodes.
- ISO/IEC 39075:2024, Information technology — Database languages — GQL — the first new ISO database language since SQL; standardises the property graph as a directed, labelled, attributed multigraph in which nodes and edges both carry properties.