---
id: ATS-CRM-ENT-013
scope: CAP-CRM-ENT-013
product_area: crm
module: entities
revision: 1
status: proposed
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-CRM-ENT-013-01
    title: Archive needs its own key
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-01
    preconditions: 'Prepare callers with update, read and archive keys.'
    steps: Archive and unarchive a contact and an organization as each.
    expected: 403 without the archive key; the record left live.
    negative: true
    data_needs: Use personas by key.
    bound_to:
      - TST-CRM-ENT-786
    provenance: test
    source: >-
      services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
      caller who may update contacts but not archive them, 403
    category: permission
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        caller who may update contacts but not archive them, 403
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        caller who may update contacts but not archive them, 403
    test_anchors:
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        caller who may update contacts but not archive them, 403
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        caller who may only read contacts, 403
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        caller who may update organizations but not archive them, 403
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses the
        unarchive to the same callers, 403
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#left the
        contact live after the refusals
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-013-02
    title: Archive at the version read
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-02
    preconditions: Prepare a live contact.
    steps: Archive without a version; at a stale version; an unknown id.
    expected: 400 naming sys_version; 409; 404.
    negative: true
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-786
      - TST-CRM-ENT-787
    provenance: test
    source: >-
      services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses an
      archive with no version, 400, naming it
    category: concurrency
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses an
        archive with no version, 400, naming it
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses an
        archive with no version, 400, naming it
    test_anchors:
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses an
        archive with no version, 400, naming it
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        stale version, 409
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#answers 404
        for a contact the tenant has not
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#leaves
        the contact live after a stale version
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-013-03
    title: Archive preserves everything and is idempotent
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-03
    preconditions: Prepare a deceased contact with collections and an affiliation.
    steps: Archive it; archive it again.
    expected: >-
      Instant, user and reason set, version once, status preserved, collections
      preserved, one revision; no new version.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-787
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
      the status it had: archive is not a status
    category: invariant
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
        the status it had: archive is not a status
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
        the status it had: archive is not a status
    test_anchors:
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#sets
        the instant, the user and the reason
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#bumps
        the version once and stamps the caller
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
        the status it had: archive is not a status
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
        every collection and the affiliation, unchanged
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#writes
        one revision of its own, naming the archive columns and nothing else of
        the record
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#archived
        again answers as it is, with no new version
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-013-04
    title: Unarchive returns the record and preserves its reason
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-04
    preconditions: Prepare an archived organization.
    steps: Unarchive with a reason; with 501 characters; archive again.
    expected: >-
      Columns cleared, record as it was, reason preserved; rejected; reason
      cleared.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-787
      - TST-CRM-ENT-786
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
      the trimmed reason as unarchive_reason
    category: transition
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
        the trimmed reason as unarchive_reason
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#keeps
        the trimmed reason as unarchive_reason
    test_anchors:
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#clears
        the three archive columns
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#returns
        the organization as it was, apart from its version and modified stamps
      - >-
        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/integration/services/persistence/organizations.archive.integration.spec.js#is
        refused as ObjectInvalid over 500 characters, naming the reason
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#is
        cleared by the next archive
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#is
        unarchived to the record it was, editable again
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-013-05
    title: an archived record rejects saves; a merge may save it
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-05
      - INV-DOM-CRM-ENT-033-12
    preconditions: Prepare an archived contact and organization.
    steps: 'Replace, patch, save as a merge.'
    expected: '409 RecordArchived twice, nothing changed; the merge saved.'
    negative: true
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-786
      - TST-CRM-ENT-787
    provenance: test
    source: >-
      services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
      replacement, 409 RecordArchived
    category: failure
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        replacement, 409 RecordArchived
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        replacement, 409 RecordArchived
    test_anchors:
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        replacement, 409 RecordArchived
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        patch, 409 RecordArchived
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        save of the organization, 409 RecordArchived
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#is
        unchanged after a refused save
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#is
        saved by a merge, which names the one save an archived record accepts
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-013-06
    title: Lists leave archived records out by default
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-06
    preconditions: Prepare one archived and some live contacts.
    steps: >-
      List by default, archived=only, archived=include; read the archived one by
      id.
    expected: Live only; it alone; both; complete record.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-786
      - TST-CRM-ENT-787
    provenance: test
    source: >-
      services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it for
      archived=only, and only it
    category: rule
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it for
        archived=only, and only it
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it for
        archived=only, and only it
    test_anchors:
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#leaves it
        out of the list
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it for
        archived=only, and only it
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it
        with the live ones for archived=include
      - >-
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#is still
        read by its id
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#is
        left out of the list by default
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-013-07
    title: Pickers and Quick Search leave archived records out
    level: browser
    proves:
      - BR-CAP-CRM-ENT-013-07
    preconditions: Prepare an archived contact.
    steps: Search for it in Quick Search and a contact picker.
    expected: Not offered.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-774
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/contacts/CRM-ACC-0066.spec.ts#CRM-ACC-0066
    category: interaction
    action_evidence:
      provenance: test
      source: >-
        react-console:acceptance/crm/playwright/journeys/contacts/CRM-ACC-0066.spec.ts#CRM-ACC-0066
    assertion_evidence:
      provenance: test
      source: >-
        react-console:acceptance/crm/playwright/journeys/contacts/CRM-ACC-0066.spec.ts#CRM-ACC-0066
    test_anchors:
      - >-
        react-console:acceptance/crm/playwright/journeys/contacts/CRM-ACC-0066.spec.ts#CRM-ACC-0066
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-013-08
    title: an archived organization preserves its people
    level: browser
    proves:
      - BR-CAP-CRM-ENT-013-08
    preconditions: Prepare an organization with a current and a former employee.
    steps: Archive it; read the affiliations and the people list.
    expected: >-
      Affiliations keep the organization with its archive instant; Past, Current
      and All returned, each marked.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-787
      - TST-CRM-ENT-775
    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
    category: interaction
    action_evidence:
      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
    assertion_evidence:
      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
    test_anchors:
      - >-
        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#lists
        the former employee under Past
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#lists
        both under All, each marked with the organization it names being
        archived
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#stays
        on the organization’s people list, marked as archived
      - >-
        react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0147.spec.ts#CRM-ACC-0147
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-013-09
    title: Only the actions write the archive record
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-09
      - INV-DOM-CRM-ENT-033-11
    preconditions: Prepare an unarchived contact with an unarchive reason.
    steps: Save it ordinarily.
    expected: The reason preserved; the archive columns untouched.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-787
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#is
      kept through a plain save, which never writes it
    category: invariant
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#is
        kept through a plain save, which never writes it
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#is
        kept through a plain save, which never writes it
    test_anchors:
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#is
        kept through a plain save, which never writes it
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#is
        kept through a plain save, which never writes it
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-013-10
    title: 'the journey: archive a closed firm and keep its people'
    level: browser
    proves:
      - AS-JNY-CRM-ENT-003-01
      - AS-JNY-CRM-ENT-003-02
      - AS-JNY-CRM-ENT-003-03
    preconditions: Prepare a firm with a former employee.
    steps: Run JNY-CRM-ENT-003.
    expected: >-
      Out of the default list; past affiliations name it, badged archived;
      unarchive returns it as it was.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-775
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0147.spec.ts#CRM-ACC-0147
    category: interaction
    action_evidence:
      provenance: test
      source: >-
        react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0147.spec.ts#CRM-ACC-0147
    assertion_evidence:
      provenance: test
      source: >-
        react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0147.spec.ts#CRM-ACC-0147
    test_anchors:
      - >-
        react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0147.spec.ts#CRM-ACC-0147
      - >-
        react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0116.spec.ts#CRM-ACC-0116
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-013-11
    title: Accept the archive reason limit and refuse the next character
    category: boundary
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-03
      - BR-CAP-CRM-ENT-013-04
    preconditions: Two eligible records have current versions.
    steps: >-
      Archive one with a reason of 500 characters; try the other with 501;
      exercise the same boundary when restoring.
    expected: >-
      The limit-length reason is retained; the longer reason is refused without
      changing lifecycle state.
    negative: true
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
      the status it had: archive is not a status
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
        the status it had: archive is not a status
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
        the status it had: archive is not a status
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-013-12
    title: Archive changes discovery without losing direct reads
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-003-05
      - BR-CAP-CRM-ENT-013-06
    preconditions: A live person can be found in an ordinary list.
    steps: >-
      Archive the person; list ordinarily and with archive inclusion; open it by
      identity.
    expected: >-
      The ordinary list omits it, the explicit archived selection includes it
      and the direct read retains its saved information.
    negative: false
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/entities/tests/e2e/contacts.e2e.spec.js#answers only
      the contacts a picker may offer: not the inactive, not the deceased;
      services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it for
      archived=only, and only it
    exercises:
      - CAP-CRM-ENT-003
      - CAP-CRM-ENT-013
    workflows:
      - WF-CRM-ENT-011
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/e2e/contacts.e2e.spec.js#answers
        only the contacts a picker may offer: not the inactive, not the
        deceased;
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it for
        archived=only, and only it
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/e2e/contacts.e2e.spec.js#answers
        only the contacts a picker may offer: not the inactive, not the
        deceased;
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it for
        archived=only, and only it
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-013-13
    title: Archive invalidates an open correction
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-004-01
      - BR-CAP-CRM-ENT-013-05
    preconditions: An editor reads a live person while an administrator can archive it.
    steps: Archive the person; submit the editor’s pending correction.
    expected: >-
      The correction is refused and the archived record retains its pre-edit
      values.
    negative: false
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/entities/tests/e2e/contacts.e2e.spec.js#answers 400
      naming sys_version to a patch that tests no version;
      services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
      replacement, 409 RecordArchived
    exercises:
      - CAP-CRM-ENT-004
      - CAP-CRM-ENT-013
    workflows: []
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/e2e/contacts.e2e.spec.js#answers 400
        naming sys_version to a patch that tests no version;
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        replacement, 409 RecordArchived
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/e2e/contacts.e2e.spec.js#answers 400
        naming sys_version to a patch that tests no version;
        services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
        replacement, 409 RecordArchived
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-013-14
    title: Archived bodies retain their people’s relationships
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-009-15
      - BR-CAP-CRM-ENT-013-08
    preconditions: 'An organization has current, ended and upcoming person ties.'
    steps: >-
      Archive the organization; inspect each dated people view and the contacts’
      affiliations.
    expected: >-
      The relationship identities persist and reads show the organization’s
      archive information.
    negative: false
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/entities/tests/e2e/contact-affiliations.e2e.spec.js#answers
      403 permission_missing to a caller who may read organizations but not
      contacts;
      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
    exercises:
      - CAP-CRM-ENT-009
      - CAP-CRM-ENT-013
    workflows: []
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/e2e/contact-affiliations.e2e.spec.js#answers
        403 permission_missing to a caller who may read organizations but not
        contacts;
        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
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/e2e/contact-affiliations.e2e.spec.js#answers
        403 permission_missing to a caller who may read organizations but not
        contacts;
        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
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-013-15
    title: Archive does not erase deletion dependencies
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-08
      - BR-CAP-CRM-ENT-014-05
    preconditions: An archived organization still has an ended person affiliation.
    steps: Attempt organization deletion and read the retained affiliation.
    expected: >-
      Deletion is refused and the ended relationship still identifies the
      archived body.
    negative: false
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    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;
      services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
      409 to a delete while the contact is affiliated with it
    exercises:
      - CAP-CRM-ENT-013
      - CAP-CRM-ENT-014
    workflows: []
    test_anchors: []
    action_evidence:
      provenance: proposed
      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;
        services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
        409 to a delete while the contact is affiliated with it
    assertion_evidence:
      provenance: proposed
      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;
        services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
        409 to a delete while the contact is affiliated with it
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-013-16
    title: Archive and restoration remain inspectable
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-03
      - BR-CAP-CRM-ENT-016-01
    preconditions: A live person has readable history.
    steps: >-
      Archive it with a reason, restore it with a reason and open both
      revisions.
    expected: >-
      History identifies both lifecycle changes while the restored person keeps
      its identity and collections.
    negative: false
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
      the status it had: archive is not a status;
      services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#writes
      exactly one revision, whatever the save touched
    exercises:
      - CAP-CRM-ENT-013
      - CAP-CRM-ENT-016
    workflows: []
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
        the status it had: archive is not a status;
        services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#writes
        exactly one revision, whatever the save touched
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
        the status it had: archive is not a status;
        services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#writes
        exactly one revision, whatever the save touched
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-013-17
    title: Exercise every declared authority independently
    category: permission
    level: api
    proves:
      - BR-CAP-CRM-ENT-013-01
    preconditions: >-
      An eligible record and configuration fixture exist for each operation; the
      caller can reach only the run’s workspace.
    steps: >-
      For each declared permission, execute its matching operation with that
      permission, then without it while retaining the other required grants.
      Read affected records after every refused mutation.
    expected: >-
      The authorized case reaches the operation; the missing-grant case is
      refused and preserves saved data. Record access alone does not authorize
      the other declared actions.
    negative: true
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:aws/crm.service.ts:ApplicationPermissions;
      services-crm:modules/entities/aws/api/entities.routes.ts
    permission_keys:
      - crm.contacts.archive
      - crm.organizations.archive
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:aws/crm.service.ts:ApplicationPermissions;
        services-crm:modules/entities/aws/api/entities.routes.ts
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:aws/crm.service.ts:ApplicationPermissions;
        services-crm:modules/entities/aws/api/entities.routes.ts
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
evidence:
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a caller
    who may update contacts but not archive them, 403
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a caller
    who may only read contacts, 403
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a caller
    who may update organizations but not archive them, 403
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses the
    unarchive to the same callers, 403
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#left the contact
    live after the refusals
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses an
    archive with no version, 400, naming it
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a stale
    version, 409
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#answers 404 for
    a contact the tenant has not
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#leaves
    the contact live after a stale version
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
    the status it had: archive is not a status
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#sets
    the instant, the user and the reason
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#bumps
    the version once and stamps the caller
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
    every collection and the affiliation, unchanged
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#writes
    one revision of its own, naming the archive columns and nothing else of the
    record
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#archived
    again answers as it is, with no new version
  - >-
    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/integration/services/persistence/organizations.archive.integration.spec.js#clears
    the three archive columns
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#returns
    the organization as it was, apart from its version and modified stamps
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#is
    refused as ObjectInvalid over 500 characters, naming the reason
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#is
    cleared by the next archive
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#is unarchived to
    the record it was, editable again
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
    replacement, 409 RecordArchived
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a patch,
    409 RecordArchived
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a save
    of the organization, 409 RecordArchived
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#is
    unchanged after a refused save
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#is
    saved by a merge, which names the one save an archived record accepts
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it for
    archived=only, and only it
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#leaves it out of
    the list
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it with
    the live ones for archived=include
  - >-
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#is still read by
    its id
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#is
    left out of the list by default
  - >-
    react-console:acceptance/crm/playwright/journeys/contacts/CRM-ACC-0066.spec.ts#CRM-ACC-0066
  - >-
    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#lists
    the former employee under Past
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#lists
    both under All, each marked with the organization it names being archived
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#stays
    on the organization’s people list, marked as archived
  - >-
    react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0147.spec.ts#CRM-ACC-0147
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#is
    kept through a plain save, which never writes it
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/organizations.archive.integration.spec.js#is
    kept through a plain save, which never writes it
  - >-
    react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0116.spec.ts#CRM-ACC-0116
  - >-
    services-crm:modules/entities/tests/e2e/contacts.e2e.spec.js#answers only
    the contacts a picker may offer: not the inactive, not the deceased;
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#lists it for
    archived=only, and only it
  - >-
    services-crm:modules/entities/tests/e2e/contacts.e2e.spec.js#answers 400
    naming sys_version to a patch that tests no version;
    services-crm:modules/entities/tests/e2e/archive.e2e.spec.js#refuses a
    replacement, 409 RecordArchived
  - >-
    services-crm:modules/entities/tests/e2e/contact-affiliations.e2e.spec.js#answers
    403 permission_missing to a caller who may read organizations but not
    contacts;
    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 ended affiliation naming the organization's id, with its name and its
    archive instant;
    services-crm:modules/entities/tests/e2e/organizations.e2e.spec.js#answers
    409 to a delete while the contact is affiliated with it
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.archive.integration.spec.js#keeps
    the status it had: archive is not a status;
    services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#writes
    exactly one revision, whatever the save touched
  - >-
    services-crm:aws/crm.service.ts:ApplicationPermissions;
    services-crm:modules/entities/aws/api/entities.routes.ts
