1# 15. A cell system is handed a `Ground`, not an application23- **Date:** 2026-08-024- **Status:** accepted5- **Where it is written down:** issue #5 §5.4, §10 decision 17;6 [analysis.md](../analysis.md) §378## Context910The pre-rewrite cell systems reach into the running application's shared client11state to find out what they are dividing: the world square, the open lens, the12world's geometry attributes. That makes each system a function of a global, so13it cannot be tested headlessly, cannot be reused by a renderer nobody has14written, and cannot divide two grounds at once.1516The analysis lane's charter is broader than cell systems — future analyses may17declare inputs beyond the volume (user markup, a live feed, a hook into a18running game) — and a lane whose founding family reads globals cannot absorb19those without being refactored first.2021## Decision2223Every system receives a **`Ground` descriptor**: exactly the implicit state the24old systems read, and nothing else.2526```ts27interface Ground {28 tileGridSize: number | null; // the volume's world square; null with no volume open29 lens: Lens | null; // null with no lens open30 world: World; // the semconv geometry keys31}32```3334`surfaceExtent(ground)` resolves it in three branches, in order: the lens's35declared surface, else the lens's raster bounds, else the whole world square.3637**Session state is deliberately not in it.** The active system, the held cell38and whether the subgrid shows arrive as arguments — `cellPlan(ground, system,39cellID)` — which is what lets one ground be divided two ways at once by two40callers who never meet.4142## Consequences4344- Every transformation is a clean function of its declared inputs, which is45 what lets the charter's future analyses register without refactoring the46 lane.47- A third system (H3, MGRS, a game's district grid) is a registry entry plus a48 green run of the conformance suite.49- The vectors record nine grounds as language-neutral JSON, and the gate50 compares JSON *text* on both sides — a lens anchored at `y = 0` produces a51 `maxY` of `-0`, which is a real double that JSON cannot carry, and loosening52 the comparison would hide a class of difference the harness exists to see.53- `analysis/semconv/geometry.ts` is the lane's own reader for the four geometry54 keys it may be asked about. It is deliberately a *reader*: it never writes a55 key and never validates a bundle. Its key constants come from56 `spec/registry.yaml`, the one machine-readable source both ends generate57 from.