docs/reference-mechanisms.md
The reference is invisible
src/lib/projection/rule.ts, src/lib/world/changeset.ts
The working model
Observed quantity
↓
Reference ← the vulnerability sits here
↓
Projection
↓
Visual channel
Retracted hypothesis: "subject-scoped channels communicate subject change cleanly." Falsified across four repositories (change-channels); referenced only as a retraction.
Standing law: a channel's truthfulness depends on the stability of its reference, not on the subject it appears to describe. Height and brightness were never subject-scoped — they are world-normalised and merely looked clean because their divisor happened not to move.
The reference is never drawn. Nothing on screen says what 1.0 means, so its movement is indistinguishable from the subject's.
The two ways a reference lies
| failure | definition |
|---|---|
| spurious | the magnitude did not change; the mark moved |
| invisible | the magnitude changed; the mark did not move |
The strongest example of the second is structural: the largest subject can never appear to grow, because it defines 1.0. Quadrupling the biggest file in the repository is invisible.
Characterising the class
Five mechanisms, plus capped/uncapped variants, over the same HEIGHT_RULE
pipeline (normalize → sqrt → scale 26 → offset 2 → floor 0.4). Reporting
floor 0.28 = 1% of output range. peak blind counts revisions where the largest
subject's own magnitude changed and its mark did not move.
| repo | mechanism | invisible% | spurious% | peak blind | out-of-range |
|---|---|---|---|---|---|
| enterprise-xi | observed-peak | 26.0 | 0.0 | — | 0.0% |
| enterprise-xi | declared-ceiling | 32.0 | 0.0 | — | 0.0% |
| enterprise-xi | baseline-revision | 26.0 | 0.0 | — | 0.0% |
| enterprise-xi | rolling-avg(3) | 26.0 | 0.0 | — | 0.0% |
| enterprise-xi | percentile-95 | 16.0 | 0.4 | — | 4.7% |
| stable-peak | observed-peak | 20.0 | 0.0 | — | 0.0% |
| stable-peak | percentile-95 | 6.7 | 60.3 | — | 3.0% |
| moving-peak | observed-peak | 70.0 | 34.2 | 10/10 | 0.0% |
| moving-peak | declared-ceiling | 5.0 | 0.0 | 0/10 | 2.7% |
| moving-peak | declared-ceiling+cap | 45.0 | 0.0 | 8/10 | 0.0% |
| moving-peak | baseline-revision | 5.0 | 0.0 | 0/10 | 3.0% |
| moving-peak | baseline-revision+cap | 55.0 | 0.0 | 10/10 | 0.0% |
| moving-peak | rolling-avg(3) | 55.0 | 46.8 | 5/10 | 3.0% |
| moving-peak | percentile-95 | 5.0 | 40.0 | 0/10 | 3.0% |
| monorepo | observed-peak | 50.0 | 40.3 | 3/4 | 0.0% |
| monorepo | baseline-revision | 15.0 | 0.0 | 1/4 | 11.2% |
| monorepo | percentile-95 | 30.0 | 51.0 | 0/4 | 5.2% |
| rotating-max | observed-peak | 0.0 | 31.9 | — | 0.0% |
| rotating-max | baseline-revision | 0.0 | 0.0 | — | 16.1% |
| rotating-max | percentile-95 | 0.0 | 41.3 | — | 6.1% |
Three findings, and they separate cleanly
1. Spurious change is caused by a moving reference — nothing else.
Every fixed reference (declared-ceiling, baseline-revision) scores 0.0%
spurious in every scenario, including the ones built to break normalisation.
Every moving reference (observed-peak, rolling-avg, percentile) scores
22–60%.
2. Invisible change is caused by the cap, not by the reference. The same
reference, capped and uncapped, on moving-peak:
| invisible | peak blind | |
|---|---|---|
baseline-revision |
5.0% | 0/10 |
baseline-revision+cap |
55.0% | 10/10 |
observed-peak carries an implicit cap — the ratio cannot exceed 1 because
the divisor is the maximum — which is exactly why its blind spot is total
(10/10) and cannot be tuned away.
3. Robust statistics are not safer here — they are worse. percentile-95
moves and clips: 60.3% spurious even in the stable-peak control, where
observed-peak scores 0.0%. The maximum of that repository is stable; its 95th
percentile is not. Choosing a "more robust" reference imported instability that
the naive one did not have.
The trilemma
Three properties. Any mechanism gets two:
| bounded output | no blind spot | no spurious change | |
|---|---|---|---|
| observed-peak | ✅ | ❌ | ❌ |
| declared-ceiling +cap | ✅ | ❌ | ✅ |
| declared-ceiling uncapped | ❌ | ✅ | ✅ |
| baseline-revision uncapped | ❌ | ✅ | ✅ |
| rolling / percentile | varies | ❌ | ❌ |
A bounded channel cannot represent a value beyond its bound. That is not an implementation defect — a box 28 units tall cannot depict "taller than the tallest box". The blind spot is the price of the bound, and the only question is whether it is declared.
observed-peak is the single worst cell in the table: it is the only mechanism
that pays both costs, because its divisor moves and it clips. It is what
ships today.
What this does not license
The repair is not yet made, per the standing discipline. Choosing
declared-ceiling requires declaring a ceiling, and no observation supports any
particular value — it is a stipulation, and on rotating-max an uncapped
baseline puts 16.1% of subjects past the end of the channel. Trading a
measured defect for an undeclared stipulation is not obviously progress, and
which trade is right depends on evidence not yet gathered.
What is established: the mechanism must be named in the display. A reference that moves invisibly is the only reason a truthful pipeline produced 90%+ false firings.
The stronger result: the explanation outlived the visualization
Across every adversarial repository and every channel:
| result | |
|---|---|
| channel false-firing rate | 0% → 95% |
| false firings the model correctly disclaimed | 100% |
| real changes the model mislabelled | 0 |
The channels collapsed. The attribution did not move.
The stable semantic object is not the visualization. It is the explanation.
A channel is a projection through a reference, and the reference is a free
parameter that no observation fixes — so a channel's truthfulness is contingent
on a choice made elsewhere. The attribution is not: it compares a retained
magnitude against itself, and there is nothing in it to destabilise. This is why
ChangeSet is the canonical temporal model and the renderer consumes it rather
than two worlds.
It also reframes what the product is. The city is a view on an explanation, and it is the weaker half. When the two disagree, the explanation is right.
Instrument correction, recorded
An earlier version of this study declared box height as unit 0–1 with floor
0.01, while HEIGHT_RULE actually emits 0.4–28. The floor was therefore 26×
more sensitive than the stated 1% convention, which produced a false 0% miss
rate for height on Enterprise XI. Corrected to 0.4–28 / 0.28, the same
measurement gives:
| before (bad floor) | after | |
|---|---|---|
| height FP% (enterprise-xi) | 0.0 | 0.0 |
| height FN% (enterprise-xi) | 0.0 | 37.5 |
| height FP% (moving-peak) | 96.9 | 94.6 |
The falsification is unaffected — 0% → 94.6% either way. But the "clean" case was never clean: over a third of real byte changes were already invisible, and the declared unit was hiding it. A unit that does not match its values is a threshold hidden inside a label.