Identity Is a Seal
An artifact's identity is the hash of its canonical form, the same on every host.
- Standing
- WITNESSED CHECKABLE RUNNABLE EXECUTED STAGED PUBLISHED REPRODUCED
- Last checked
- 2026-09-11 15:25:45 UTC
- Source
WRL/test/conformance.mjs@32160fec77a1· bytese1f1e313eefe0001…- Limit
- wrl.js seals a topology to an id and the forge agrees with it. That establishes that the seal is a function of the graph and not of the text — it does not establish that the graph captures the meaning anyone cares about.
- Next rung
live_local— the seal computed in a browser on this site from source the reader supplies, rather than at build time. The build already seals 33 worlds; nothing yet exposes sealWorld to the page.
Why this page says WITNESSED — the derivation, not the word
- ✓ a witness is named
- ✓ its evidence kind is one the ledger already uses (constructive_witness)
- ✓ the witness path resolves in this tree
- ✓ its rung is in_tree or above (in_tree)
- ✓ a run is recorded for these exact bytes
- ✓ no claim is cited that could be REFUTED
- ✓ a counterexample is shipped (required once WITNESSED)
- ✗ not staged on this site, so it cannot run from the page
WITNESSED requires every line above to hold. The label is computed from them by build.mjs and cannot be typed into the registry — the build refuses a record that carries it.
Intent
Identity is computed, not assigned. A WRL world is parsed, canonicalized and sealed to a SemanticArtifactID; every host derives the same id from the same canonical form, and a world with a different future has a different id. Nothing about the id names a file, a row or a machine.
Technical register
WRL Core 0.1.2: the starter world seals to sem-67e954cf… on every host; a second, larger pinned fixture is what the batteries assert against; both are checked on every change by test/conformance.mjs (924 checks passing at the last run). 'birth key' appears once in WRL/HANDOFF_D8_PATH_B.md; the invariant's wording is the book's.
Problem
Systems assign identity by location — an autoincrement, a path, a host-qualified name — and then have to defend the assignment with locks, registries and migrations. Two copies with the same content get different names; one thing edited in place keeps its name while its meaning changes.
Solution
Define the canonical form first. Hash it. Make the hash the only identity the artifact has; let names be labels that point at hashes. Pin fixtures whose ids must never change, and fail the build if one does.
Real-world analogy
An ISBN is assigned; a checksum is computed. Two warehouses can disagree about an ISBN. They cannot disagree about a checksum without one of them being wrong about the bytes.
Structure — on the surface
An illustration on a compute surface: loci above, carriers below. Press Play or Step; the takeaways collect as you go. Nothing here is evidence — the witness section is.
The chapter in WRL — and the chain so far
Chapter 4 of 32 — the fragment _patterns/wrl/chain/identity-is-a-seal.wrl, sealed alone by wrl.js
; IDENTITY IS A SEAL — the named rotor `identity` is the unit; the world's id is the hash of this text's
; canonical form. is_in is the entry; in the chain it is fed by the machine router of chapter 3.
[relay:is_in]{sig_in, sig_out}
[spinner:is_seal](w=16, n=8, rotor=identity){sig_in, socket}
[orb:is_id]{pose}
[is_in] --sig--> [is_seal]
[is_seal] --socket--> [is_id]Its test bench _patterns/wrl/chain/identity-is-a-seal.bench.wrl — drives the entry for this chapter's own film; never part of the chain
; TEST BENCH — drives this chapter's entry alone; the chain replaces it with a wire from an earlier chapter
[pulser:is_bench](every 1){sig_out}
[is_bench] --sig--> [is_in]module + bench seal to → sem-0738b04e54f4544857dcf62b4508f1bf70e9b80ad494e4a3b60efff620faa15d
Run inputs — a ScenarioV1, the forge's own document, bound to this world's id and never part of it (D3) · ScenarioDigest scen-886cdaf007dc64a8089… (the run inputs' own identity, computed by the forge)
No claims: the world runs on its clocks alone for 7 epochs.
Idle by design in this world alone: is_id — the rotor is `identity`, the unit: the pose does not move, by construction — that is what a unit is.
Reduced by the native reducer (ic32); the reference reducer reproduces every epoch's film hash (46.346s).
The Film, epoch by epoch (7)
epoch 1 · sha256:48a3b5e253a74b74b4da5378376489dd197e70cee5d09e766675b96967f35f01
FILM v0.7 t=1 spinner:is_seal:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=0100,0000,0000,0000,socket=is_id,config=fixed orb:is_id:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=is_seal,fault=0 pulser:is_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1 relay:is_in:cur_out=0,next_out=1 wire:w__is_bench__is_in:cur=1,nxt=1 wire:w__is_in__is_seal:cur=0,nxt=0 admit:policy=admit_candidate_min_firstreceipt_v1,fact_capacity_fault=0,receipt_capacity_fault=0,capacity_fault=0
epoch 2 · sha256:26db7a897099a92d816cbc10b7626d48883de2a01e2ed6abcae58a134d7fbe3c
FILM v0.7 t=2 spinner:is_seal:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=0100,0000,0000,0000,socket=is_id,config=fixed orb:is_id:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=is_seal,fault=0 pulser:is_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1 relay:is_in:cur_out=1,next_out=1 wire:w__is_bench__is_in:cur=1,nxt=1 wire:w__is_in__is_seal:cur=0,nxt=1 admit:policy=admit_candidate_min_firstreceipt_v1,fact_capacity_fault=0,receipt_capacity_fault=0,capacity_fault=0
epoch 3 · sha256:f0719cd9cc217796205855d72b3da19de189623dc8047a8dacad256bbf4c1177
FILM v0.7 t=3 spinner:is_seal:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=0100,0000,0000,0000,socket=is_id,config=fixed orb:is_id:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=is_seal,fault=0 pulser:is_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1 relay:is_in:cur_out=1,next_out=1 wire:w__is_bench__is_in:cur=1,nxt=1 wire:w__is_in__is_seal:cur=1,nxt=1 admit:policy=admit_candidate_min_firstreceipt_v1,fact_capacity_fault=0,receipt_capacity_fault=0,capacity_fault=0
epoch 4 · sha256:025b973a4b6c11174579702f3bcdf278d38db3960f6a6361575cfa0a70a1399e
FILM v0.7 t=4 spinner:is_seal:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=0100,0000,0000,0000,socket=is_id,config=fixed orb:is_id:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=is_seal,fault=0 pulser:is_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1 relay:is_in:cur_out=1,next_out=1 wire:w__is_bench__is_in:cur=1,nxt=1 wire:w__is_in__is_seal:cur=1,nxt=1 admit:policy=admit_candidate_min_firstreceipt_v1,fact_capacity_fault=0,receipt_capacity_fault=0,capacity_fault=0
epoch 5 · sha256:b00c365a9021323c164c34a76b519cd45e5040b9589a58417167aa9bbffd5399
FILM v0.7 t=5 spinner:is_seal:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=0100,0000,0000,0000,socket=is_id,config=fixed orb:is_id:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=is_seal,fault=0 pulser:is_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1 relay:is_in:cur_out=1,next_out=1 wire:w__is_bench__is_in:cur=1,nxt=1 wire:w__is_in__is_seal:cur=1,nxt=1 admit:policy=admit_candidate_min_firstreceipt_v1,fact_capacity_fault=0,receipt_capacity_fault=0,capacity_fault=0
epoch 6 · sha256:81c0d9ae25106895f22b3861370c24e8fe4e8d8021538581a664851cabb0c83d
FILM v0.7 t=6 spinner:is_seal:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=0100,0000,0000,0000,socket=is_id,config=fixed orb:is_id:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=is_seal,fault=0 pulser:is_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1 relay:is_in:cur_out=1,next_out=1 wire:w__is_bench__is_in:cur=1,nxt=1 wire:w__is_in__is_seal:cur=1,nxt=1 admit:policy=admit_candidate_min_firstreceipt_v1,fact_capacity_fault=0,receipt_capacity_fault=0,capacity_fault=0
epoch 7 · sha256:9a54f7aff6f81937ca1a76e31a44b8c7096deb3fbc191504e696834bec23ad98
FILM v0.7 t=7 spinner:is_seal:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=0100,0000,0000,0000,socket=is_id,config=fixed orb:is_id:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=is_seal,fault=0 pulser:is_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1 relay:is_in:cur_out=1,next_out=1 wire:w__is_bench__is_in:cur=1,nxt=1 wire:w__is_in__is_seal:cur=1,nxt=1 admit:policy=admit_candidate_min_firstreceipt_v1,fact_capacity_fault=0,receipt_capacity_fault=0,capacity_fault=0
Composes with the 3 chapters before it
The chain through this chapter — every earlier fragment, this one, and the links — seals to sem-9e5f93837672264d3a73524eafb75842490f8b1d75637bd4f485441256731148: 12 objects, 11 edges (was 9 / 8; every earlier object and edge is still present — checked, or the build refuses).
Links only the chain carries
[lc_machine] --sig--> [is_in]
How to read this board
Five kinds of object, two kinds of wire, and one band per Part of the book. Signal flows left to right: it starts at a clock, travels through relays, and ends at a door — or turns a spinner, which drives an orb. Nothing below is the book's own vocabulary; each line is quoted from where the definition lives.
| shape | is | and so |
|---|---|---|
| a clock; the only source of signal | Every signal on the board starts at one of these. Nothing else can make one. | |
| a pass-through, so signal can travel | One arrives, any number leave — a relay that fans out is the board's router. | |
| a sink; signal arrives and stops | It latches what reached it and passes nothing on. A door is where a path ends. | |
| rotation: takes signal, drives a pose | The only object on the board that holds a value a claim can rewrite — and only if its config says configurable. | |
| the thing that gets moved | It is driven, never driving: an orb is what you watch to see whether anything happened. | |
| not a WRL role — the book's own drawing of the receipts in the epoch's Film | It counts what the run admitted, and turns red on a Rejected outcome. | |
| SignalWire | signal: a sig_out to a sig_in | Legal from a Pulser or Relay, into a Relay, Door or Spinner. This is how the board moves. |
| SocketControl | control: a socket to a pose | Legal only from a Spinner into an Orb. At most one may land on any input port — fan-in is a typed refusal. |
Hover any object for what it is, which chapter put it there, and every field of its line in that epoch's Film — split into what it is doing now and how it was built. Click to pin the readout, then click a wired name to follow the signal. The field definitions come from TRVM/forge/film.py (the emitter), TRVM/forge/forge_state.py (nf, derived from the decoded counter and never from t), TRVM/forge/lower_e2a.py (the commit/react law), TRVM/FORGE_SEMANTIC_IR_v1_MEASURE.md §1.3; the shapes from WRL/learn.html and WRL/docs/spec/README.md. The build refuses if a Film emits a field this key does not explain.
The board so far: one band per Part, signal flowing left to right; relays that fan out are routers, doors are switches, pulsers are clock domains. Hover an object — or click the board and walk it with the arrow keys — for its role, its Part and what it is wired to. This board is the chain’s sealed shape; no Film drives it, so it has no state to report, and the whole board in the conclusion is where every object’s state is read epoch by epoch. Wheel zooms · drag pans · double-click fits.
Syntax — quoted from the tree at build time
The starter world that seals to sem-67e954cf… — WRL/README.md WRL/README.md:16
profile forge.world.core.v1
[pulser:p0](every 2){sig_out}
[relay:r0]{sig_in, sig_out}
[spinner:sp](w=16, n=8, rotor=quarter_turn_z, configurable){sig_in, socket}
[orb:ob]{pose}
[p0] --sig--> [r0]
[r0] --sig--> [sp]
[sp] --socket--> [ob]The sentence that names the seal WRL/README.md:31
sem-67e954cfe3115166b49388366df3f062a46572ba2baf53380f1520f4050b60ae
Forces
Hashing needs a canonical form, and canonicalization is where the real work is: two texts with the same meaning must produce the same bytes before hashing. A seal is only as trustworthy as the canonicalizer that both sides run, which is why the conformance suite and the cross-implementation vectors exist.
Applicability
Any artifact that must be the same thing on two machines: worlds, projections, certificates, packages. Not for things whose identity is legitimately their history rather than their content.
Transformations
- moving the artifact between hosts, files, rows
- renaming a label that points at a seal
- re-deriving the seal on any host
- assigning identity from a location
- editing in place under a preserved id
- trusting an id a record asserts without recomputing it (see Refusable Divergence)
A refusing transformation is not one that is discouraged: it is one that, applied, makes the invariant above false. The word is the tree's, and it is the same word the join uses.
Consequences
Identity questions become recomputable. The cost is that in-place mutation is gone: to change a world is to make a new one, and continuity between the two is a separate question (Continuity Through Reconstruction).
Failure mode it answers
Location Leak — Encoding physical placement into identity when placement is not semantic.
Witness
Source identity: WRL/test/conformance.mjs · shape side-effect · evidence kind constructive_witness · rung in_tree (STACK_COMPLETION.md:73 (890 checks then; run today))
Execution identity: 2026-09-11T15:25:45.285Z on PX13 · bytes e1f1e313eefe0001… · repo HEAD 32160fec77a1
Not staged on this site: the page cannot run this witness. It runs from the command line: node test/conformance.mjs in WRL.
Counterexample
Fixture WRL/test/projection-negative-vectors.json: 15 vectors, each expected REFUSED.
What to take away
- from the animationThree hosts, one seal; one changed relation, a different seal.
- from the syntaxNine lines of WRL are a world, and the world is its hash.
- from the literatureMerkle trees, Nix store paths and Unison's hashed definitions are the ancestry; credit them.
- from the witnessThe conformance suite pins the fixture ids; this page cannot run it yet and says so.
Prior art — and what is not claimed
| work | relation | what it shares | where it differs |
|---|---|---|---|
| Merkle (1979) | antecedent | a hash names a structure | Merkle authenticates; this uses the hash as the identity itself |
| Unison — every definition identified by the hash of its syntax tree | close analogue | content-addressed identity for program meaning, not for bytes | Unison hashes definitions; WRL seals a topology, and comments do not move the id |
| Nix store paths | realization | identity derived from inputs rather than assigned | Nix hashes build inputs; the seal here is over a semantic graph |
Novelty not claimed. Content-addressed identity is well-established prior art. The phrase 'birth key' appears once in WRL/HANDOFF_D8_PATH_B.md; the invariant's wording is the book's, and the wording is not the contribution.
Realizations in the tree
- WRL/README.md:17-27
Relations with other patterns
Meaning Is a Hash WITNESSED · Refusable Divergence WITNESSED