coverage:
  rule: covered
  transition: covered
  validation: 'gap: FND-CRM-ENT-061'
  permission: covered
  edge: 'gap: FND-CRM-ENT-061'
  failure: covered
  boundary: covered
  concurrency: covered
  invariant: covered
  interaction: covered
previous_approval:
  revision: 1
  approved_by: Andrew
  approved_at: '2026-10-22T00:00:00.000Z'
transition_coverage:
  - state_model: STATE-CRM-ENT-001
    from: active
    to: archived
    scenarios:
      - ATS-CRM-ENT-013-03
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/design/state-models/STATE-CRM-ENT-001-contact-record-lifecycle.md:transitions
  - state_model: STATE-CRM-ENT-001
    from: archived
    to: active
    scenarios:
      - ATS-CRM-ENT-013-04
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/design/state-models/STATE-CRM-ENT-001-contact-record-lifecycle.md:transitions
  - state_model: STATE-CRM-ENT-002
    from: active
    to: archived
    scenarios:
      - ATS-CRM-ENT-013-03
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/design/state-models/STATE-CRM-ENT-002-organization-record-lifecycle.md:transitions
  - state_model: STATE-CRM-ENT-002
    from: archived
    to: active
    scenarios:
      - ATS-CRM-ENT-013-04
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/design/state-models/STATE-CRM-ENT-002-organization-record-lifecycle.md:transitions
coverage_notes:
  validation:
    reason: >-
      No detailed validation scenario currently specifies this aspect; the
      coverage finding records the required follow-through.
    provenance: unknown
    source: FND-CRM-ENT-061
  edge:
    reason: >-
      No detailed edge scenario currently specifies this aspect; the coverage
      finding records the required follow-through.
    provenance: unknown
    source: FND-CRM-ENT-061
