---
id: STATE-CRM-ENT-002
title: Organization record lifecycle
object: DOM-CRM-ENT-002
product_area: crm
module: entities
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
states:
  - name: new
    meaning: No organization is stored under the requested identity.
    entry_conditions: There is no live organization at this identity.
    allowed_actions:
      - Submit a valid create request.
    terminal: false
    reversible: false
    provenance: observed
    source: >-
      services-crm at 7ea48a41: modules/entities/db/organizations.table.ts;
      services/persistence/organizations.ts (createOrganization, archive,
      deleteOrganization, deleteOrganizationRow); docs/archive.md.
    experience: The create form is still a draft with no saved organization number.
  - name: active
    meaning: The organization has its normal active status.
    entry_conditions: A create defaults to active or an authorized save records it.
    allowed_actions:
      - Read
      - update under ordinary guards
      - archive
      - delete if dependencies permit.
    terminal: false
    reversible: true
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#with
      a type that holds it to rules: not in compliance, every rule with a
      minimum violated (it has no contact yet)
    experience: The body can appear in ordinary discovery.
  - name: inactive
    meaning: >-
      The stored organization is inactive but retains hierarchy, affiliations
      and revisions.
    entry_conditions: A versioned save records inactive business status.
    allowed_actions:
      - Read
      - edit if otherwise available
      - restore active status
      - archive.
    terminal: false
    reversible: true
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/integration/db/organizations.table.integration.spec.js#refuses
      a status outside the closed list by organizations_status_check
    experience: The identity and its hierarchy remain readable.
  - name: duplicate
    meaning: Duplicate status identifies a record awaiting data-quality treatment.
    entry_conditions: A save records duplicate status.
    allowed_actions:
      - Read
      - correct under ordinary guards
      - use separately authorized Data Quality work.
    terminal: false
    reversible: true
    provenance: observed
    source: >-
      services-crm:modules/entities/db/organizations.table.ts:ORGANIZATION_STATUSES
    experience: The body remains a live CRM identity pending further treatment.
  - name: archived
    meaning: >-
      Archive independently preserves status and relationships while blocking
      ordinary organization editing and default selection.
    entry_conditions: The archive action records the overlay without changing stored status.
    allowed_actions:
      - Direct read
      - unarchive
      - inspect authorized history
      - request guarded deletion.
    terminal: false
    reversible: true
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the ended affiliation naming the organization's id, with its name and its
      archive instant
    experience: >-
      Badges identify retained closed context, including archived ancestors or
      affiliation labels.
  - name: deleted
    meaning: >-
      The live organization and owned data are removed, with history and its
      spent number retained.
    entry_conditions: The guarded delete transaction succeeds.
    allowed_actions:
      - Inspect retained revisions under history authority.
    terminal: true
    reversible: false
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
      409 to a delete while the contact is affiliated with it
    experience: The live organization is absent; ordinary restore is unavailable.
