docs/semantic-quantity-audit.md
Semantic quantity audit — verifier coverage
Standing invariant, in its strongest form:
Any semantic quantity reconstructed independently is expected to diverge over time. Agreement between duplicated derivations is evidence of coincidence, not correctness.
The audit question changed accordingly. Not "do these projections agree?" but "can they ever disagree?" If the semantics are implemented twice, the answer is yes and the class is Accidental, whatever the current tests say.
The duplicated surface
Two parallel representations of an agent exist:
| fields | |
|---|---|
WorldAgent (world/types.ts) |
14 |
CityNode (hq/view.ts) |
17 |
Eight semantic quantities are carried by both and computed independently:
accent · blocked · code · focus · id · queue · status ·
load/workload
The last is invisible to a field-name comparison — it is the same quantity under two names, which is how it survived earlier audits.
Verifier coverage — the structural blind spot
export function verifyWorld(world: World, facts: WorldFacts): Violation[]
The signature receives World and WorldFacts. It receives no HqState, no
CityView, no CityNode.
| Implementations of the 8 quantities | 16 (two roots) |
| Observed by the constitutional verifier | 8 |
| Coverage of the second root | 0% |
This is not a missing rule. No rule the verifier could be given would help, because the second implementation is not in its input type. Every constitutional guarantee in this system holds over one of two derivation roots.
Two divergences already live
Both found by this audit, both invisible to every verifier and every test.
1. Normalisation — Article IV.4
| Projection | Formula | |
|---|---|---|
World.load |
min(1, log1p(w)/log1p(peak)) |
repaired |
CityNode.workload |
min(1, w/peak) |
original |
Beyond peak ≈ 600, an agent with real work renders at 0.0100 in CityMap (reads as empty) while reading 0.3041 in the World. The repair landed in one root; the other kept the defect the repair was written to remove.
2. Identity of absence — Article I.5
| Site | Reserved agent's accent |
|---|---|
build.ts:438 |
UNDEVELOPED_HUE |
structure.ts:161 |
UNDEVELOPED_HUE |
page.tsx:82 |
hueFor(a.agent.id) — unconditional |
CityMap has no reserved branch. A reserved agent — a role nobody holds — renders in the SVG city with a normal entity hue, i.e. as a staffed agent. Article I.5 requires absence to read as absence.
hue-provenance.test.ts asserts UNDEVELOPED_HUE and passes, because it
observes the World. The violation is in the projection the test cannot see.
What this establishes
The classification predicted this sequence, and the repository now contains two completed instances of it:
- a quantity is reconstructed independently;
- one implementation is repaired;
- the other silently diverges;
- no verifier observes the break, because verification is bound to one root.
Agreement is a snapshot. Structural coherence is a property. Every quantity above is currently in the Accidental class, and two have already left agreement behind.
The objective, restated
Not matching formulas. One semantic computation, many projections.
The repair for CityMap is therefore not "copy the logarithm" and not "add a reserved branch." Each of those restores agreement while leaving the class Accidental — two implementations that match again until the next one-sided repair, which the verifier will again fail to see.
The repair is to eliminate the second implementation: CityNode should carry
values read from World.agents[], not recomputed from HqState. That converts
eight quantities from Accidental to Structural in one change, and brings the
second root inside the verifier's reach for the first time.
Recorded, not applied. It touches page.tsx, hq/view.ts and removes
derivations in hq/state.ts. Finding 3.2 remains untouched per standing
instruction.