WallRiderLangWRL CORE 0.1.2 · FROZEN
THE COMPLETE DESIGN DRAFT

The authored full-language draft.

Parts II–VI of the original design — the expression notation, capabilities, supervision, mailboxes, behavior blocks, fragments, stencils, derives, sealed tools, modules, build films, tests, FFI — with every section carrying the tier its author assigned it, so you can read the language whole and see exactly where the implementation stops. The later topology work is not on this page; it is documented separately in Direction and Core Part II.

Why the scope line matters. This page is a record, not a roadmap that has been kept up to date. It says what the language's author designed, in that author's own words and tier marks. Work done afterwards — node-aligned multilayer identity, relation attributes, resolved terminals, acausal connectors, profile-scoped models of computation, solver walls, domain profiles — is not in the authored draft and has deliberately not been merged into it. Folding later thinking back into an authored document would destroy the one thing that makes it worth publishing: you would no longer be able to tell which decisions the design actually made.

What this page is

WallRiderLang exists as two documents. The design draft is the complete, deliberately ambitious statement of the language: 46 sections across six parts, written as one argument. The frozen core extract is the small subset the TRVM Forge toolchain has actually grounded, and it is what Part I of the spec publishes.

Precedence, stated once. Where this page and the frozen extract disagree, the frozen extract wins. The draft is the design rationale and the forward map, not a ratified standard. Nothing here should be implemented verbatim as though it were settled, and no part of it should be announced as shipped until it has been extracted into a frozen core. The draft says this about itself, and this page repeats it because readers arrive here first.

The reason to publish the draft rather than only the frozen part is that a language you cannot see whole cannot be criticized. The frozen extract tells you the four objects you can wire together today. It does not tell you what the four route textures are for, why the podium needs a stable tie-breaker, why coherence has to be hash-pinned, or why derives are stratified. Those decisions are the language. They are also the part most likely to be wrong, so they are the part most worth exposing.

Part I of the draft — the four reading laws, containers, identity, routes, walls, time — is already published in full as the language guide. This page picks up at Part II and runs to the end.

The three tiers

Every section of the draft carries one of three status marks. They are the author's own classification, not a retrospective guess.

Core Grounded. The family is committed by the frozen extract: the set of members is closed and each member's meaning-role is settled. Freezing a family does not freeze exact glyphs, argument grammars, sugar, or edge-case rules.
Experimental Designed and internally coherent, but not grounded in a running implementation. Expect the details to move. Nothing in this tier is writable in the toolchain today.
Proposed Speculative or deliberately deferred. Expect substantial change or removal. Read this tier as a statement of intent, not a promise.

Three sections are split, because the split is real:

The reality check

Four corrections the draft makes about itself, because a status word alone hides the interesting distinctions.

1 · "Grounded" splits in two

A construct can be IR-grounded — the intermediate representation and runtime handle it — while being surface-ungrounded: there is no way to write it in source, and no round trip through the text form. Most of the Core-tier process machinery is in exactly that position. The frozen extract is a statement about families, not about what you can type.

2 · The mailbox is not a sixth role

MailboxDecl is IR-grounded. The async texture ~~ has no structural edge declaration, because an async message does not settle within the period and therefore cannot be an ordinary edge. The playground rejects [mailbox:m] as source for that reason, and formatCore refuses to emit a role its own parser would reject.

3 · A world and a run of a world are different documents

Periods and [epoch:N] claims are run inputs. They belong to a scenario document, are outside the SemanticArtifactID, and are rejected inside world source with WRL_WORLD_SOURCE_HAS_SCENARIO. Editing the world moves the id; editing the scenario does not.

4 · Of the four textures, only one is surface-grounded

-- can be written, sealed and round-tripped. ~~, == and !! have frozen notation and frozen guarantees, and no writable surface construct. In particular == is not nearly done — a verified route needs a checker identity, a policy version and an evidence hash, none of which have a surface form.

Source: WallRiderLang — Complete Design Draft, status note and reality check, revised for Core 0.1.2.

Part II — The expression notation

10 · The punctuation rule Experimental

The expression notation is where ordinary computation lives: values, records, arithmetic, functions, pattern matching, collections. It appears inside state cells, route arguments, guards, behavior blocks, derives and tests. It is deliberately conventional — the visual symbols describe the architecture of computation, not arithmetic.

The rule. The process alphabet owns punctuation globally. The expression notation defaults to words, and may claim a punctuation token only after passing a collision audit against every process glyph — in both the lexer and the eye.

That is why WRL writes mul rather than *, and and rather than &&. Not aesthetics: * is already the wildcard and replication mark, and & is already graph composition. The sanctioned set is closed, and each entry records what it was audited against.

PurposeTokenAudit note
arithmetic+ -+ is graph union in process position; split by grammar, not by guessing
multiply / divide / remaindermul div remwords — * is wildcard/replication, / is a boundary
comparison= < > <= >=never == (verified route) or != (! is the fault family)
logicand or notnever && (composition), || (parallel lanes), ! (faults)
error propagationtry expra word — postfix ? would collide with ?x pattern variables
paths / field access.state.status — never ::, which opens a fragment
match arms=>permitted; the formatter must never let an arm resemble a ==> route
return type->permitted; one dash versus two is the learnable distinction from -->
generics<T> attached to a nameMailbox<T>, Fixed<16>; standalone < > stay reserved
bindinglet var <-<- binds a pattern to a result
record updatewithrider with { energy=e }
closuresfn(x) exprnever |x| — the bar is a lane

Nothing else. Operator overloading of punctuation does not exist, and is permanently excluded rather than deferred.

11 · Values and data types Experimental

Algebraic data types: records, variants, tuples, recursive data. There is no null.

type Rider = {
  name: Name,
  watts: Watts,
  energy: Energy,
  status: RiderStatus
}

enum RiderStatus {
  staged,
  riding(lap: Int32),
  dropped(reason: DropReason),
  finished(time: Period)
}

enum Option<T> { some(T), none }
enum Result<T, E> { ok(T), err(E) }

These are the foundation of messages, actor state, boundary responses, films and evidence. Absence is Option. Expected failure is Result. A genuine fault travels on !! — that three-way split is enforced statically and is the subject of §24.3.

Values are immutable; updating produces a new value:

let next = rider with { energy = rider.energy - cost }

12 · Bindings, functions, effect rows Experimental

12.1 · Bindings

let introduces an immutable binding. var permits local mutation as sugar; it lowers to immutable SSA form, so shared mutable variables are impossible by construction, not by convention.

let cost = grade_cost(course.grade)
var total = 0        ; local only; lowers to SSA