coverage_findings:
  - FND-CRM-ENT-061
  - FND-CRM-ENT-075
permission_coverage:
  - key: crm.contacts.archive
    where_checked: api
    scenario: ATS-CRM-ENT-013-17
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-013-archive-a-contact-or-an-organization-and-bring-it-back.md
  - key: crm.organizations.archive
    where_checked: api
    scenario: ATS-CRM-ENT-013-17
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-013-archive-a-contact-or-an-organization-and-bring-it-back.md
related_coverage:
  - capability: CAP-CRM-ENT-003
    scenarios:
      - ATS-CRM-ENT-013-12
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-013-archive-a-contact-or-an-organization-and-bring-it-back.md:related
  - capability: CAP-CRM-ENT-004
    scenarios:
      - ATS-CRM-ENT-013-13
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-013-archive-a-contact-or-an-organization-and-bring-it-back.md:related
  - capability: CAP-CRM-ENT-009
    scenarios:
      - ATS-CRM-ENT-013-14
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-013-archive-a-contact-or-an-organization-and-bring-it-back.md:related
  - capability: CAP-CRM-ENT-014
    scenarios:
      - ATS-CRM-ENT-013-15
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-013-archive-a-contact-or-an-organization-and-bring-it-back.md:related
  - capability: CAP-CRM-ENT-016
    scenarios:
      - ATS-CRM-ENT-013-16
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-013-archive-a-contact-or-an-organization-and-bring-it-back.md:related
examination_evidence:
  provenance: documented
  source: 'rhythm-v2-docs:specs/crm/entities/reports/EXAMINATION-2026-10-23.md'
  heading_conflict: FND-CRM-ENT-075
