OpenSentience.orgUnboxed PatternsChapter 11 of 32 · Composition

UP-011 · Composition · WITNESSED CHECKABLE RUNNABLE EXECUTED STAGED

Projection, Not Duplication

Every view of an artifact is derived from it by a declared, recomputable function.

Every view of a semantic artifact is derived from it by a declared, recomputable projection; a receiver recomputes the claims on the wire rather than trusting flags or prose.
Standing
WITNESSED CHECKABLE RUNNABLE EXECUTED STAGED PUBLISHED REPRODUCED
Last checked
2026-09-11 15:26:17 UTC
Source
graphonomous/v2/test/projection_v1.test.mjs @ 61adec2d5484 · bytes 957b52a20a403381…
Limit
States that derived views may not become rival authorities. Nothing here checks that any view in the tree is derived rather than maintained; the WRL world for this chapter is sealed, and a sealed topology is not an authority audit.
Next rung
live_local — a check on this page that walks a projection back to its source and refuses one that has drifted. The WRL world for this chapter seals, and a sealed topology is not an authority audit.
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

A view is a projection, not a second copy that pretends to be authoritative. Two viewers agree because each derived the view from the artifact, not because they trusted each other. A copy that was edited since it was taken is a replica, and a receiver that cannot derive it refuses it.

Technical register

WRL §D8.18/§D8.19: deriveRuntimeProjection makes the V1→V2 downgrade in-band, and the projection on the wire carries only claims a receiver recomputes. Graphonomous projection-v1: eleven acceptance laws over schema_closure_id + projection_contract_id, so a projection's certificate closes over the schemas it actually used rather than every schema in the checkout — growing the vocabulary no longer re-mints frozen projections (the v0 defect D-068 fixed). 15 tests, five golden vectors.

Problem

v0 hashed every schema file in the checkout into every projection's identity. Adding a schema re-minted the certificates of frozen projections whose records had not moved. Identity that closes over the wrong set is duplication wearing a hash.

Solution

Declare the projection function and its contract. Derive the schema closure from what the projection actually consumed. Put the closure id and contract id in the certificate. Have every consumer recompute the projection from the artifact and refuse anything it cannot derive.

Real-world analogy

Two accountants each recompute the quarter from the ledger. A third brings last month's spreadsheet with edits. The first two agree; the third is not a view of anything.

Structure — on the surface

compute surfaceprojection · derived, recomputableartifactartifactview Aview Aview Bview BPderived from the artifactAn artifact, the projection derived from it, and two views that recompute rather than copy.

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 11 of 32 — the fragment _patterns/wrl/chain/projection-not-duplication.wrl, sealed alone by wrl.js

; PROJECTION, NOT DUPLICATION — pj_view_a and pj_view_b are both derived from pj_artifact through
; SocketControl; neither is a copy. pj_in is the entry, fed by the grant router.
[relay:pj_in]{sig_in, sig_out}
[spinner:pj_artifact](w=16, n=8, rotor=quarter_turn_z){sig_in, socket}
[orb:pj_view_a]{pose}
[orb:pj_view_b]{pose}

[pj_in] --sig--> [pj_artifact]
[pj_artifact] --socket--> {[pj_view_a], [pj_view_b]}

Its test bench _patterns/wrl/chain/projection-not-duplication.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:pj_bench](every 1){sig_out}
[pj_bench] --sig--> [pj_in]

module + bench seal to → sem-7e9b02088e689d96680477ca165ad6e8f6ae575d47913b7fbf1f7c189a58648b

Reduced by the reference reducer (pure Python); parity with the other reducer not run for this world.

compute surfacesigsigsocketsocketpj_artifact · Spinnerpj_artifactspinnerpj_bench · Pulserpj_benchpulserpj_in · Relaypj_inrelaypj_view_a · Orbpj_view_aorbpj_view_b · Orbpj_view_borbThis chapter's world alone, before epoch 1. Reduced by TRVM's forge in 53.244s; the forge's id equals the seal above.
The Film, epoch by epoch (4)

epoch 1 · sha256:fb2c4975b7bdcba090926926df7373ad28b422f6646764bb3abc8a99431e238a

