docs/label-attachment.md
Labels measured — recoverable, and the fixture refused the real question
Fourth result under renderer-as-laboratory. Labels are the first genuinely
semantic UI layer: the text carries identity, and WorldScene.tsx:352 puts
failing on the label colour. Unlike the camera, a label can make a claim.
tests/label-attachment.test.ts.
The task
Given a label on screen, can a viewer attach it to the right building?
Two failure modes, both computed in closed form and neither needing a label
width — which matters, because distanceFactor scaling is a drei internal and
approximating it would put the result at the mercy of a guess:
- Misattachment — the label's anchor falls inside a nearer, different building's silhouette, so a viewer reads the name as belonging to that one.
- Orphaning —
occlude={false}(:348) draws every label through geometry, so a label for a hidden building floats with no referent.
Result
18 buildings · 2 occluded · 18 labels projected
misattached at the default vantage: 0
orphaned (referent hidden, drawn): 2/18 (11.1%)
108 poses · worst single pose: 2 misattached
labels misattached at EVERY pose: 0
Misattachment is real and recoverable. Up to 2 labels sit on the wrong building at some poses; none does so at every pose. Same verdict shape as the camera — a navigation cost, not a claim failure.
Orphaning is not a defect on its own. A floating name may be the honest way to say "something is here you cannot see". It becomes a false claim only if it lands on another building, which the misattachment test covers separately.
| Element | Semantic ownership | Perceptual effect |
|---|---|---|
| label text | derived — identity | preserves — 0 misattached at every pose |
| label colour | derived — failing |
unmeasured; shares ALERT with the beacon |
| label anchor height | arbitrary (h + 4.5) |
preserves |
occlude={false} |
arbitrary | preserves — orphans 11.1%, none misread |
The finding the fixture produced instead
The density question — do labels collide when the estate is crowded? — could not be asked. Scaling the input from 9 to 80 repositories:
repos=9 buildings=18 misattached=0
repos=20 buildings=18 misattached=0
repos=40 buildings=18 misattached=0
repos=80 buildings=18 misattached=0
The building count does not respond to the input at all. Tracing it:
deriveStructure iterates PRODUCTS (src/lib/hq/estate.ts:82) and AGENTS
(src/lib/hq/roster.ts:67) — fixed constant tables. The repos argument only
supplies stats for products that already exist, matched by
repos.find((r) => r.slug === product.repo).
The world does not construct itself from the repository. It is a fixed estate of predefined products and agents, onto which repository statistics are attached.
That is a much larger finding than the label result, and it bears directly on the stated milestone — "point Cognithamus at a real repository, watch the world construct itself". Today, pointing it at a different repository changes the heights and colours of a predetermined city. It does not change what buildings exist.
The repository adapter built in
repository-reconstruction.md does produce
subjects from arbitrary input — 117 of them from an unprepared repo — but
nothing connects those subjects to deriveStructure. The two halves exist and
do not meet.
This was not derived. The fixture rule forced it: can the fixture express the phenomenon? It could not, and the reason it could not was the finding.
Standing
| Measurable defect exposed? | yes — the estate is constant, not derived from input |
| Measurable improvement? | none made; measurement first |
| Freedom removed without evidence? | no |
| Fixture rule applied? | yes, and it produced the result |
What is still not established
- Label-to-label overlap is unmeasured. Two names on top of each other is a
distinct failure from misattachment, and it needs a label width — i.e. drei's
distanceFactorsemantics, or a rendered surface. - Label colour is unmeasured. It carries
failingand sharesALERTwith the beacon; whether two carriers of one fact is sufficiency or competition is the beacon investigation's question. - Density remains untested, and it is the condition under which labels are most likely to fail. It cannot be tested until the estate responds to input.
- 108 poses at 20° steps; a misattachment could hide between samples.
219 → 223 tests, tsc clean.