transitions:
  - from: new
    to: active
    trigger: Create an organization using active or default status.
    guard: >-
      Create permission, valid name and workspace references; a blocked
      duplicate requires authorized override and reason.
    side_effects:
      - allocate organization number
      - attach logo
      - evaluate initial compliance without a notice
      - publish attention only when enabled
      - capture event and revision
    who: An authorized creator or integration
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#with
      a type that holds it to rules: not in compliance, every rule with a
      minimum violated (it has no contact yet)
    audit_event: >-
      A changed organization transaction produces its aggregate revision and
      event. Archive metadata records the actor and optional explanation;
      ordinary deletion retains its historical record.
  - from: active
    to: inactive
    trigger: Save inactive status.
    guard: >-
      Organization update permission and matching version; no archive or full
      lock.
    side_effects:
      - persist the new status
    who: An authorized API editor
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/db/organizations.table.integration.spec.js#refuses
      a status outside the closed list by organizations_status_check
    audit_event: >-
      A changed organization transaction produces its aggregate revision and
      event. Archive metadata records the actor and optional explanation;
      ordinary deletion retains its historical record.
  - from: inactive
    to: active
    trigger: Save active status.
    guard: Pass ordinary organization save authorization and concurrency checks.
    side_effects:
      - persist active status
    who: An authorized API editor
    provenance: observed
    source: >-
      services-crm:modules/entities/db/organizations.table.ts:ORGANIZATION_STATUSES
    audit_event: >-
      A changed organization transaction produces its aggregate revision and
      event. Archive metadata records the actor and optional explanation;
      ordinary deletion retains its historical record.
  - from: active
    to: duplicate
    trigger: Mark the organization duplicate in a save.
    guard: Use the same guards as other status edits.
    side_effects:
      - persist duplicate status
    who: An authorized editor or data-quality process
    provenance: observed
    source: >-
      services-crm:modules/entities/db/organizations.table.ts:ORGANIZATION_STATUSES
    audit_event: >-
      A changed organization transaction produces its aggregate revision and
      event. Archive metadata records the actor and optional explanation;
      ordinary deletion retains its historical record.
  - from: active
    to: archived
    trigger: Archive the organization in its current status.
    guard: >-
      Archive permission, matching version and no full lock; optional reason is
      at most 500 characters.
    side_effects:
      - store archive metadata
      - advance version and capture revision
      - preserve affiliations with archive information
      - exclude default selection
    who: An authorized archive operator
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the ended affiliation naming the organization's id, with its name and its
      archive instant
    audit_event: >-
      A changed organization transaction produces its aggregate revision and
      event. Archive metadata records the actor and optional explanation;
      ordinary deletion retains its historical record.
  - from: archived
    to: active
    trigger: Unarchive without changing the underlying status.
    guard: 'Archive permission, current version and no full lock.'
    side_effects:
      - clear archive stamps
      - keep unarchive reason
      - advance version and capture revision
    who: An authorized archive operator
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the trimmed reason as unarchive_reason
    audit_event: >-
      A changed organization transaction produces its aggregate revision and
      event. Archive metadata records the actor and optional explanation;
      ordinary deletion retains its historical record.
  - from: active
    to: deleted
    trigger: Delete the organization directly or through a bulk job.
    guard: >-
      Delete permission, no deletion-blocking owner or element lock, no
      protection, no child organizations and no affiliation references.
    side_effects:
      - remove contact points and custom values
      - resolve enabled attention
      - detach logo
      - apply enabled owner-deletion policy
      - capture deletion history
    who: An authorized delete operator or bulk job
    provenance: test
    source: >-
      services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
      409 to a delete while the contact is affiliated with it
    audit_event: >-
      A changed organization transaction produces its aggregate revision and
      event. Archive metadata records the actor and optional explanation;
      ordinary deletion retains its historical record.
  - from: archived
    to: deleted
    trigger: Delete while the organization is archived.
    guard: Archive does not relax the normal delete checks.
    side_effects:
      - perform ordinary organization deletion
    who: An authorized delete operator
    provenance: documented
    source: 'services-crm:docs/archive.md#While archived'
    audit_event: >-
      A changed organization transaction produces its aggregate revision and
      event. Archive metadata records the actor and optional explanation;
      ordinary deletion retains its historical record.
invalid:
  - from: active
    to: deleted
    why: >-
      Any child organization or affiliation blocks deletion, including
      relationships already ended or not yet started.
    response: >-
      The service returns a dependency refusal when children or any affiliation
      reference the organization. Past and future ties still preserve their
      organization context.
  - from: archived
    to: inactive
    why: Archive blocks general saves until an unarchive action clears it.
    response: >-
      Archive refuses general correction with the archived-record response. An
      authorized unarchive action is the supported way to reopen ordinary
      editing.
  - from: deleted
    to: active
    why: >-
      The API has no restore action. A fresh create can reuse an unoccupied
      identity but receives another number; retained revisions keep their
      subject identity.
    response: >-
      No deleted-to-active restore exists. Live reads return not-found; a fresh
      create is a different creation with another allocated number.