FILM v0.7
t=1
spinner:pj_artifact:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=00b5,0000,0000,00b5,socket=pj_view_a,config=fixed
orb:pj_view_a:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=pj_artifact,fault=0
orb:pj_view_b:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=pj_artifact,fault=0
pulser:pj_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1
relay:pj_in:cur_out=0,next_out=1
wire:w__pj_bench__pj_in:cur=1,nxt=1
wire:w__pj_in__pj_artifact: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:4d885cf88f3378fffe3454d8d9b1be3cfb4e4d773a58a927c5e7bf5d0e257750

FILM v0.7
t=2
spinner:pj_artifact:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=00b5,0000,0000,00b5,socket=pj_view_a,config=fixed
orb:pj_view_a:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=pj_artifact,fault=0
orb:pj_view_b:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0100,0000,0000,0000,controller=pj_artifact,fault=0
pulser:pj_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1
relay:pj_in:cur_out=1,next_out=1
wire:w__pj_bench__pj_in:cur=1,nxt=1
wire:w__pj_in__pj_artifact: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:e37c4d4b30741d10519a387c22f571c197c0a8c2c903535f44d15cfb5243b4e2

FILM v0.7
t=3
spinner:pj_artifact:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=00b5,0000,0000,00b5,socket=pj_view_a,config=fixed
orb:pj_view_a:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=00b5,0000,0000,00b5,controller=pj_artifact,fault=0
orb:pj_view_b:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=00b5,0000,0000,00b5,controller=pj_artifact,fault=0
pulser:pj_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1
relay:pj_in:cur_out=1,next_out=1
wire:w__pj_bench__pj_in:cur=1,nxt=1
wire:w__pj_in__pj_artifact: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:ce88a51cbe43b6b1500a2ab79acdc0c2ddba06d2957fc45abb2e07eaf04b077a

FILM v0.7
t=4
spinner:pj_artifact:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,rotor=00b5,0000,0000,00b5,socket=pj_view_a,config=fixed
orb:pj_view_a:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0000,0000,0000,00ff,controller=pj_artifact,fault=0
orb:pj_view_b:policy=forge_motor_widemac_tz_sat_v1,quat4,w=16,n=8,pose=0000,0000,0000,00ff,controller=pj_artifact,fault=0
pulser:pj_bench:mode=periodic,p=1,phase=0,armed=0,done=0,nf=1
relay:pj_in:cur_out=1,next_out=1
wire:w__pj_bench__pj_in:cur=1,nxt=1
wire:w__pj_in__pj_artifact: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 10 chapters before it

The chain through this chapter — every earlier fragment, this one, and the links — seals to sem-42597d2b8f062a222caf638d66eb8745b939bed8ce14afebf4276dec55d3c9fb: 34 objects, 33 edges (was 30 / 29; every earlier object and edge is still present — checked, or the build refuses).

Links only the chain carries

