ReadonlylayerReadonlylocalReadonlyserverThe row's server identity, when the record had one.
ReadonlykindThe operation that met the conflict.
ReadonlyentryThe queue entry it came from — the handle a report needs to name the capture.
ReadonlydetectedWhen the conflict was settled, milliseconds since epoch.
ReadonlybaseThe marker the local edit was based on — the filter that matched nothing.
ReadonlyserverThe marker the crushed row carried. null unless readOutcome is "read".
ReadonlyserverThe crushed row, as the server returned it. null unless readOutcome is "read".
⚠️ Stored as the server's own shape, not as a GeoJSON Feature: converting it would
mean guessing which column is the geometry on a row nothing will ever re-send. What is
kept is what was there.
ReadonlyreadWhat the re-read could establish — see ConflictReadOutcome.
ReadonlysettledHow it was settled.
A single value today, and declared rather than implied for the reason ConflictPolicy gives: the record must say which policy produced it, or a later policy would make every archived record ambiguous.
Optional ReadonlyprofileThe profile the conflicting write was queued under — its OutboxEntry.profileId. The store is shared by every profile of the origin: a conflict is listed, and purged, under its own profile. Absent on a conflict archived before 3.18.0, or for a write queued before then, which every profile reads, as before.
One settled conflict — keyed
[layerId, localId], one record per entity.🛑 WHY THE STORE EXISTS.
lastWriteWinsis the policy, and it was made OBSERVABLE on 17/09/2026 — detected, logged, then settled by an unfiltered re-send. What no part of the cycle did was LOOK at the row it was about to crush. After an overwritten update the server still holds a row; after an overwritten delete it holds nothing, and neither did anything else: that is the only irrecoverable loss of the whole write cycle.🛑 THE KEY IS THE BOUND, and it is derived rather than invented.
db/eviction.tsknows a single store name (layers), so this store is UNREACHABLE by eviction exactly asfeaturesis — nothing will ever purge it. Keying by entity caps it at one row per entity, so its size is bounded by the layer it describes. A journal would have needed a ceiling, and a ceiling here would be a number posted in the noise band — something this repository has paid for twice. The cost is stated rather than hidden: an entity that conflicts twice keeps only the most recently crushed version.⚠️ It carries no zone index, and no index at all (decision of 17/09/2026). Reading a layer costs 0,45 to 0,8 s at 30 000 entities from disk, which does not justify one, and the composite key already yields per-layer traversal by key range —
IDBKeyRange.bound([layerId], [layerId, []]), the reasoningdb/features.tscarries in full.⚠️ The server's row is EVIDENCE, never a source. Nothing writes it back into
features: doing so would overwrite what the operator captured, which is the sixth defect closed on 17/09/2026 reappearing in a new place.