# CELL CITY worker contract

CELL CITY uses six module workers to model explicitly managed local stores. The city observatory and the article instruments execute the same [worker module](../src/spu.worker.js). It is a Cell-inspired software model; it does not emulate the processor's instruction set or measure physical local-store memory.

## Ownership and byte accounting

Chunk `cid` belongs to worker `cid % workerCount`; the city uses six workers. Each owned chunk retains 32 bytes of Float32 metadata, 12 bytes of Uint32 metadata and one rejection-flag byte: 45 bytes in total. A retained building table uses 16 Float32 payload bytes and four usage/seed bytes per building.

Detailed lighting adds eight bytes of window dimensions, four band-cache bytes and one byte per modelled window per building. Floors are `clamp(round(height / floorH), 1, 80)`. Columns are `clamp(round(radius * 2.2), 4, 72)`. The supplied city's `floorH` is 3.1 metres.

`ls` is the sum of all retained typed-array payloads owned by this model: metadata, rejection flags, tables, dimensions, window states and band caches. `cacheBytes` excludes metadata; `metadataBytes` reports it separately. JavaScript objects, the runtime, code, GPU resources and transient input/output buffers are outside this accounting boundary. These counters do not report total browser memory.

Space is reserved before cache retention or detail allocation. The active entry is pinned while reserving its detail; other entries are evicted in least-recent-use order. A detail allocation that cannot fit keeps its table and uses analytic lighting. A table that cannot fit is marked as unavailable at that capacity.

## Capacity and distance rules

The default capacity is **256 KiB per worker**, including when `init.capacity` is omitted or null. One KiB is 1,024 bytes. Supported presets are 8, 16, 24, 32, 48, 64, 80, 96, 112, 128, 144, 160, 192 and 256 KiB. The observatory's controls expose 64, 128 and 256 KiB; the article can exercise the full preset range.

Capacity must be one of those integer-byte presets and accommodate the worker's metadata. Initialization rejects invalid IDs, ownership metadata, bounds and capacity. Jobs reject invalid times, camera/frustum inputs, duplicate chunk IDs and chunks owned by another worker. Table buffers must match their chunk's declared building count and contain finite coordinates and nonnegative dimensions.

A visible chunk closer than 1,050 metres can produce a lighting update when its table is retained. Detail is admitted below 560 metres. Beyond that admission threshold, a retained table produces analytic bands; its detailed arrays can remain cached. Detailed arrays are released beyond 1,150 metres, including for a chunk outside the frustum. These different admission and release conditions make retained state depend on the ordered camera trace.

Frustum visibility controls city geometry. When the worker returns no lighting offset, the renderer retains the previous GPU lighting bands. A missing lighting update is not a missing building.

Window bands depend on usage/seed data and absolute simulation time, sampled at ten ticks per second. Equal-time band values can be reproduced after table eviction and reload. Cache contents, access order and cumulative counters still depend on the preceding commands. This contract makes no cross-engine or GPU pixel-equality claim.

## Message protocol

| Command | Response and behavior |
| --- | --- |
| `init` | Validates the complete metadata input, assigns ownership, resets state and returns `ready`. An unsuccessful initialization preserves the previous initialized state. |
| `table` | Receives transferred Float32 and Uint8 buffers for one owned chunk. Successful admission has no direct response. Invalid input returns `rejected`. |
| `configure` | Changes to a supported capacity, evicts as needed and returns `configured`. A changed capacity resets the retained-byte peak to current retention; cumulative eviction and DMA counters remain. |
| `jobs` | Accepts a frame number, absolute time, 24 frustum-plane values, camera X/Z and an ordered list of unique owned chunk IDs. Returns `done`, transferable result and band buffers, misses and telemetry. |
| `inspect` | Returns `inspected` with telemetry and scalar copies of each retained entry's ID, byte count, detailed-state flag and access serial. It does not change arrays, access order, counters, rejection flags or later eviction choices. |

Each result tuple contains chunk ID, frustum visibility, floored distance and band offset. A negative offset indicates no lighting update. `fullDetail` and `analytic` count chunk jobs for that batch. `fallbacks` accumulates near-detail requests served analytically. `evict` and `dmaIn` are cumulative since initialization. `us` is elapsed worker job time, not GPU duration.

The article's small [session adapter](/assets/cell-city-lab/city-experiment.worker.js) imports the canonical module and adds request IDs and acknowledgements, including acknowledgements for table commands. It executes one logical ownership partition at a time in a reusable physical worker. The displayed results therefore do not measure the throughput of six concurrent workers.

## Article data and replay

The [article data record](/assets/cell-city-lab/city-instruments.data.json) includes the canonical source SHA-256, compact binary SHA-256, original city binary SHA-256, chunk bounds, byte invoices, fixed camera inputs and recorded results. The compact binary holds 7,770 building tables in 155,400 bytes; it contains no rendering geometry. The city has 233 chunks.

The fixed replay uses 54 camera poses, two worker batches per pose, explicit absolute times and bounds derived from actual vertices. Every capacity starts with fresh state and eagerly receives all of the selected partition's tables. Recorded points were executed in Node; browser points appear only after a reader completes a run. The record identifies the runtime, date, exact source hash and protocol. This is a sparse source replay, not a continuous tour or rendering-speed benchmark.

The no-update metric counts visible chunk-job samples with floored distance below 1,050 metres and a negative lighting offset, across both passes and before servicing that pass's misses. It is neither a unique-building count nor a count of visible defects. Initialization evictions are reported separately from the final cumulative total.

The session checks its generated source-version label against the data record. That label identifies the build; it is not a runtime cryptographic measurement of the imported code. The compact binary is SHA-256 checked before use. Regenerate and deploy the canonical worker, adapter and data record together when the worker changes.

The authored two-chunk admission fixture, fixed-time distance sequence and adjustable-height fixture are labelled separately from the processed city data. Sound is optional and starts only after an explicit gesture; its cues are driven by positive eviction deltas from completed worker batches.
