docs/identity-law.md
The identity law
Attempted falsification: does a universal fact identity exist, or does each family require its own law?
Result: a universal law exists. The four current implementations are four different wrong approximations of it — which is why it looked like four laws.
⚠️ Superseded in part by identity-axes.md. A per-axis falsification found that
validAtis not the right third component (a polling sensor over-splits by its polling rate) and that the law is not universal across state and event facts. The per-family defect measurements below stand; the universality claim does not.
Measured behaviour, per family
| Family | Current identity | Measured consequence |
|---|---|---|
condition |
(condition, subject) |
two episodes of the same condition share identity → recovery-then-recurrence is unrepresentable |
measure |
(metric, subject) |
two readings collapse → change is unrepresentable, and the survivor is order-dependent |
placement |
(subject, place) |
two locations coexist → the package is in 2 places at once |
exchange |
(moved, from, to) |
two transfers collapse to 1 fact → a repeated transfer is counted once |
placement fails in the opposite direction from the other three. It
under-collapses because it puts the value (the place) inside identity,
while the others over-collapse because they omit time. That opposition is what
made a single law look impossible.
Deriving the law from semantics
Ask what varies and what does not.
| Family | Subject-tuple | Dimension | Value that varies |
|---|---|---|---|
condition |
subject | the condition id | presence (implicit true) |
measure |
subject | the metric | number + unit |
placement |
subject | "place" | which place |
exchange |
(from, to) | what moved | quantity + unit |
Every fact has the same shape:
A fact asserts a value on a dimension, about a subject-tuple, at a time.
From which identity follows directly:
identity(fact) = (subjects, dimension, validAt)
state(fact) = the value
Two observations are the same fact iff they assert about the same subjects, on the same dimension, at the same time. Otherwise they are different facts and must coexist.
The law explains all four current defects
| Family | Deviation from the law | Effect |
|---|---|---|
condition |
omits validAt |
episodes merge |
measure |
omits validAt |
readings merge |
placement |
omits validAt and puts the value in identity |
locations coexist |
exchange |
omits validAt |
events merge |
One law, four deviations, four distinct symptoms. That is stronger evidence for universality than agreement would have been — the symptoms differ, and the law predicts each from its specific deviation.
And it answers the six questions uniformly
| Question | Answer under the law |
|---|---|
| What makes two observations the same fact? | same subjects, dimension and time |
| What makes them different? | any of the three differing |
| Is time identity or state? | identity |
| Can later observations supersede? | no — they coexist as a series; a lens selects the latest ≤ its instant |
| Can observations coexist? | yes, and must |
| Can they legitimately merge? | only at identical identity — merging evidence, never values |
Supersession turns out to be a lens concern, not a collapse concern. That is
the cleanest consequence: collapse should never choose between values, because
under the law two different values never share an identity.
The honest cost
Making time part of identity has a real price, and it should not be waved past: observer clock skew. Two connectors reporting the same condition at timestamps differing by a millisecond would produce two facts under the law, where today they merge.
The current condition behaviour tolerates skew precisely because it is
time-invariant. So the law trades a false merge (episodes) for a possible false
split (skew).
That is a canonicalization tolerance question — whether identity uses the
instant or a quantised window — and it is not answered here. Window in
core/time.ts, still unused, is the obvious candidate, which is the first time
that type has had a motivated purpose.
Classification
- Ontology: survived again.
validAtis already on every fact; the law uses only existing fields. No new primitive. - Canonicalization: falsified.
factIdentityasserts a law that does not hold, in four different ways.
Not implemented. The rule is that a canonicalization failure must not be
misclassified as an ontology failure — and equally, deriving a law is not the
same as changing one. The skew question should be settled before factIdentity
moves.