Skip to content
← Documentation

docs/semantic-locality.md


Semantic locality — the representation graph and its dual

CARRIER COUNTS ARE A FLOOR — see closure-verification.md. The parser under-counts: it reported status with one carrier; the render shows three. Carriers computed into variables rather than written as inline attribute expressions are invisible to it. Closure verdicts survive; the counts do not.

Measurement. Observable object: source-tree. Every JSX attribute in WorldScene.tsx whose expression references a semantic fact, indexed both ways.


Instrument limits, stated first

Three, because two of them affect the numbers below:

  1. Attributes only. The walker enumerates JSX attributes. Conditionally rendered elements{agent.blocked > 0 && <beacon/>} — are invisible to it. So blocked's beacon carrier is missing from the graph.
  2. kind over-matched. The pattern caught link.kind and placement.kind as well as building.kind, inflating its carrier count to 8. Treat that row as unreliable.
  3. span.style is one attribute containing many properties. It counts as a single carrier here while carrying three facts inside one object literal.

The representation graph — fact → carriers

Fact Carriers Where
identity (accent) 4 Line.color, material.emissive, material.color, span.style
health 3 material.transparent, material.opacity, span.style
activity 2 Line.opacity, material.emissiveIntensity
blocked 1 (+ beacon, unseen) span.style
status 1 material.wireframe
flow 1 Line.opacity
kind unreliable over-matched

The dual — carrier → facts

Only carriers holding more than one fact:

Carrier Facts Purposes
span.style health + identity + blocked explanation + identity + decision
material.color kind + identity state + identity
material.opacity / .transparent health + kind explanation + state
material.emissiveIntensity activity + kind state + state
material.wireframe kind + status state + state
Line.opacity activity + flow state + state

Semantic conservation — the migration is real and it concentrated

The separation experiment removed the identity/alert overload from material.emissive. The dual shows where it went:

span.style now carries three facts — health, identity and blocked — making it the most overloaded carrier in the renderer. It is also the only carrier in that list with zero measurement coverage.

So the answer to did ambiguity decrease or relocate? is measured, and it is relocate — and concentrate. Total semantic load on the renderer did not fall; it moved from an instrumented carrier to an uninstrumented one, where it joined two facts already present.

That is a general property of this rendering language, not an accident of one fix: carriers are shared by default, so removing a fact from one carrier does not delete the encoding, it re-homes it. Nothing in the language prevents the destination from being a channel nobody can observe.


The proposed invariant, and its current status

A separation is verified only when every carrier of the affected fact is instrumented. Otherwise it is provisional.

Applying it:

Fact Carriers Instrumented Status
identity 4 3 provisional
health 3 2 provisional
blocked 2 (1 unseen by this probe) 1 provisional
activity 2 2 verified
status 1 1 verified
flow 1 0 (animation) provisional

Three of the six most important facts are provisional, and the identity/alert separation is among them. The earlier report of success was premature by this invariant, which is exactly what the invariant is for.


Semantic locality — the metric

Locality = how many carriers must be checked, across how many observable objects, before a fact can be said to be correctly represented.

Fact Carriers Observable objects Coverage Locality
status 1 1 (scene-graph) 1/1 high
activity 2 1 (scene-graph) 2/2 high
flow 1 1 (animation) 0/1 low — unmeasurable
blocked 2 2 (scene-graph, Html) 1/2 low
health 3 2 (scene-graph, Html) 2/3 low
identity 4 2 3/4 lowest

Identity has the worst locality in the system. Four carriers across two observable objects, one of which cannot be measured — and it is precisely the fact that keeps being seized by alerts.

Locality exposes what the other metrics missed: nothing about identity is technically wrong, and it is still the fact least likely to stay correct, because verifying it requires checking four places and one of them cannot be checked at all.


Is identity a fourth purpose?

Measured evidence that it behaves differently from state:

  1. It is the most widely distributed fact — 4 carriers, more than any other reliably-measured fact. State facts occupy 1–3.
  2. It is the only fact appearing on every entity type — buildings, agents and links each carry accent.
  3. It is the only fact that is repeatedly displaced. emissive seized by health; span.style seized by blocked. No state fact was ever displaced by another fact in the measured history.
  4. It is the only fact with no value of its ownhueFor(id) is a function of identity, carrying no organizational content. Health, activity and capacity all encode magnitudes or categories; identity encodes only which entity this is.

Point 4 is the structural distinction: identity is not a property of an entity; it is the thing that makes properties belong to an entity. That is a different role from state, and it explains the recurring overload — identity has no natural magnitude, so any channel it occupies looks free to a fact that does.

Not adopted. This is evidence, not a decision, and the standing rule requires implementation to demonstrate that the current vocabulary cannot express the phenomenon. It currently can: identity is classifiable as state with a note. The question is whether that classification keeps producing the same defect.


What this does not establish

  • Whether relocation harmed perception. span.style may be a better carrier for alerts than emissive was. Unmeasured, and requires observers.
  • Whether four carriers for identity is redundancy (robust) or diffusion (fragile). Both are consistent with the measurement.
  • The kind row, which the instrument over-matched.