---
fragment_id: oscar.map.versioning.002
domain: MAP
rule: Layer versioning rules
source: app/src/map/MapView.tsx, app/src/data/models/MapLayer.ts
bound_to_modules:
  - oscar.map
status: SHIPPED
version: .002
---

# Layer versioning (per rules.md §10)

Every `MapLayer` record carries a `version: number` field, starting at `1` on creation. Significant edits increment the version by 1. Non-significant edits do not change the version.

## Significant edits (version bumps)

- **Vertex move** — committed vertex drag per oscar.map.vertex-editing.002
- **Delete** — layer removed from store; no version bump (the record ceases to exist; audit trail preserved in `layer_versions`)
- **Rename** — name field updated
- **Kind change** — point / line / polygon change
- **Linked-tree change** — link, unlink, re-link

Each significant edit also writes a `LayerVersion` ledger record (see below).

## Non-significant edits (no version bump)

- Note text edit
- Photo attach / detach / reorder
- Selection (no edit)
- Filter (no edit)
- Map pan / zoom (no edit)

## LayerVersion ledger

Every version bump writes a record to the `layer_versions` IDB store:

```
LayerVersion {
  layerId: string
  version: number           // the new version after the bump
  timestamp: ISO8601
  operation: 'vertex-move' | 'delete' | 'rename' | 'kind-change' | 'linked-tree-change'
  actor: 'operator'         // v0.2.0 hard-coded; future cloud-sync replaces with profile id
}
```

## Backward compatibility

Existing v0.1.0 layer records without a `version` field are read as `version: 1`. The first significant edit on such a record bumps it to `version: 2` and writes the corresponding `LayerVersion` record. This means v0.1.0 records appear as "version 1" in the side panel, which is correct — they were at the canonical initial version.

## Display

The side panel shows a small `v{n}` badge near the top (see oscar.map.side-panel.002). Documents record the version they were generated against (see oscar.map.documents-view.002 + rules.md §11).