concurrency: >-
  Organization saves compare the read version under the row lock. Compliance
  uses that row lock plus a transaction advisory lock and can make an open
  editor stale. Hierarchy constraints reject a competing move that would
  complete a cycle. Deletion is unversioned.
invariants:
  - INV-DOM-CRM-ENT-002-05
  - INV-DOM-CRM-ENT-002-10
  - INV-DOM-CRM-ENT-033-01
  - INV-DOM-CRM-ENT-033-12
evidence:
  - >-
    services-crm at 7ea48a41: modules/entities/db/organizations.table.ts;
    services/persistence/organizations.ts (createOrganization, archive,
    deleteOrganization, deleteOrganizationRow); docs/archive.md.
  - >-
    react-console at da630758:
    components/console/organization/organization-sections.tsx (no organization
    editor on a live console).
automatic: []
ai_may_recommend: false
ai_may_execute: false
permissions_by_state:
  - state: new
    action: create
    permission: crm.organizations.create
  - state: active
    action: read
    permission: crm.organizations.read
  - state: active
    action: update
    permission: crm.organizations.update
  - state: active
    action: archive
    permission: crm.organizations.archive
  - state: active
    action: delete
    permission: crm.organizations.delete
  - state: active
    action: history
    permission: crm.organizations.history
  - state: inactive
    action: read
    permission: crm.organizations.read
  - state: inactive
    action: update
    permission: crm.organizations.update
  - state: inactive
    action: archive
    permission: crm.organizations.archive
  - state: inactive
    action: delete
    permission: crm.organizations.delete
  - state: inactive
    action: history
    permission: crm.organizations.history
  - state: duplicate
    action: read
    permission: crm.organizations.read
  - state: duplicate
    action: update
    permission: crm.organizations.update
  - state: duplicate
    action: archive
    permission: crm.organizations.archive
  - state: duplicate
    action: delete
    permission: crm.organizations.delete
  - state: duplicate
    action: history
    permission: crm.organizations.history
  - state: archived
    action: read
    permission: crm.organizations.read
  - state: archived
    action: archive
    permission: crm.organizations.archive
  - state: archived
    action: delete
    permission: crm.organizations.delete
  - state: archived
    action: history
    permission: crm.organizations.history
  - state: deleted
    action: history
    permission: crm.organizations.history
narrative:
  status: verified
  review: NARRATIVE-REVIEW-2026-10-23