[cc_grant] --sig--> [pj_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.

shapeisand so
a clock; the only source of signalEvery signal on the board starts at one of these. Nothing else can make one.
a pass-through, so signal can travelOne arrives, any number leave — a relay that fans out is the board's router.
a sink; signal arrives and stopsIt latches what reached it and passes nothing on. A door is where a path ends.
rotation: takes signal, drives a poseThe only object on the board that holds a value a claim can rewrite — and only if its config says configurable.
the thing that gets movedIt 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 FilmIt counts what the run admitted, and turns red on a Rejected outcome.
SignalWiresignal: a sig_out to a sig_inLegal from a Pulser or Relay, into a Relay, Door or Spinner. This is how the board moves.
SocketControlcontrol: a socket to a poseLegal 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.

compute surfaceI · The LocusII · Compositional_locus · Spinneral_locusspinneral_view · Orbal_vieworbal_world · Pulseral_worldpulsercb_fixed · Spinnercb_fixedspinnercb_gate · Doorcb_gatedoorcb_in · Relaycb_inrelaycb_view · Orbcb_vieworbcc_carrier · Doorcc_carrierdoorcc_grant · Relaycc_grantrelayct_in · Relayct_inrelayct_locus · Spinnerct_locusspinnerct_view · Orbct_vieworbis_id · Orbis_idorbis_in · Relayis_inrelayis_seal · Spinneris_sealspinnerlc_core · Relaylc_corerelaylc_locus · Spinnerlc_locusspinnerlc_machine · Relaylc_machinerelaylc_thread · Relaylc_threadrelaylc_view · Orblc_vieworbpj_artifact · Spinnerpj_artifactspinnerpj_in · Relaypj_inrelaypj_view_a · Orbpj_view_aorbpj_view_b · Orbpj_view_borbrb_record · Orbrb_recordorbrj_join · Doorrj_joindoorrj_r · Relayrj_rrelaysm_in · Relaysm_inrelaysm_inside · Spinnersm_insidespinnersm_outside_a · Orbsm_outside_aorbsm_outside_b · Orbsm_outside_borbso_in · Relayso_inrelayso_pose · Orbso_poseorbso_rotor · Spinnerso_rotorspinner

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

Why v1 exists — the test file's own header graphonomous/v2/test/projection_v1.test.mjs:3

 * The subject is one coordinate. v0's `schema_set_id` hashes EVERY schema file in the checkout, keyed on basename, so
 * growing the v1 vocabulary re-minted the certificates of frozen v0 projections whose records had not moved. v1
 * replaces it with `schema_closure_id` + `projection_contract_id`: the REQUIRED closure the verifier derives from the
 * projection's own adapter_run records through a trusted local contract (lib/closure.mjs, contracts/projection.v1.json).

The projection on the wire (WRL relation-v2.js) WRL/relation-v2.js:2363

export async function deriveRuntimeProjection(artifact,
                                              claimedSemanticId = null) {
  const v2 = artifact && typeof artifact === "object" &&
    Object.prototype.hasOwnProperty.call(
      V2_RELATION_SOURCE_FAMILIES, artifact.ir_version);

Forces

Derivation costs recomputation on every read, which is exactly the cost a replica avoids — and the reason replicas drift. The closure a projection's identity depends on must be neither too wide (every schema) nor too narrow (none); it is derived from the adapter runs that produced it, through a trusted contract.

Applicability

Read models, dashboards, exports, search indexes, semantic graphs over a corpus — anything that presents an artifact from another angle.

Transformations

Preserving
  • adding a projection
  • re-deriving after the artifact changes
  • downgrading a projection in-band so the receiver sees the downgrade as a claim
Refusing
  • a copy presented as the artifact (Replica Theater)
  • an identity that closes over inputs the projection did not use
  • a flag that says 'this is current' instead of a recomputation

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

Views can multiply without becoming sources of truth. The methodological consequence is law 4 of projection-v1, measured in both of its readings, with the second found not to hold — the test says so, and D-072 records it.

Failure mode it answers

Replica Theater — Calling independent mutable copies 'the same thing'. Paid for at: CLAUDE.md: the served box-and-box copy is a MANUAL COPY and nothing syncs it

Witness

Source identity: graphonomous/v2/test/projection_v1.test.mjs · shape side-effect · evidence kind constructive_witness · rung in_tree (graphonomous/v2/handoff/STATUS.md:113 — TESTED, 15 tests over eleven laws)

Execution identity: 2026-09-11T15:26:17.256Z on PX13 · bytes 957b52a20a403381… · repo HEAD 61adec2d5484

Not staged on this site: the page cannot run this witness. It runs from the command line: node test/projection_v1.test.mjs in graphonomous/v2.

Counterexample

graphonomous/v2/test/projection_v1.test.mjs — marker does not hold, expected REFUSED.

A marker, not a resolved law. The build checked that this string is present in the file. A string being present proves the file mentions it, not that the file refuses anything — this record cites no law id that could be resolved against a suite index. It is the weaker of the two forms this catalog uses.

What to take away

  1. from the animationTwo views agreed by derivation; the replica was refused because nothing could derive it.
  2. from the syntaxA projection's identity closes over the schemas it consumed — schema_closure_id — not the checkout.
  3. from the literatureCQRS read models and materialized views are the ancestry; the contribution is the closure id in the certificate.
  4. from the witness15 tests over eleven laws ran today with a receipt; law 4's second reading fails and the test says so.

Prior art — and what is not claimed

workrelationwhat it shareswhere it differs
CQRS read models; materialized viewsantecedentmany views derived from one authorityCQRS permits a read model to drift and reconcile; this pattern refuses a second authority outright
Unison's hash-addressed definitionsclose analoguederivations cannot disagree about what they derive fromUnison gets it from naming; this gets it from a projection rule

Novelty not claimed. Derived views are ubiquitous. The narrow claim is about authority, not about caching.

Realizations in the tree

Relations with other patterns

Refusable Divergence WITNESSED · Shared Observable WITNESSED