---
id: ADR-CRM-ENT-004
title: Changes Use the Version Read
product_area: crm
module: entities
revision: 1
status: proposed
design_intent: confirmed
source_sha:
  services-crm: 7ea48a414c42eade10d60753b8bcc323b1dd726f
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
decision: >-
  Field-changing updates require the client’s read version and reject missing or
  stale versions with modifier attribution; current-version contact and
  organization no-op saves preserve capture and stamps; classification no-op
  behavior differs, and deletion remains unversioned.
constrains:
  - DOM-CRM-ENT-033
  - SVC-CRM-ENT-entities
  - SVC-CRM-ENT-configuration-types
  - WF-CRM-ENT-002
  - STATE-CRM-ENT-001
  - STATE-CRM-ENT-002
  - STATE-CRM-ENT-007
  - SCR-CRM-ENT-004
origin: >-
  D-05 and D-35 (Andrew, 2026-10-19); M1-D6; services-platform
  docs/standards/record-write-contracts.md W1 and W2
alternatives:
  - option: Accept whichever write arrives last.
    why_not: >-
      The recorded version decision rejects silent overwrite of another person’s
      or the system’s work.
  - option: Accept a stale request whose resulting content is unchanged.
    why_not: >-
      Platform requires that retry behavior, but the approved Entities rule and
      current code reject stale versions. The existing open question must
      resolve the conflict.
consequences:
  - >-
    System maintenance can make an open editor stale and identifies the system
    in conflict attribution.
  - >-
    A repeated committed edit can report a stale-version conflict despite
    unchanged content.
  - >-
    Catalogue records have versions; settings begin at zero, and catalogue no-op
    behavior needs alignment.
evidence:
  - >-
    services-crm at 7ea48a41: docs/entities-api.md (Versions and no-op saves);
    modules/entities/services/persistence/contacts.ts (updateContact);
    lib/api/write-preconditions.ts
  - >-
    services-platform at ad3f6a65: docs/standards/record-write-contracts.md W1,
    W2
---
# Changes Use the Version Read

## Context

Optimistic concurrency preserves the basis on which a person edited a record. Dedicated update and archive operations validate that basis under record locks; deletion has no version argument.

## Decision

Field-changing updates require the client’s read version and reject missing or stale versions with modifier attribution; current-version contact and organization no-op saves preserve capture and stamps; classification no-op behavior differs, and deletion remains unversioned.

## Alternatives Considered

Accept whichever write arrives last. The recorded version decision rejects silent overwrite of another person’s or the system’s work.

Accept a stale request whose resulting content is unchanged. Platform requires that retry behavior, but the approved Entities rule and current code reject stale versions. The existing open question must resolve the conflict.

## Consequences

Contact and organization no-op detection runs after the version check. The approved planning and Platform standard differ on stale unchanged requests. Classification writes also lack uniform no-op preservation, so this decision must not be read as proof of universal enforcement.

System maintenance can make an open editor stale and identifies the system in conflict attribution. A repeated committed edit can report a stale-version conflict despite unchanged content. Catalogue records have versions; settings begin at zero, and catalogue no-op behavior needs alignment.