narrative_sources:
  - section: Purpose
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#with
      a type that holds it to rules: not in compliance, every rule with a
      minimum violated (it has no contact yet);
      services-crm:modules/entities/tests/integration/db/organizations.table.integration.spec.js#refuses
      a status outside the closed list by organizations_status_check;
      services-crm:modules/entities/db/organizations.table.ts:ORGANIZATION_STATUSES;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the ended affiliation naming the organization's id, with its name and its
      archive instant;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the trimmed reason as unarchive_reason;
      services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
      409 to a delete while the contact is affiliated with it;
      services-crm:docs/archive.md#While archived
  - section: Ownership and Authority
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#with
      a type that holds it to rules: not in compliance, every rule with a
      minimum violated (it has no contact yet);
      services-crm:modules/entities/tests/integration/db/organizations.table.integration.spec.js#refuses
      a status outside the closed list by organizations_status_check;
      services-crm:modules/entities/db/organizations.table.ts:ORGANIZATION_STATUSES;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the ended affiliation naming the organization's id, with its name and its
      archive instant;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the trimmed reason as unarchive_reason;
      services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
      409 to a delete while the contact is affiliated with it;
      services-crm:docs/archive.md#While archived
  - section: The Lifecycle
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#with
      a type that holds it to rules: not in compliance, every rule with a
      minimum violated (it has no contact yet);
      services-crm:modules/entities/tests/integration/db/organizations.table.integration.spec.js#refuses
      a status outside the closed list by organizations_status_check;
      services-crm:modules/entities/db/organizations.table.ts:ORGANIZATION_STATUSES;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the ended affiliation naming the organization's id, with its name and its
      archive instant;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the trimmed reason as unarchive_reason;
      services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
      409 to a delete while the contact is affiliated with it;
      services-crm:docs/archive.md#While archived
  - section: States
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#with
      a type that holds it to rules: not in compliance, every rule with a
      minimum violated (it has no contact yet);
      services-crm:modules/entities/tests/integration/db/organizations.table.integration.spec.js#refuses
      a status outside the closed list by organizations_status_check;
      services-crm:modules/entities/db/organizations.table.ts:ORGANIZATION_STATUSES;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the ended affiliation naming the organization's id, with its name and its
      archive instant;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the trimmed reason as unarchive_reason;
      services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
      409 to a delete while the contact is affiliated with it;
      services-crm:docs/archive.md#While archived
  - section: Transitions Explained
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#with
      a type that holds it to rules: not in compliance, every rule with a
      minimum violated (it has no contact yet);
      services-crm:modules/entities/tests/integration/db/organizations.table.integration.spec.js#refuses
      a status outside the closed list by organizations_status_check;
      services-crm:modules/entities/db/organizations.table.ts:ORGANIZATION_STATUSES;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the ended affiliation naming the organization's id, with its name and its
      archive instant;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the trimmed reason as unarchive_reason;
      services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
      409 to a delete while the contact is affiliated with it;
      services-crm:docs/archive.md#While archived
  - section: What Cannot Happen
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#with
      a type that holds it to rules: not in compliance, every rule with a
      minimum violated (it has no contact yet);
      services-crm:modules/entities/tests/integration/db/organizations.table.integration.spec.js#refuses
      a status outside the closed list by organizations_status_check;
      services-crm:modules/entities/db/organizations.table.ts:ORGANIZATION_STATUSES;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the ended affiliation naming the organization's id, with its name and its
      archive instant;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the trimmed reason as unarchive_reason;
      services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
      409 to a delete while the contact is affiliated with it;
      services-crm:docs/archive.md#While archived
  - section: Concurrency and Timing
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#with
      a type that holds it to rules: not in compliance, every rule with a
      minimum violated (it has no contact yet);
      services-crm:modules/entities/tests/integration/db/organizations.table.integration.spec.js#refuses
      a status outside the closed list by organizations_status_check;
      services-crm:modules/entities/db/organizations.table.ts:ORGANIZATION_STATUSES;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the ended affiliation naming the organization's id, with its name and its
      archive instant;
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the trimmed reason as unarchive_reason;
      services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
      409 to a delete while the contact is affiliated with it;
      services-crm:docs/archive.md#While archived
  - section: Permissions by State
    provenance: documented
    source: 'rhythm-v2-docs:specs/crm/AUTHORIZATION.md#Role Entitlement Matrix'
  - section: Purpose
    provenance: inferred
    source: >-
      services-crm at 7ea48a41: modules/entities/db/organizations.table.ts;
      services/persistence/organizations.ts (createOrganization, archive,
      deleteOrganization, deleteOrganizationRow); docs/archive.md.
    note: >-
      The explicitly labeled rationale interprets the separation of state
      dimensions and the existing trigger and guard rows.
  - section: Invariants
    provenance: inferred
    source: >-
      INV-DOM-CRM-ENT-002-05; INV-DOM-CRM-ENT-002-10; INV-DOM-CRM-ENT-033-01;
      INV-DOM-CRM-ENT-033-12
    note: >-
      Protection explanations interpret the unchanged domain-object invariants;
      no lifecycle policy is added.
  - section: Invariants
    provenance: inferred
    source: "services-crm:modules/entities/services/persistence/contacts.ts; services-crm:modules/entities/services/persistence/organizations.ts; services-crm:modules/entities/services/organizations/compliance/organization-compliance.ts; services-crm:modules/entities/services/persistence/record-locks.ts"
    note: "The rationale interprets this artifact’s sourced invariants and linked capability rules; it does not claim a recorded product decision."