12.2 · Actors do not replace functions

Actors are for identity, concurrency, persistence and fault domains. Pure functions are for local calculation. A function declares its effect row with uses; an empty row means pure.

fn drain(rider: Rider, cost: Energy) -> Result<Rider, Exhausted>
  uses {} {
  let remaining = rider.energy - cost
  match remaining {
    e when e >= 0 => ok(rider with { energy = e })
    _             => err(exhausted(required=cost, available=rider.energy))
  }
}

A pure function has no hidden effects, is deterministic, is callable from guards and from metaprograms, and never requires spawning an actor. This is the answer to "everything is an actor" bloat: most computation is not concurrency.

12.3 · Effect rows are the type face of capability walls

fn download_world(id: WorldId) -> Result<Bytes, NetError>
  uses { net.send, storage.write }

A call whose row is non-empty can only execute where an actor's ports grant those capabilities. The checker proves the row. §21 is the runtime half of the same statement.

12.4 · Portability is a type property, not ceremony

Closures exist: riders.filter(fn(r) r.watts > 350).

A closure whose effect row is empty and whose captures are all content-addressed values has a canonical graph — it is a fragment, and may travel as a message, be stored, or be stamped. A closure capturing a live capability or an affine resource handle is not portable, and using it where a portable value is required is a compile error that names the offending capture.

The :: … // syntax of §30 is the literal notation for fragment values — the notation for the property, not its source. This is how "a copied fragment inherits no ambient authority" becomes a theorem rather than a rule.

13 · Pattern matching Experimental

match message {
  Command.attack(at=?p)                  => …
  Command.recover(amount=?n) when ?n > 0 => …
  _                                      => …
}

Graph patterns use the same binding system, so one mental model covers data and topology:

[rider:?id](energy=?e, status=riding(?lap))
  --when(?e < 20)-->
/feed-zone
Matching is bounded and deterministic. There is no implicit search anywhere in the ordinary language. Rule patterns are anchored — the left side of a solid rule may match its own subject actor's cell and mailbox head, which is tree matching and cheap by construction. Topology-wide relational patterns are legal only in derives, which are offline, stratified and budgeted, or in explicitly scored search contexts on the expressive ceiling.

Non-exhaustive matches over variants are static errors unless a _ arm exists.

14 · Generics and traits Experimental

14.1 · Generics are parametric

Never token templates. Const parameters where needed.

type Mailbox<T>        type Port<T>        type Graph<T>
type Fragment<T>       type Result<T, E>   type Vector<T, N: Int32>
fn map<T, U>(items: List<T>, f: fn(T) -> U) -> List<U>

Stencil parameters and type parameters are related but distinct; a stencil may take both — ::: cache<K, V>(name, capacity: Int32) … ///.

14.2 · Traits, and no class inheritance

trait Hashable {
  fn hash(self) -> Hash
}

trait Merge<T> {
  fn join(left: T, right: T) -> T
}

trait Verify<Candidate, Evidence> {
  fn verify(candidate: Candidate, evidence: Evidence)
    -> Result<Verified<Candidate>, Rejection>
}

Traits map directly onto runtime policies. Merge instances implement <~merge~>. Verify instances implement ==verified==> checkers. Boundary adapters are trait implementations. The abstraction mechanism of the expression notation and the policy mechanism of the process notation are the same mechanism.

14.3 · Coherence is hash-pinned Experimental

Instance resolution is a correctness property here, not a style preference. <~merge~> converges because every replica applies the same commutative, associative, idempotent join. If two replicas resolved Merge<FactSet<T>> to different instances, they would diverge while each believed it had merged correctly.

Therefore: during canonicalization every trait-method call site is resolved to a concrete instance, and the instance's content hash is baked into the canonical bytes. Two replicas holding the same program hash hold the same join function, by construction. Instance selection can never vary by context, import order, or build.

15 · Numerics and determinism classes Experimental

Int8  Int16  Int32  Int64      UInt8 … UInt64
Float32  Float64                Decimal
Fixed<Q>                        Duration   Period

Integer semantics are fully defined and identical on every target. Overflow is checked by default; wrapping_add, saturating_add and friends are explicit. Quotient truncates toward zero and remainder takes the dividend's sign, identically everywhere; div_euclid and rem_euclid variants exist. No numeric behavior may depend on build mode or platform.

Floating point is a determinism hazard and is treated as one. Identical executables on identical hardware reproduce float results; across hardware, compilers or optimization settings they do not — fused multiply-add, SIMD variation and transcendental library differences all break bit-equality. The answer is determinism classes bound to execution profiles.

ProfileSimulation-state numericsFloats
world
lockstep console/desktop
Fixed<Q>, integersforbidden in state cells; permitted on the presentation/effect side only
pure / replayFixed<Q>, integers; Float64 with #[det=bitexact]strict IEEE-754, no FMA, no fast-math, pinned softfloat transcendental artifact
effect side of any wallanythingfloat results are observations; their hashes enter the film like any effect

The corresponding static check: a Float may not appear in a state cell of a world-profile actor. Duration is a wall-clock quantity and therefore effect-side; Period is logical time and replayable.

16 · Collections, strings, symbols Experimental

List<T>   Vector<T, N>   Map<K, V>   Set<T>   Bytes   String
Queue<T>  Mailbox<T>     FactSet<T>  Stream<T>

Every collection defines deterministic iteration order, canonical serialization, equality and hashing, and documented complexity. Nondeterministic map iteration does not exist — it is on the exclusion list, not the roadmap.

Set<T> and FactSet<T> are different types on purpose. A Set is a local collection. A FactSet is a monotonic join-semilattice — a claim that its merge obeys the lattice laws. Collections are never silently CRDT-mergeable; replication is opt-in by type.

Data iteration is textual and never uses periods. The dot family means logical time and nothing else:

for rider in riders { … }
map(riders, score)
fold(results, initial, combine)

Four things other languages conflate are four different things here:

"rider a"      String — data
rider_a        identifier — a name in source
#rider-a       tag / content identity
@rider-a       address / stamp

Interned symbols exist as Symbol; the intern table is bounded per sealed scope and cannot grow without limit at runtime.

17 · Resources and ownership Experimental

The ownership model is small and sufficient: values are immutable; actor state is singly owned; messages are immutable; large binaries use shared immutable storage; external resources are affine handles; and capabilities cannot be duplicated unless their type permits it.

resource FileHandle
resource GpuBuffer
resource Socket

fn upload(buffer: borrow GpuBuffer) -> Result<Receipt, GpuError>
fn close(socket: move Socket)