---

# Set records aside and restore them
## Coverage

The category map separates specified cases from recorded gaps. A proposed case describes proof to implement; a binding identifies the assertions supplied by an existing executable file. The permission and transition ledgers record the individual checks needed for the capability.

| Required rule | Scenario or finding |
|---|---|
| `BR-CAP-CRM-ENT-013-01` | `ATS-CRM-ENT-013-01`, `ATS-CRM-ENT-013-17` |
| `BR-CAP-CRM-ENT-013-02` | `ATS-CRM-ENT-013-02` |
| `BR-CAP-CRM-ENT-013-03` | `ATS-CRM-ENT-013-03`, `ATS-CRM-ENT-013-11`, `ATS-CRM-ENT-013-16` |
| `BR-CAP-CRM-ENT-013-04` | `ATS-CRM-ENT-013-04`, `ATS-CRM-ENT-013-11` |
| `BR-CAP-CRM-ENT-013-05` | `ATS-CRM-ENT-013-05`, `ATS-CRM-ENT-013-13` |
| `BR-CAP-CRM-ENT-013-06` | `ATS-CRM-ENT-013-06`, `ATS-CRM-ENT-013-12` |
| `BR-CAP-CRM-ENT-013-08` | `ATS-CRM-ENT-013-08`, `ATS-CRM-ENT-013-14`, `ATS-CRM-ENT-013-15` |
| `BR-CAP-CRM-ENT-013-09` | `ATS-CRM-ENT-013-09` |

## Interactions With Related Capabilities

The interaction scenarios exercise locate people and organizations; save corrections without overwriting another change; maintain a person’s organizational relationships; remove records and their owned information; inspect a record’s changes over time. They change one part of a prepared record and inspect the dependent outcome. Unbound interactions remain proposed rather than implying an existing end-to-end implementation.

## Source Evidence

The frontmatter pins the repositories and identifies the source anchors for each scenario. Bindings record inspected assertions, while unbound cases remain proposed. Source inspection supplies no execution result or product approval.