---

# Organization record lifecycle

## Purpose

This lifecycle explains the availability of an organization without discarding its organizational context. A chapter can close while past representatives and hierarchy still need its name. Staff can mark business status or archive the record for different reasons, and hard deletion must account for references that still depend on it.

Our reading is that the organization’s continuity matters independently of its current representatives. Archive retains an identity people can understand in dated views, while deletion removes owned live data. Role compliance is a separate assessment lifecycle; an inactive or archived organization is not automatically a compliant organization.

## Ownership and Authority

Creators establish an organization and its initial information. An API editor changes business status through a versioned save. Archive operators use dedicated actions, and deletion requires the delete grant plus dependency and protection checks. The built Organization 360 offers selected actions but does not provide a general editor for every service operation.

Compliance workers may change stored assessment and version without requesting a business-status transition. No inference operation recommends or executes organization lifecycle actions here. A parent relationship describes structure rather than authority; access continues to come from Platform security and the CRM operation grants.

## The Lifecycle


```mermaid
stateDiagram-v2
  state "Stored organization status" as status {
    [*] --> active
    active --> inactive: status save
    inactive --> active: status save
    active --> duplicate: status save
    duplicate --> active: status save
  }
  state "Archive flag (independent of status)" as archiveFlag {
    [*] --> live
    live --> archived: archive action
    archived --> live: unarchive action
  }
  status --> deleted: delete after dependency checks
  deleted --> [*]
```

## States

### new

No organization is stored under the requested identity. Entry requires this condition: There is no live organization at this identity. Available behavior is Submit a valid create request.. The create form is still a draft with no saved organization number.

### active

The organization has its normal active status. Entry requires this condition: A create defaults to active or an authorized save records it. Available behavior is Read; update under ordinary guards; archive; delete if dependencies permit.. The body can appear in ordinary discovery.

### inactive

The stored organization is inactive but retains hierarchy, affiliations and revisions. Entry requires this condition: A versioned save records inactive business status. Available behavior is Read; edit if otherwise available; restore active status; archive.. The identity and its hierarchy remain readable.

### duplicate

Duplicate status identifies a record awaiting data-quality treatment. Entry requires this condition: A save records duplicate status. Available behavior is Read; correct under ordinary guards; use separately authorized Data Quality work.. The body remains a live CRM identity pending further treatment.

### archived

Archive independently preserves status and relationships while blocking ordinary organization editing and default selection. Entry requires this condition: The archive action records the overlay without changing stored status. Available behavior is Direct read; unarchive; inspect authorized history; request guarded deletion.. Badges identify retained closed context, including archived ancestors or affiliation labels.

### deleted

The live organization and owned data are removed, with history and its spent number retained. Entry requires this condition: The guarded delete transaction succeeds. Available behavior is Inspect retained revisions under history authority.. The live organization is absent; ordinary restore is unavailable. This row’s lifecycle ends here; a new request or new record is separate work.

## Transitions Explained

### new → active

An authorized creator or integration starts this change when the following occurs: Create an organization using active or default status. The transition checks this boundary: Create permission, valid name and workspace references; a blocked duplicate requires authorized override and reason. The accompanying work is allocate organization number; attach logo; evaluate initial compliance without a notice; publish attention only when enabled; capture event and revision. A changed organization transaction produces its aggregate revision and event. Archive metadata records the actor and optional explanation; ordinary deletion retains its historical record.

### active → inactive

An authorized API editor starts this change when the following occurs: Save inactive status. The transition checks this boundary: Organization update permission and matching version; no archive or full lock. The accompanying work is persist the new status. A changed organization transaction produces its aggregate revision and event. Archive metadata records the actor and optional explanation; ordinary deletion retains its historical record.

### inactive → active