A resource is consumed, moved, or explicitly borrowed. There are no shared mutable pointers anywhere in the language.

Part III — Process semantics

The five memory kinds (§18), the period cycle (§20.1–20.5) and the two invariants are covered in the guide. This part picks up the machinery built on top of them.

One place the draft is out of date. The draft states the period cycle as five phases — Collect, Order, Reduce, Commit, Record. The frozen errata replaced it with six: OBSERVE, ACCEPT, MAP, COMMIT, REACT, FILM. The five-phase statement is superseded. The invariants it was there to justify — canonical event keys, within-period fixpoint, conflicts dissolving — are unchanged, and the guide states the frozen version.

19 · Runtime entities Core

An implementation needs exactly six semantic entity types. Not five, not seven — this is the closed list.

EntityWhat it carries
Actora stable identity, a current state cell, a mailbox, a declared port/capability set, an optional supervisor, a deterministic behavior table (the solid rules whose source is this actor), resource counters and status
Valueimmutable. Updating state produces a new value at the same identity at the next logical step
Edgesource, destination, label, texture, payload expression, policy, provenance. Decorative line length is not stored
Boundarymediates propagation: stop, filter, authorize, commit, snapshot, rank, externalize, or seal
Fragmentquoted graph data with hygienic holes and explicitly captured identities; typed Fragment<T>
Stencila deterministic, hygienic, resource-bounded, canonicalizable map from parameters to a fragment; typed Stencil<Args, Fragment<T>>
A known collision with the later topology work. Edge above is a binary directed pair. The topology extrapolation needs connections that are attributed, that admit several drivers meeting at one resolved terminal, and that have three or more participants and no direction at all — none of which a source/destination pair can hold. The resolution is not a seventh entity type: the closed list of six stands, and the third member is broadened from Edge to Relation, with today's directed route as its simplest specialisation. That argument, its cost to the identity ladder, and what it must deliver before shipping are in Core Part II §D8. It is recorded there rather than edited into this table, so that the authored ontology stays legible as the authored ontology.

20.6 · Boundaries are reduction operators Core

A wall is not decoration around a diagram. Each boundary is a reduction operator with a defined effect on memory.

BoundaryReduction effect
/gaterequire the named capability in the crossing fragment's ports; emit an effect-request node rather than performing I/O
//commitcanonicalize the fragment so far and assign it a content id; it becomes immutable
//finisha commit boundary that may also receive race or workflow arrivals
///sealperform //commit, then register the artifact under a content hash and an optional name

A gate authorizes and externalizes; a commit freezes; a seal freezes and content-addresses. The finish line is literal: crossing //finish is the canonicalize-and-record reduction, which is why it can feed a podium directly.

20.7 · The podium Experimental

oN. consumes an eligible result set that has crossed a boundary this run and reduces it to a provenance-carrying object with N named places.

Podium {
  places: [r; N],        ; missing places are explicit _
  ranking_policy,
  evidence,
  source_boundary
}
//finish ==rank(by=time, tie=#id)==> o3.
[winner, second, third] <- o3.
Ranking must name a stable tie-breaker. Arrival order and scheduling are never acceptable implicit tie-breakers — a podium that depended on them would not survive replay, which defeats the point of having one. Omitting the tie-breaker is a static error.

The podium can rank anything, not only race results. o0. is accepted as sugar for o3. where the three-place reading is intended.

20.8–20.11 · Messages, schedules, determinism, quiescence Core

Messages are immutable facts

A ~~msg~~> in period t appends:

{ msg_id, sender, receiver, payload_hash,
  send_tag=(t,m), delivery_policy, provenance }

Delivery is a separate event. Under the default policy a message sent at (t, m) becomes deliverable no earlier than (t+1, 0). An actor cannot observe its own send within the same period, which keeps periods well-founded and forbids same-period causal loops. Exactly-once processing is not assumed; deduplication keys and acknowledgements are explicit.

Scheduled events

..after(periods=k)..> at period t creates an event due at t+k. ..after(5s)..> desugars through a /time wall that converts the duration into a period count; the observed conversion is a signed fact, so replay uses the recorded count and never a live clock.

The determinism property

Given the same initial configuration and the same sequence of external observations — the signed facts crossing effect walls — the committed film is byte-identical across any hardware scheduling.
Editorial correction. The authored draft's proof sketch for this property is written in the superseded five-phase vocabulary flagged at the head of Part III — it argues that "Collect and Order depend only on configuration content" and that "Commit and Record are deterministic functions of Reduce". Those phases no longer exist. The claim is unchanged and still holds; the argument below is the same argument restated over the six frozen phases. This is the one place on this page where the author's words have been replaced rather than merely annotated, because leaving them would have made the page assert a cycle the language does not have.

The argument is short, and it is one clause per phase. OBSERVE canonicalizes external claims. ACCEPT creates missing receipts under pinned policies. MAP deterministically derives controls from newly accepted operations. COMMIT applies a canonically ordered compatible write set. REACT settles the same-period cascade by deterministic microsteps to fixpoint. FILM serializes every state variable and observation required to determine future behavior.

Nothing in that chain consults arrival order, wall-clock time, address identity, or iteration order over an unordered container. The write set is compatible because there is no destructive state conflict — only commutative appends and lattice joins — and it is canonically ordered because the ordering key is content, not schedule. The only entry point for nondeterminism is effect-wall observations, and those are captured in the film — so replay is exact.

Consequently "the same sealed film runs identically on desktop and console" is a testable property rather than a hope, provided the numeric rules of §15 are respected.

Termination is not quiescence

A graph is locally quiescent when no solid transition is enabled, no message is deliverable this period, no scheduled event is due, no actor is runnable, and all required boundary commits are complete. A distributed run is complete only under an explicit termination detector or a sealed finite-horizon film. Importing state that marks actors runnable invalidates a prior quiescence conclusion; restored work must be rescheduled before termination is declared.

21 · Effects, capabilities, entropy Experimental

All non-deterministic or external action crosses a named wall. No effect happens invisibly.

[request] --> /net
[frame]   --> /gpu
[sound]   --> /audio
[file]    --> /storage

An adapter returns a signed observation, and that is what enters the film — so a replay reproduces the run without repeating the call:

/net ==observed(response=#hash)==> [requester]

Capabilities live at boundaries and ports and are typed as the effect rows of §12.3. A copied fragment inherits no ambient authority; captured capabilities must be named:

[actor]{net.send}
[request] --> /net requires net.send
Randomness is an effect. All of it — simulation noise, scored-branch exploration seeds, scheduler-fuzzing seeds — enters through /entropy as seeded streams whose seeds are recorded as facts. Any run, including a randomized test exploration, therefore replays exactly from its film. This is what makes §37.2 possible.

Effect walls are the only source of nondeterminism in the language. Everything else is a pure function of configuration content.

22 · Merging replicated facts Core (union law) Proposed (trust)

Monotonic knowledge merges as a CRDT join-semilattice. The merge is commutative, associative and idempotent; convergence follows from those laws alone.

[node:a] <~merge(facts)~> [node:b]
[node:a]{facts} + [node:b]{facts} --> [facts:joined]

<~merge~> canonicalizes both fact sets, unions them, and deterministically reduces. + is monotonic union, not arithmetic addition. The join function is a Merge<T> instance whose content hash is pinned into the program's canonical identity (§14.3) — so every replica of a given program hash provably applies the same join.

Semantic convergence is a separate concern from work efficiency; an implementation reports duplicate work, verifier work and divergence cost independently.

The split. The union law is Core. The trust and evidence policy for dishonest peers is Proposed and deliberately left open — the CRDT laws guarantee convergence among honest replicas and say nothing whatever about Byzantine ones. See §45.

23 · Verification and sealing Core

A verified route requires evidence satisfying a named policy. The runtime does not infer what "verified" means. Verification is a protocol with an explicit checker identity — a Verify instance from §14.2 — a policy version, inputs, a result and an evidence hash.

[candidate]
  ==verified(by=proof, policy=forge.v1)==>
[film:#hash]

A failed verification travels on an explicit rejection route to a quarantine boundary — it does not silently vanish:

[candidate] !!reject(reason=?r)!!> /quarantine

Sealing (///) content-addresses the result, making it a reusable immutable artifact.

This is the section that explains why == is not nearly done. Four things have frozen meaning and no surface: the checker identity, the policy version, the evidence hash, and the rejection route.

24 · Supervision, faults, the error ladder Experimental

24.1 · Supervision

The caret denotes upward supervision or promotion:

[worker:a] ^ [supervisor:pool]

A supervisor deterministically chooses a policy in response to a fault — the response is a rule, not a callback:

[supervisor:pool](policy=restart_one)
  --on(crash(worker=?w))-->
@worker(id=?w, restored_from=last_checkpoint)

24.2 · Rest and wake

The underscore is a parked or quiescent actor state — observable, and therefore usable to define termination, snapshot safety and scheduler economics:

[worker:a] --> _
[queue] ~~job(?j)~~> [worker:a] _--> active(job=?j)

24.3 · The error ladder

Three levels, kept distinct, and the distinction is statically checked — this is the section most often skimmed and it is the one that does the work.

LevelMeaningForm
normal absence / alternativenot an error at allOption<T>
expected failurean anticipated bad outcome; a valueResult<T, E>err(file_not_found)
faultcorrupted invariant, crashed adapter, genuine breakage!!crash(reason)!!> — engages supervision

A missing file is err(file_not_found). A corrupted driver is [storage] !!crash(reason=corrupt_driver)!!> [supervisor]. A path that is a normal outcome must not silently become a fault; !! is reserved for faults and the checker rejects the promotion — in both directions.

25 · Mailboxes, streams, backpressure Experimental

Mailboxes are bounded by default. An unbounded mailbox is rejected unless an explicit policy says otherwise.

Mailbox<Job, capacity=1024, overflow=reject>
Overflow policyBehaviour
rejectthe sender receives a normal Result-level refusal — not a fault
shed_oldestdrop from the head; the shed is recorded as a fact
shed_newestdrop the arrival; the shed is recorded as a fact
backpressureparticipate in demand signalling

Backpressure is explicit demand signalling. Producers send only what consumers have demanded — there is no implicit flow control to reason about:

[consumer] ~~demand(32)~~> [producer]
[producer] ~~items(batch)~~> [consumer]

The stream vocabulary is Stream<T>, Subscription<T>, CancelToken, Demand. Cancellation is a normal message, observable in the film; a cancelled producer winds down through ordinary routes, not through faults.

26 · Actor behavior blocks Experimental

Routes are excellent for diagrams; complex actors also need an organized textual home. A behavior block declares an actor's state shape, ports and handlers in one place.

actor rider(name: Name, watts: Watts) {
  state (name=name, watts=watts, energy=100, status=staged)

  ports {
    radio: Mailbox<Command, capacity=64, overflow=reject>,
    road: Port<RideEvent>
  }

  on ~~Command.attack(at=?t)~~> {
    [self] --set(status=attacking(?t))--> (state)
  }

  on --tick--> when state.status = riding(?lap) {
    (state) <- try drain(state, 8)
  }

  on !!crash(?reason)!!> {
    [self] !!report(?reason)!!> [supervisor]
  }
}

The same actor, drawn. Every handler above is a route here, and the claim is that the two spellings are not merely similar but byte-identical after canonicalization:

profile forge.world.core.v1

[rider:self](name=name, watts=watts, energy=100, status=staged)
  {radio: Mailbox<Command, capacity=64, overflow=reject>, road: Port<RideEvent>}

[self] ~~Command.attack(at=?t)~~> [self].set(status=attacking(?t))
[self] --tick--> [self].drain(8) when status = riding(?lap)
[self] !!crash(?reason)!!> [supervisor]
A behavior block is a projection, not a second semantics. It canonicalizes to exactly the same behavior table — and therefore the same content hash — as the equivalent drawn routes. This is a conformance requirement: for every construct with both a drawn and a textual form, the two forms produce identical canonical bytes. The language has two surfaces and one meaning, permanently.
This pair is a registered future equivalence claim, not a comment — and not yet an executable obligation. The two blocks above are tagged with the same equivalence id in the page source. Today the suite checks only what is checkable today: that the pair is well-formed, that neither spelling is accepted, and that both spellings wait on the same prerequisites — a pair whose two halves disagreed about what they need would already be evidence that the claim was confused. Whether they genuinely produce the same sem- id cannot be tested until behaviours exists to seal them; no amount of harness work can extract that answer from a toolchain that rejects both inputs. What the tag buys is that the claim is recorded, located and enumerable, so when the capability is promoted the obligation is waiting rather than remembered. Registering a claim is a weaker thing than enforcing one, and it is worth naming the difference.

27 · Evolution: migration and compatibility Experimental

27.1 · Live-state migration

Content-addressed modules evolve code: a new implementation is a new hash and names re-point. But a persistent actor in the world profile holds state typed by the old version, and re-pointing a name transforms nothing. Live state evolves through an explicit verified migration:

(state: Rider@#a91) ==migrate(policy=rider.upgrade.v1v2, by=#m7)==> (state: Rider@#b12)

A migration is a verified route: evidence-carrying, recorded in the film, orchestrated by supervisors (drain to _, migrate, wake), and replayable. A world upgrade is a sequence of migrations, not an improvisation.

27.2 · Message compatibility

Message types are content-addressed like everything else. A mailbox accepts the message hashes its port type declares; an unrecognized hash is a normal outcome, never a fault — which is what leaves room for explicit adapter routes between versions:

on ~~unknown(#msg)~~> {
  [self] --forward(#msg)--> /adapter.v1v2
}
Part IV — Metaprogramming

Metaprogramming is a defining capability of the language, not an accessory — and it is not textual substitution.

WRL is homoiconic over its canonical graph, not its surface text. A metaprogram inspects and produces typed graph nodes, and can never distinguish --go--> from ----go---->, because those are the same edge. Raw token arrays are not exposed. Every property in this part follows from that one decision.

28 · The three phases Proposed

The expression notation evaluates at three moments. It is the same language at each; the phase determines only what exists to be touched.

PhaseWhat runsCapabilities available
expansion timestencil bodies; derives over Graph<T>pure only; no walls exist yet; fuel-bounded; host-blind
verification timeVerify policy checkers behind ==verified==>the checker's declared capabilities only
run timeguards, cell updates, handlers, ordinary computationwhatever the actor's ports grant

The build pipeline fixes when expansion happens: stencils expand, then derives evaluate to fixpoint, before canonicalization and hashing — and long before any reduction runs. Metaprograms cannot modify sealed artifacts; they produce new graphs, and therefore new hashes.

29 · The six laws of metaprogramming Proposed

#LawWhat it buys
1Hygiene by default. Identities minted by an expansion never collide with identities at the expansion site. @worker_pool(a) and @worker_pool(b) produce distinct internal queues, clocks and supervisors unless a capture is explicitly sharedcomposition without name discipline
2Phase separation. Every metaprogram knows which phase it runs in; expansion-time code cannot reach forward into run time, and sealed artifacts cannot be reached backwardno build/run confusion
3No ambient authority. A metaprogram gains no network, filesystem, model, clock or package access from the compiler that runs it. Pure by default; anything else is a sealed toola build cannot phone home
4Resource-bounded expansion. Stencil recursion must be structurally decreasing; general expansion carries explicit fuel. A build that exhausts fuel fails — it never silently emits a partially expanded programexpansion terminates
5Generated structure remains visible. Tooling always offers the collapsed invocation, the expanded graph, per-node provenance, the canonical bytes actually hashed, and diffs between expansionsno invisible macro magic
6Expansion is hermetic and host-blind. Expansion-time code has no I/O facilities at all and cannot observe the build machine — no host paths, clocks, endianness or environmentreproducible and cacheable everywhere
; law 4, spelled
#[meta_fuel=10_000, max_nodes=50_000]

Laws 3, 4 and 6 are not ergonomics. They are the premises of the no-build property — without host-blindness there is no sound cache key, and without fuel there is no guarantee the key ever gets computed.

30 · Fragments Proposed

:: opens a quoted graph fragment; // closes it. A fragment is a first-class value of type Fragment<T>data until stamped or explicitly executed. It supports typed holes, explicit captures, hygienic local identities, copying, transport as a message, signing, storage, inspection and canonical hashing.

:: breakaway(leader=?l, mate=?m)
  [rider:?l] ~~signal~~> [rider:?m]
  [rider:?l] --accelerate--> [road]
//

Free variables are illegal unless declared as holes; captured identities must be named:

:: with_clock(capture [shared:clock], hole ?target)
  [shared:clock] ~~tick~~> ?target
//

Copying a fragment mints fresh local identities unless an identity is explicitly marked shared. Because a fragment is a value, it travels as a message payload — code as a message:

[coach] --plan(::breakaway//)--> [team]

A fragment does not run merely because it exists. It must be stamped, executed, or crossed through an appropriate boundary. That is what makes "code can move" safe rather than alarming.

31 · Stencils Proposed

31.1 · The ordinary metaprogramming mechanism

::: opens a typed, hygienic graph constructor; /// seals it. Most things that are classes, component definitions, declarative macros, annotations, or infrastructure templates elsewhere are stencils here.

::: rider(name: Name, watts: Watts)
  : [rider:#name](
      watts=watts,
      energy=100,
      status=staged
    ){
      road: Port<RideEvent>,
      radio: Mailbox<Command, capacity=64, overflow=reject>
    }
///

Stamping instantiates: : @rider(a, 330). Idiomatic stencils scale from one actor to whole architectures — @supervised_pool(workers=8), @replicated_archive(nodes=3), @forge_pipeline(policy=world.v1).

31.2 · Identity derivation

Hygiene demands fresh identities per site. Incremental builds and stable diffs demand the same identities on every rebuild. Both hold via one normative formula:

#child = H( stencil#, canonical(args), path-within-expansion )

Same stencil, same arguments, same position ⇒ the same identity on every rebuild. Different site or arguments ⇒ a different identity. Colliding identities are caught at expansion, never at run time.

31.3 · The expansion pipeline

Stamping performs, deterministically: normalize arguments → allocate derived identities by the formula → substitute parameters → alpha-rename locals → validate capabilities and budget → canonicalize → attach provenance.

32 · Derives Proposed

Some transformations are inconvenient as stencils — cross-cutting rules like "every faultable actor gets a supervisor". Those are derives: expression-notation functions over typed graphs, evaluated at expansion time.

derive supervise_faulting(g: Graph<Actor>) -> Graph<Supervision> {
  for actor in g.actors
  where actor.can_fault and actor.supervisor = none
  emit actor ^ [supervisor:#actor.id]
}

Invocation stamps the derive over a fragment, like a stencil: @supervise_faulting(::workers//).

Three normative restrictions give derives their guarantees:

RestrictionWhat it guarantees
1 · Intrinsically typed. A derive f(g: Graph<A>) -> Graph<B> is checked once at its definition; the type system guarantees every output is a well-formed Graph<B>derive output needs no re-checking, and the build pipeline never loops
2 · Stratified and monotonic. A derive may read, filter and emit; it may not delete or mutate emitted structure; negation only across stratatermination (stratified evaluation reaches a fixpoint), confluence (monotonic rules commute, so derive order cannot change the result — the same law that makes fact merges safe), and incrementality
3 · Semantics, not spelling. A derive sees typed canonical nodes; it cannot observe formatting, layout, comments, or anything else canonicalization removesa reformat can never change what a derive emits

Anything genuinely non-monotonic — deletion, rewriting, arbitrary recursion — belongs to sealed tools. That is the principled boundary between the two levels, and it is why the stratified system can be trusted without a budget on trust.

33 · Sealed tools behind /compiler Proposed

Parsers, schema generators, GPU layout generators, binding generators, asset importers — procedural power that cannot live in the stratified system — run as sealed tools behind an explicit compiler capability wall.

[schema:#game] --> /compiler
/compiler ==generated(tool=#generator-hash)==> [bindings:#hash]

A sealed tool requires: a pinned tool hash; explicit input hashes; declared capabilities; CPU and memory budgets; deterministic output where possible; recorded provenance; and a sealed generated artifact.

Because tools are content-addressed, capability-declared and budgeted, they can be published, signed and verified with the same ==verified==> machinery as everything else — compiler extensibility without compiler trust. Every tool invocation appears in the build film.

34 · Reflection Proposed

Compile-time reflection over canonical structure is rich and free:

graph.actors      graph.routes       graph.boundaries
type.fields       fragment.holes     fragment.capabilities

Runtime reflection is capability-controlled. A mirror over an actor is a capability — {reflect: Capability<Mirror<Pool>>} — that must be granted like any other port. Unrestricted runtime reflection over private actor state does not exist.

Part V — Programs at scale

35 · Modules and the no-build property Proposed

35.1 · Content-addressed modules

module race.timing@#a184

export { Time, FinishResult, rank_finish }

import trvm.facts@#91bc as facts
import forge.world@#33ae as world

Human-readable names and versions are metadata that point to immutable hashes:

[email protected] -> #a184

A locked build stores the hashes, not only the human versions. Upgrading never mutates a sealed artifact; it produces a new artifact with a new hash, and names re-point. Because downstream references are to hashes, nothing silently changes underneath a consumer — a consumer opts into a new version by re-pointing a name. Live actor state evolves separately, by migration.

35.2 · The no-build property

Property. Given pure, host-blind, fuel-bounded expansion — Laws 3, 4 and 6 — over content-addressed inputs, build caching by memo[(transform#, input#)] = output# is sound with no invalidation logic. A hash either matches or it does not.

Incremental compilation, distributed build caches and perfect reuse across machines follow immediately. The hard problem of incremental build systems — knowing when a cached result is still valid — does not exist here, because validity is hash equality. This is the single strongest argument for paying the canonicalization cost.

36 · Build films Proposed

The build pipeline is itself a deterministic process with effects only at declared walls — so it is recorded as one. Every build emits a build film: which stencils expanded with which arguments, which derives fired, which trait instances were resolved and pinned, which sealed tools ran against which input hashes, and what was hashed.

wrl replay build.film

Consequences: any build reproduces bit-for-bit; provenance views (Law 5) are film queries; and "why does this node exist?" has the same kind of answer at compile time as at run time. One mechanism, both worlds.

37 · Testing and conformance monitoring Experimental

37.1 · Tests are first-class graph specifications

test "formatting does not affect identity" {
  hash(program_a) = hash(program_b)
}

property "fact join is commutative" {
  for all a, b: join(a, b) = join(b, a)
}

film_test "worker restart" {
  run scenario
  restore checkpoint
  expect same observables
}

37.2 · The language is simulation-native

Every prerequisite of deterministic simulation testing — a deterministic scheduler, virtualized time, randomness funnelled through recorded seeds, effects behind mockable walls — is a construction property of the language, not a retrofit. So the test runner explores adversity as ordinary execution:

check schedules=10_000
check partitions=100
check restores=100
check scores=all          ; systematically enumerate scored-branch choices

Exploration randomness enters through /entropy, so every failing exploration replays exactly from its film. Scheduler randomization, fault injection, partition simulation and restore testing are modes of the one deterministic machine rather than four separate tools.

37.3 · Film conformance monitoring

A film is a total record and a sealed specification is executable — so conformance is a diff. An implementation may continuously validate production films against a sealed specification film's invariants, closing the gap between the verified design and the running system: the model and the implementation are the same graph.

38 · Foreign functions Proposed

The FFI is boundary-based. Impure native calls cross a named wall and return observations:

[physics_request] --> /native.physics
/native.physics ==observed(result=#hash)==> [world]

Pure native functions may be imported as verified deterministic modules:

extern pure fn vec_dot(a: Vec3, b: Vec3) -> Fixed<16>
  from artifact #native-math-v3

Every extern pins the target ABI, the compiler/toolchain hash, the native artifact hash, the declared effects and the determinism class. An extern pure claiming bit-exact determinism is testable against that claim, and is rejected if the artifact's outputs vary across supported targets.

Part VI — Reference

Canonicalization (§39) and the grammar (§42) are published in the reference tables and the guide. What follows are the four reference sections that state what a conforming implementation must refuse, offer, never and prove.

40 · Static checks Experimental

A conforming checker rejects all of the following. Each is a load-bearing invariant of some earlier section, restated as a refusal.

A conforming checker rejects…Because
duplicate durable identities in one sealed scopeidentity is the whole point
unbound pattern variables; free variables in quoted fragments§30 hygiene
overlapping deterministic branch guardsthe second invariant of the execution model
shared mutable cellsthe first invariant; conflicts must dissolve
routes crossing undeclared capability walls; direct effects outside named boundaries§21
a Float in a state cell of a world-profile actor§15 determinism classes
an unbounded mailbox without an explicit overflow policy§25
a non-anchored multi-node pattern on a rule's left side§13 — no implicit search
a capability or affine-resource capture in a value used where portability is required§12.4
expression-layer punctuation outside the sanctioned set§10.1
a derive that deletes or mutates emitted structure§32 monotonicity
a normal-outcome path promoted to a fault, or a fault demoted to a value§24.3 — the ladder is checked in both directions
non-exhaustive matches over variants without a _ arm§13
missing stable tie-breakers for oN.§20.7
recursive stencil expansion without a decreasing budget; expansion exceeding declared fuelLaw 4
mutation of content-addressed sealed artifactssealing means sealed
scheduler arrival order used as semantic datareplay exactness
mismatched :: // or ::: /// scopesthe only paired scopes in the language

41 · Execution profiles Experimental

An implementation may offer restricted profiles that trade expressiveness for guarantees. A profile is not a compiler flag — it changes what the checker accepts.

ProfileCharacteristicsSimulation-state numerics
pureno effect walls; finite fuelintegers, Fixed<Q>; Float64 only with #[det=bitexact]
replayeffects supplied only from a filmas pure
sandboxnamed adapters with quotasas pure
worldpersistent actors; bounded per-period reductions; lockstep-capableintegers, Fixed<Q>; floats forbidden in state cells
forgegeneration plus verification gatesas pure
clusterreplicated facts and reconciliation; termination distinct from quiescenceas pure
The minimal conforming implementation. Staged actors, the four core route textures, single / walls, :: … // fragments, .n period repetition, ? variables, | guarded branches, _ quiescence, and the expression core (records, variants, Option/Result, pure functions, match) — enough to observe the deterministic reduction property. Podium, stencils, derives, verified routes, merge, behavior blocks, streams and the spatial canvas may be added incrementally without changing the core semantics.

43 · Seven worked examples

These seven span sports, distributed systems, fabrication, biology, machine-assisted patching and a versioned service. Together they exercise every construct in the language — which is exactly why none of them can be written today. Each carries a note saying which tiers it depends on.

Read these as the target, not as a tutorial. The surface you can actually type is the world-core: a profile line, five roles, solid edges and ports. If you want to write something and seal it, start at the tutorial; if you want to know what the language is aiming at, read on.

43.1 · Criterium race

staging · stencils · periods · async · finish · podium

; a five-lap criterium with async team radio and a podium

::: rider(name, watts)
  [rider:#name](watts=watts, energy=100, lap=0, status=staged){road, radio, timing}
///

: @rider(a, 330)
: @rider(b, 295)
: @rider(c, 410)
: @rider(d, 305)
: [coach](plan=wait_then_attack)
: [clock](period=0)

{
  [coach] ~~radio~~> [rider:*]
  [rider:*] ~~draft~~> [rider:next]
  [clock] ..tick..> [rider:*]
}

(
  [clock](period=?t) --advance--> (clock period=?t+1)
  [rider:*](lap=?l, energy=?e) --ride(cost=8)--> (rider:* lap=?l+1, energy=?e-8)
  [coach](plan=wait_then_attack) --when(clock.period=4)--> (coach plan=sent)
  [coach] ~~attack~~> [rider:c]
).5

[rider:*] --sprint--> //finish
//finish ==rank(by=time, tie=#id)==> o3.
[winner, second, third] <- o3.
///race-result

Read the last three lines together. The finish line is a commit boundary, so crossing it is what makes a result rankable; the rank policy names a stable tie-breaker because a podium without one would not replay; and the seal content-addresses the outcome. Nothing here is a library function.

43.2 · Supervised worker pool

mailboxes · quiescence · faults · restart

::: worker(id)
  [worker:#id](status=idle, checkpoint=0){jobs: Mailbox<Job, capacity=256, overflow=reject>, supervisor}
///

: [supervisor:pool](policy=restart_one)
: @worker(a)
: @worker(b)
: @worker(c)
: [queue](jobs=[j1, j2, j3])

[worker:*] ^ [supervisor:pool]

[queue] ~~job(?j)~~> [worker:*]
[worker:*] _--> active(job=?j)
[worker:*] --perform(?j)--> (worker:* status=idle, checkpoint=?j)
[worker:*] --> _

[worker:b] !!crash(reason="bad input")!!> [supervisor:pool]

[supervisor:pool](policy=restart_one)
  --on(crash(worker=?w))-->
@worker(?w, restored_from=last_checkpoint)

[supervisor:pool] ==pool_quiescent==> //done

This is the example WRL is weakest against today, and the site says so elsewhere: there is no supervision floor, no writable mailbox, no runtime-spawnable process. The design is stated; the runtime is not there.

43.3 · Replicated fact lattice

CRDT merge · partition · convergence

: [node:a]{facts, peers}
: [node:b]{facts, peers}
: [node:c]{facts, peers}

[worker:a] ~~candidate(program=#p1, result=true)~~> [node:a]
[node:a] --verify(program=#p1)--> [fact:#f1]
[fact:#f1] ==accepted(by=node:a)==> [node:a]{facts+#f1}

[node:a] <~merge(facts)~> [node:b]
[node:b] <~merge(facts)~> [node:c]

/partition
[node:a] <~blocked~> [node:c]
[node:c] --derive(from=#f1)--> [fact:#f2]

/partition --open--> _
[node:a] <~merge(facts)~> [node:c]
[node:b] <~merge(facts)~> [node:c]

[node:a]{facts} ==same_hash==> [node:b]{facts}
[node:b]{facts} ==same_hash==> [node:c]{facts}
///converged

The partition is a boundary, not a failure mode bolted on for testing. Convergence is asserted as an ordinary verified route between two fact sets, which is only meaningful because the join instance is hash-pinned.

43.4 · Forge world fabrication

model wall · checks · verification · seal

: [brief](goal="coastal cycling city", players=64)
: [seed:#city17]

[brief] & [seed:#city17] --derive--> [world_spec]
[world_spec] --> /model
/model ==observed(candidate=#layout1)==> [layout:#layout1]

[layout:#layout1] --check_connectivity--> [report:roads]
[layout:#layout1] --check_spawn_safety--> [report:spawns]
[layout:#layout1] --check_budget--> [report:budget]

[layout:#layout1]
  & [report:roads] & [report:spawns] & [report:budget]
  ==verified(policy=forge.world.v1)==>
[film:#world17]

[film:#world17] --> /gpu
/gpu ==preview(frame=#preview17)==> [designer]
[designer] ~~approve~~> [film:#world17]
[film:#world17] ==seal==> ///world17

A generative model sits behind /model like any other effect adapter: it returns an observation, which is what the film records. Replaying this build does not re-run the model. That is the whole argument for putting generation behind a wall.

43.5 · Cell signaling

membranes · diffusion · decay

::: cell(id, kind)
  [cell:#id](kind=kind, active=false, energy=50){membrane, neighbors}
///

: @cell(a, sensor)
: @cell(b, relay)
: @cell(c, motor)
: [field](signal=0)

[field](signal=?s) --increase(10)--> (field signal=?s+10)
[field] ~~diffuse(level=?s)~~> [cell:a]

[cell:a](kind=sensor, active=false) --when(signal>5)--> (cell:a active=true)

[cell:a] ~~ligand(type=go)~~> /membrane:b
/membrane:b --bind(type=go)--> [cell:b]
[cell:b] ~~relay(type=go)~~> /membrane:c
/membrane:c --bind(type=go)--> [cell:c]
[cell:c] --contract--> (cell:c energy=energy-5)

([field] --decay(1)--> [field]).10

A membrane is a / wall. Binding is a solid transition through it. Nothing about this domain required new syntax — which is the claim the example exists to test.

43.6 · Proof-carrying patch

parallel lanes · verified acceptance · seal

: [issue:#217](failure="stale imported schedule")
: [repo:#trvm](revision=#a91)

[issue:#217] & [repo:#trvm] --> /model
/model ==observed(patch=#p44)==> [patch:#p44]

|| {
  [patch:#p44] --compile--> [report:compile]
  [patch:#p44] --property_tests--> [report:laws]
  [patch:#p44] --replay_battery--> [report:replay]
  [patch:#p44] --diff_scope--> [report:scope]
}

[patch:#p44]
  & [report:compile] & [report:laws] & [report:replay] & [report:scope]
  ==verified(policy=trvm.patch.v1)==>
[film:#accepted-p44]

[film:#accepted-p44] ==merge_candidate==> //review
[reviewer] ~~approve~~> //review
//review ==seal==> ///release-candidate

A machine proposes; four independent checks run in parallel lanes; a named policy decides; a human approval is an ordinary async message into a commit boundary. The acceptance is an artifact with a hash, so "who accepted this and on what evidence" is a query, not an archaeology project.

43.7 · Versioned telemetry ingest

expression notation · behavior block · backpressure · migration · test

module ingest@#b12

type Reading = { sensor: SensorId, value: Fixed<16>, at: Period }

enum IngestNote { out_of_range(sensor: SensorId), duplicate(sensor: SensorId) }

fn validate(r: Reading) -> Result<Reading, IngestNote>
  uses {} {
  match r.value {
    v when v >= 0 and v <= 5000 => ok(r)
    _                           => err(out_of_range(r.sensor))
  }
}

actor ingest(shard: ShardId) {
  state (stored=0, noted=0)

  ports {
    readings: Mailbox<Reading, capacity=1024, overflow=backpressure>,
    archive: Port<FactWrite>
  }

  on ~~Reading(?r)~~> {
    match try validate(?r) {
      ok(?v)  => [self] --store(?v)--> {facts + ?v}
      err(?e) => [self] --note(?e)--> (state noted=state.noted+1)
    }
  }

  on ~~unknown(#msg)~~> {
    [self] --forward(#msg)--> /adapter.v1v2     ; unknown messages are outcomes, not faults
  }
}

; demand-driven collection
[ingest:shard] ~~demand(32)~~> [sensor:*]
[sensor:*] ~~Reading(batch)~~> [ingest:shard]

; upgrading a live shard
(state: Ingest@#a91) ==migrate(policy=ingest.v1v2, by=#m7)==> (state: Ingest@#b12)

test "validation rejects out of range" {
  validate({sensor=s1, value=9000, at=0}) = err(out_of_range(s1))
}

check schedules=10_000

This is the example that shows both surfaces at once. The behavior block and the drawn routes below it are the same language; by conformance they must canonicalize to identical bytes. The migration line upgrades live state without touching the module hash that produced it.

44 · Exclusions Permanent

The following are permanently excluded. They are not future work. Each would break a stated principle, and the reason is given rather than assumed.

ExcludedPrinciple it would break
textual or unhygienic macros; raw token-array metaprogramminghomoiconic over the canonical graph, not the text
operator overloading of punctuationthe punctuation rule
implicit conversionsthe surface must say what it means
nullabsence is Option
class inheritance; deep hierarchies; implicit virtual dispatch; actors inheriting actor implementationstraits are the abstraction mechanism
hidden exceptionsthe error ladder
shared mutable global state; shared mutable pointerssingle-owner cells; conflicts must dissolve
nondeterministic map or set iterationreplay exactness
ambient filesystem / network / model / clock access — at run time or compile timeLaw 3; effects cross named walls
arbitrary compile-time I/O; compile-time host introspectionLaw 6; the no-build property depends on it
scheduler-dependent mailbox selection; scheduler arrival order as datadeterminism
semantics derived from canvas coordinateslayout is presentation; identity is content
a new punctuation symbol for every conventional featurea small coherent alphabet is preferred to a large one

45 · Reserved and implementation-defined Proposed

Deliberately left open. A conforming implementation may specify these; the language does not fix them. Naming them is how the draft avoids pretending to have answers it does not have.

Open questionStatus
Byzantine trust modes. The CRDT laws guarantee convergence among honest replicasthe trust and evidence policy for dishonest peers is implementation-defined (trust= on merge routes)
Distributed termination detection. The detector that distinguishes true termination from temporary quiescenceimplementation-defined
Scoring functions. A scored branch must record its scores as facts so replay is exactthe scoring function itself is implementation-defined
Four-stroke delimiters::::, ////reserved, undefined; the depth ladder caps at three
Backtick blocks for raw or foreign-code embeddingreserved; admitted only behind an authority wall with a pinned toolchain and artifact hash
Explicit spatial predicates#[inside=/district.north], #[near=[station], distance<20m]reserved. Spatial layout is presentation only; geometry becomes semantic only when explicitly declared

46 · Conformance Core

An implementation conforms if it satisfies the following observable properties. They double as a test matrix — which is the point: a conformance claim you cannot execute is a marketing claim.

PropertyTest
Formatting invariancerandom spaces and line lengths retain the semantic hash
Two-surface isomorphisma behavior block and its equivalent drawn routes produce identical canonical bytes
Scheduler invariancerandomized worker ordering retains the committed film
Replay exactnessa live run and its replay share all observables
Build invariancethe same inputs produce an identical build film and identical hashes on different hosts
Memoized-build soundnessreusing (transform#, input#) cache entries yields outputs identical to a cold build
Fragment hygienecopied fragments do not alias local identities; rebuilds reproduce derived identities
Merge lawsfact union is commutative, associative, idempotent; the pinned join instance is identical across replicas of one program hash
Boundary safetyundeclared effects cannot cross walls; capability-capturing values cannot travel
Ranking stabilityoN. is unaffected by arrival order
Numeric portabilityworld-profile simulations produce identical films across supported targets; extern pure artifacts honor their declared determinism class
Restore correctnessimported stale work prevents false termination
Resource safetyloops, mailboxes, streams and expansion respect budgets and bounds
Portabilitythe same sealed film executes identically across runtimes

Today's toolchain demonstrably satisfies formatting invariance and the identity half of build invariance; those are what the browser conformance corpus asserts on every change. The other twelve are properties of a runtime this repository documents but does not contain.


The language becomes real when one small set of reading laws — shape says what a thing is, texture says how it moves, colons introduce and slashes bound, marks for architecture and words for computation — accurately expresses a bike race, a supervised server, a replicated document, a generated world, a biological pathway, a proof-carrying patch and a versioned service, and all of them compile to one inspectable canonical graph whose build, execution and history are equally replayable.