docs/graph-closure.md
Graph closure, and the identity structural law
Measurement. Two results: closure classification of every representation graph, and an empirical test of whether identity obeys different structural laws from state.
1. Closure — facts
A fact's representation graph is closed when every carrier of it is observable, open when any carrier is not. Closure is a property of the whole set, not of any carrier.
| Fact | Carriers | Observable | Closure |
|---|---|---|---|
activity |
Line.opacity, emissiveIntensity |
2/2 | closed |
status |
wireframe |
1/1 | closed |
identity |
Line.color, emissive, color, span.style |
3/4 | open |
health |
transparent, opacity, span.style |
2/3 | open |
blocked |
beacon element, span.style |
1/2 | open |
flow |
Line.opacity, animation |
1/2 | open |
Two of six closed. Note what closure reveals that carrier-counting hid:
activity has two carriers and is closed; blocked has two and is open.
Dispersion and completeness are genuinely independent, exactly as expected.
2. Closure — carriers (the dual)
A carrier is trustworthy when every meaning it encodes is observable.
| Carrier | Meanings | Observable | Trustworthy |
|---|---|---|---|
material.color |
kind, identity | yes | yes |
material.opacity / .transparent |
health, kind | yes | yes |
material.emissiveIntensity |
activity, kind | yes | yes |
material.wireframe |
kind, status | yes | yes |
Line.opacity |
activity, flow | flow also animated | partial |
span.style |
health, identity, blocked | none | no |
One carrier is wholly untrustworthy, and it is the one carrying three facts.
Every open fact above is open because of span.style, except flow, which is
open because of animation. Closure therefore has exactly two causes in this
renderer, and both are known.
3. The identity structural law — measured
Hypothesis: identity behaves unlike state across the renderer. Tested with a 2×2 over the closed (instrumented) subset — same entity with different facts, and different entity with the same facts.
| identity carriers | state carriers | |
|---|---|---|
| same entity, facts changed | invariant | changed |
| entity changed, facts same | changed | invariant |
The result is clean in both directions. Identity and state are functions of disjoint domains:
identity = f(entity)
state = g(observations)
Neither responds to the other's input. This is a genuine structural law, and it is measured rather than asserted.
Why the overloads recur — explained by the law
Because identity is invariant under fact change, any channel identity occupies
looks static to a fact that wants to vary. An alert needs a channel that moves
when something happens; identity's channels never move for that reason. So they
present as unused capacity, and they are seized — twice now, at emissive and
at span.style.
That is a mechanism, not a coincidence, and it predicts the next occurrence:
identity's remaining carriers (Line.color, material.color) are the next
candidates for seizure by any new state fact needing a colour.
Does this justify extending the ontology?
No — and the reason is that the vocabulary already expresses it.
A projection's domain is a first-class field in the projection ledger.
identity→hue has domain identity; facts→world has domain facts. The law
measured above is precisely the statement that these two projections have
disjoint domains — which the ledger already records, for reasons that had
nothing to do with rendering.
So the phenomenon is faithfully representable. Under the standing rule, this is not explanatory pressure. Identity is structurally different and already described.
Correction accepted: the earlier claim that identity "has no value of its own" was too strong. Identity has value; it has no operational magnitude. It partitions every other fact — which is what makes it structurally different without requiring new architecture.
4. What closure changes about the earlier results
- "Identity has the worst locality" stands, but closure is the sharper statement: identity is open, and openness is what makes a fact unverifiable, not dispersion.
- "The separation succeeded" is now fully explained. It moved a fact between two carriers of an open graph. No measurement over an open graph can establish that a separation worked, because the destination may be the unobservable carrier — and here it was.
activityis the only multi-carrier closed fact, making it the sole worked example of what a verified encoding looks like in this renderer.
5. Sequence
Recorded as the governing order:
- Complete measurement coverage —
Html, animation, remaining carriers. - Close every representation graph.
- Minimize decision loss.
- Simplify semantic locality.
- Only then, Legend amendments.
Step 1 now has a precise definition rather than a general aspiration: two
causes of openness exist — span.style and animation. Closing both closes
every open graph in the renderer.
The Legend must ratify a language whose semantics have already stabilised, not be the mechanism by which they stabilise. Nothing in this document is a proposal.