An authorized API editor starts this change when the following occurs: Save active status. The transition checks this boundary: Pass ordinary organization save authorization and concurrency checks. The accompanying work is persist active status. A changed organization transaction produces its aggregate revision and event. Archive metadata records the actor and optional explanation; ordinary deletion retains its historical record.

### active → duplicate

An authorized editor or data-quality process starts this change when the following occurs: Mark the organization duplicate in a save. The transition checks this boundary: Use the same guards as other status edits. The accompanying work is persist duplicate status. A changed organization transaction produces its aggregate revision and event. Archive metadata records the actor and optional explanation; ordinary deletion retains its historical record.

### active → archived

An authorized archive operator starts this change when the following occurs: Archive the organization in its current status. The transition checks this boundary: Archive permission, matching version and no full lock; optional reason is at most 500 characters. The accompanying work is store archive metadata; advance version and capture revision; preserve affiliations with archive information; exclude default selection. A changed organization transaction produces its aggregate revision and event. Archive metadata records the actor and optional explanation; ordinary deletion retains its historical record.

### archived → active

An authorized archive operator starts this change when the following occurs: Unarchive without changing the underlying status. The transition checks this boundary: Archive permission, current version and no full lock. The accompanying work is clear archive stamps; keep unarchive reason; advance version and capture revision. A changed organization transaction produces its aggregate revision and event. Archive metadata records the actor and optional explanation; ordinary deletion retains its historical record.

### active → deleted

An authorized delete operator or bulk job starts this change when the following occurs: Delete the organization directly or through a bulk job. The transition checks this boundary: Delete permission, no deletion-blocking owner or element lock, no protection, no child organizations and no affiliation references. The accompanying work is remove contact points and custom values; resolve enabled attention; detach logo; apply enabled owner-deletion policy; capture deletion history. A changed organization transaction produces its aggregate revision and event. Archive metadata records the actor and optional explanation; ordinary deletion retains its historical record.

### archived → deleted

An authorized delete operator starts this change when the following occurs: Delete while the organization is archived. The transition checks this boundary: Archive does not relax the normal delete checks. The accompanying work is perform ordinary organization deletion. A changed organization transaction produces its aggregate revision and event. Archive metadata records the actor and optional explanation; ordinary deletion retains its historical record.

## What Cannot Happen

The service returns a dependency refusal when children or any affiliation reference the organization. Past and future ties still preserve their organization context.

Archive refuses general correction with the archived-record response. An authorized unarchive action is the supported way to reopen ordinary editing.

No deleted-to-active restore exists. Live reads return not-found; a fresh create is a different creation with another allocated number.

## Permissions by State

The state rows reference grants from the CRM authorization model. Read access is distinct from mutation, and history requires the corresponding history and read checks. Administrator and Power User hold administrative record actions; ordinary Standard User grants include applicable read and update operations, while Read Only grants do not authorize edits.

Archived records remain directly readable, but ordinary update is blocked. Archive authority permits restoration subject to the dedicated guards. Deleted records have only retained history rather than another ordinary update state.

## Concurrency and Timing

Version checks and the organization row lock order simultaneous saves. Compliance uses that lock and an advisory lock and can advance the organization version, so an administrator’s type change can conflict with system work. The hierarchy constraint refuses a competing move that would form a cycle.

Hard deletion has no read-version input. Creation does not have the contact service’s fingerprint replay behavior: a repeated supplied identity conflicts, and an unkeyed retry can create another organization. Initial compliance evaluation occurs during creation, while later type edits require another trigger or reprocess to refresh assessments.

## Invariants

Our reading is that preserving organizational identity and hierarchy through ordinary corrections prevents a parent move from changing who a person worked for. Archive overlays availability without rewriting business status. Deletion must account for people’s ties of every date and for children, because those references remain meaningful even when a record is inactive or archived. Current-version and lock checks apply to the action actually performed; read visibility alone never supplies authority to reopen or remove an organization.
