---
id: ATS-CRM-ENT-016
scope: CAP-CRM-ENT-016
product_area: crm
module: entities
revision: 1
status: proposed
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-CRM-ENT-016-01
    title: 'One revision per committed save, none for a no-op'
    level: api
    proves:
      - BR-CAP-CRM-ENT-016-01
      - INV-DOM-CRM-ENT-033-08
    preconditions: Prepare a contact.
    steps: Save it touching several collections; save it unmodified.
    expected: Exactly one revision labelled with the name; then none.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-794
      - TST-CRM-ENT-786
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#writes
      exactly one revision, whatever the save touched
    category: invariant
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#writes
        exactly one revision, whatever the save touched
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#writes
        exactly one revision, whatever the save touched
    test_anchors:
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#writes
        exactly one revision, whatever the save touched
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#labels
        it with the contact’s display name, so a deleted contact stays
        identifiable
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/record-saves.no-op.integration.spec.js#writes
        no revision
      - >-
        services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#has
        one revision per committed save, newest first
    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-016-02
    title: the history key and reach
    level: api
    proves:
      - BR-CAP-CRM-ENT-016-02
    preconditions: 'Prepare a contact and an organization, one later deleted.'
    steps: >-
      Read history without the key; with key and read; with key but no read; of
      the deleted one.
    expected: 403; 200; 404; 200 marked deleted.
    negative: true
    data_needs: Use personas by key.
    bound_to:
      - TST-CRM-ENT-786
    provenance: test
    source: >-
      services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#answers
      a caller with the history key but no read of organizations 404, as the
      organization itself would
    category: permission
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#answers
        a caller with the history key but no read of organizations 404, as the
        organization itself would
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#answers
        a caller with the history key but no read of organizations 404, as the
        organization itself would
    test_anchors:
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#refuses
        a caller who may read the contact but was not given its history
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#answers
        a caller holding only read and history, which is the console reader
      - >-
        services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#answers
        a caller with the history key but no read of organizations 404, as the
        organization itself would
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#keeps
        a deleted contact's history readable, with the record marked deleted and
        when
      - >-
        services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#keeps
        its history, marked deleted
    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-016-03
    title: Timeline paging and filters
    level: api
    proves:
      - BR-CAP-CRM-ENT-016-03
    preconditions: Prepare a contact with several revisions.
    steps: Page while it changes; filter; send an unknown parameter; ask for 101.
    expected: Stable cursor; filtered; 400; 400.
    negative: true
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-786
    provenance: test
    source: >-
      services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#refuses
      a query parameter it does not know, rather than ignoring the filter
    category: concurrency
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#refuses
        a query parameter it does not know, rather than ignoring the filter
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#refuses
        a query parameter it does not know, rather than ignoring the filter
    test_anchors:
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#pages
        with a cursor that does not move when the record changes behind it
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#filters
        the timeline by person, operation, source and date
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#refuses
        a query parameter it does not know, rather than ignoring the filter
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#refuses
        a limit above the maximum page size
    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-016-04
    title: Revisions cannot be forged and outlive the record
    level: api
    proves:
      - BR-CAP-CRM-ENT-016-07
      - INV-DOM-CRM-ENT-033-09
    preconditions: No additional setup is required.
    steps: >-
      Insert a revision as the application; delete a contact; read across
      tenants.
    expected: Rejected; its revision preserved; another workspace’s hidden.
    negative: true
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-794
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/db/record-revisions.table.integration.spec.js#may
      not insert a revision, so nothing the application runs can forge one
    category: invariant
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/db/record-revisions.table.integration.spec.js#may
        not insert a revision, so nothing the application runs can forge one
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/db/record-revisions.table.integration.spec.js#may
        not insert a revision, so nothing the application runs can forge one
    test_anchors:
      - >-
        services-crm:modules/entities/tests/integration/db/record-revisions.table.integration.spec.js#may
        not insert a revision, so nothing the application runs can forge one
      - >-
        services-crm:modules/entities/tests/integration/db/record-revisions.table.integration.spec.js#keeps
        a revision of a contact that has been deleted, the row surviving the
        record
      - >-
        services-crm:modules/entities/tests/integration/db/record-revisions.table.integration.spec.js#reads
        nothing of another tenant’s, the policy hiding it even to a statement
        that names its record
    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-016-05
    title: 'Sections, labels and names are presented as the console displays them'
    level: api
    proves:
      - BR-CAP-CRM-ENT-016-04
      - BR-CAP-CRM-ENT-016-05
    preconditions: >-
      Prepare a contact with roles, an affiliation and custom values changed by
      a since-renamed user.
    steps: Open the revisions.
    expected: >-
      Sections and labels as configured, the role and affiliation named, the
      user by today's name.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-786
      - TST-CRM-ENT-794
    provenance: test
    source: >-
      services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#shows
      the role removed and the role added, each under the name it has now
    category: rule
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#shows
        the role removed and the role added, each under the name it has now
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#shows
        the role removed and the role added, each under the name it has now
    test_anchors:
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#reads
        one revision in full: the section, the field, its label, its data type
        and both values
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#shows
        the role removed and the role added, each under the name it has now
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#lists
        the affiliation the contact was created with as added, named by its
        organization and type
      - >-
        services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#names
        a custom field by the tenant's own label, and its value by its option's
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/record-revisions.queries.integration.spec.js#answers
        the display name the acting user has now, not the one the capture
        snapshotted
    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-016-06
    title: Roll back a change lacking revision attribution
    category: failure
    level: api
    proves:
      - BR-CAP-CRM-ENT-016-08
      - INV-DOM-CRM-ENT-033-10
    preconditions: A run-owned person is visible before a direct database transaction.
    steps: >-
      Attempt a changed write without the required actor and source context;
      inspect the person and its revision count afterward.
    expected: >-
      The transaction fails and neither the attempted value nor a revision
      survives.
    negative: true
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:docs/record-history.md#Fail closed, and the maintenance
      helper
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:docs/record-history.md#Fail closed, and the maintenance
        helper
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:docs/record-history.md#Fail closed, and the maintenance
        helper
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-016-07
    title: Review a correction and its unchanged retry
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-004-02
      - BR-CAP-CRM-ENT-016-01
    preconditions: A person with several contact points has a known revision count.
    steps: >-
      Save corrections to multiple sections; read the timeline; save the
      returned record unchanged and reread the timeline.
    expected: >-
      The changed save contributes one aggregate revision and the unchanged save
      contributes none.
    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/record-saves.no-op.integration.spec.js#writes
      no revision;
      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-004
      - CAP-CRM-ENT-016
    workflows: []
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/record-saves.no-op.integration.spec.js#writes
        no revision;
        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/record-saves.no-op.integration.spec.js#writes
        no revision;
        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-016-08
    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-016-09
    title: Deleted-record history survives the ordinary record
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-014-02
      - BR-CAP-CRM-ENT-016-02
    preconditions: A person has saved revisions and an authorized history reader.
    steps: Delete the person; read its ordinary record and its timeline.
    expected: >-
      The ordinary read is not found while history remains readable and
      identifies the deleted subject.
    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.integration.spec.js#removes
      every owned element with it, the foreign keys cascading;
      services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#answers
      a caller with the history key but no read of organizations 404, as the
      organization itself would
    exercises:
      - CAP-CRM-ENT-014
      - CAP-CRM-ENT-016
    workflows:
      - WF-CRM-ENT-009
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.integration.spec.js#removes
        every owned element with it, the foreign keys cascading;
        services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#answers
        a caller with the history key but no read of organizations 404, as the
        organization itself would
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.integration.spec.js#removes
        every owned element with it, the foreign keys cascading;
        services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#answers
        a caller with the history key but no read of organizations 404, as the
        organization itself would
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-016-10
    title: Lock changes appear in audit and aggregate history
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-015-03
      - BR-CAP-CRM-ENT-016-01
    preconditions: A live person has no lock and both histories are readable.
    steps: Apply a delete lock with a reason and read lock audit and record history.
    expected: >-
      Both reads identify the lock change without creating multiple aggregate
      revisions.
    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/record-locks.queries.integration.spec.js#answers
      the newest two changes of the record, every property mapped, and where the
      page ended;
      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-015
      - CAP-CRM-ENT-016
    workflows:
      - WF-CRM-ENT-009
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/record-locks.queries.integration.spec.js#answers
        the newest two changes of the record, every property mapped, and where
        the page ended;
        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/record-locks.queries.integration.spec.js#answers
        the newest two changes of the record, every property mapped, and where
        the page ended;
        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-016-11
    title: Exercise every declared authority independently
    category: permission
    level: api
    proves:
      - BR-CAP-CRM-ENT-016-02
    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.history
      - crm.organizations.history
      - crm.contacts.read
      - crm.organizations.read
    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/integration/services/persistence/contacts.history.integration.spec.js#writes
    exactly one revision, whatever the save touched
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#labels
    it with the contact’s display name, so a deleted contact stays identifiable
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/record-saves.no-op.integration.spec.js#writes
    no revision
  - >-
    services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#has
    one revision per committed save, newest first
  - >-
    services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#answers
    a caller with the history key but no read of organizations 404, as the
    organization itself would
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#refuses
    a caller who may read the contact but was not given its history
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#answers
    a caller holding only read and history, which is the console reader
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#keeps a
    deleted contact's history readable, with the record marked deleted and when
  - >-
    services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#keeps
    its history, marked deleted
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#refuses
    a query parameter it does not know, rather than ignoring the filter
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#pages
    with a cursor that does not move when the record changes behind it
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#filters
    the timeline by person, operation, source and date
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#refuses
    a limit above the maximum page size
  - >-
    services-crm:modules/entities/tests/integration/db/record-revisions.table.integration.spec.js#may
    not insert a revision, so nothing the application runs can forge one
  - >-
    services-crm:modules/entities/tests/integration/db/record-revisions.table.integration.spec.js#keeps
    a revision of a contact that has been deleted, the row surviving the record
  - >-
    services-crm:modules/entities/tests/integration/db/record-revisions.table.integration.spec.js#reads
    nothing of another tenant’s, the policy hiding it even to a statement that
    names its record
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#shows
    the role removed and the role added, each under the name it has now
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#reads
    one revision in full: the section, the field, its label, its data type and
    both values
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#lists
    the affiliation the contact was created with as added, named by its
    organization and type
  - >-
    services-crm:modules/entities/tests/e2e/contacts-history.e2e.spec.js#names a
    custom field by the tenant's own label, and its value by its option's
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/record-revisions.queries.integration.spec.js#answers
    the display name the acting user has now, not the one the capture
    snapshotted
  - 'services-crm:docs/record-history.md#Fail closed, and the maintenance helper'
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/record-saves.no-op.integration.spec.js#writes
    no revision;
    services-crm:modules/entities/tests/integration/services/persistence/contacts.history.integration.spec.js#writes
    exactly one revision, whatever the save touched
  - >-
    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:modules/entities/tests/integration/services/persistence/contacts.integration.spec.js#removes
    every owned element with it, the foreign keys cascading;
    services-crm:modules/entities/tests/e2e/organizations-history.e2e.spec.js#answers
    a caller with the history key but no read of organizations 404, as the
    organization itself would
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/record-locks.queries.integration.spec.js#answers
    the newest two changes of the record, every property mapped, and where the
    page ended;
    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: not-applicable
  validation: 'gap: FND-CRM-ENT-064'
  permission: covered
  edge: 'gap: FND-CRM-ENT-064'
  failure: covered
  boundary: 'gap: FND-CRM-ENT-064'
  concurrency: covered
  invariant: covered
  interaction: covered
previous_approval:
  revision: 1
  approved_by: Andrew
  approved_at: '2026-10-22T00:00:00.000Z'
coverage_notes:
  transition:
    reason: >-
      History is a read-only projection; record changes and deletion have
      transition proof in their owning specifications.
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-016-see-who-changed-a-contact-or-an-organization-and-what.md
  validation:
    reason: >-
      No detailed validation scenario currently specifies this aspect; the
      coverage finding records the required follow-through.
    provenance: unknown
    source: FND-CRM-ENT-064
  edge:
    reason: >-
      No detailed edge scenario currently specifies this aspect; the coverage
      finding records the required follow-through.
    provenance: unknown
    source: FND-CRM-ENT-064
  boundary:
    reason: >-
      No detailed boundary scenario currently specifies this aspect; the
      coverage finding records the required follow-through.
    provenance: unknown
    source: FND-CRM-ENT-064
coverage_findings:
  - FND-CRM-ENT-064
  - FND-CRM-ENT-075
permission_coverage:
  - key: crm.contacts.history
    where_checked: api
    scenario: ATS-CRM-ENT-016-11
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-016-see-who-changed-a-contact-or-an-organization-and-what.md
  - key: crm.organizations.history
    where_checked: api
    scenario: ATS-CRM-ENT-016-11
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-016-see-who-changed-a-contact-or-an-organization-and-what.md
  - key: crm.contacts.read
    where_checked: api
    scenario: ATS-CRM-ENT-016-11
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-016-see-who-changed-a-contact-or-an-organization-and-what.md
  - key: crm.organizations.read
    where_checked: api
    scenario: ATS-CRM-ENT-016-11
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-016-see-who-changed-a-contact-or-an-organization-and-what.md
related_coverage:
  - capability: CAP-CRM-ENT-004
    scenarios:
      - ATS-CRM-ENT-016-07
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-016-see-who-changed-a-contact-or-an-organization-and-what.md:related
  - capability: CAP-CRM-ENT-013
    scenarios:
      - ATS-CRM-ENT-016-08
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-016-see-who-changed-a-contact-or-an-organization-and-what.md:related
  - capability: CAP-CRM-ENT-014
    scenarios:
      - ATS-CRM-ENT-016-09
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-016-see-who-changed-a-contact-or-an-organization-and-what.md:related
  - capability: CAP-CRM-ENT-015
    scenarios:
      - ATS-CRM-ENT-016-10
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-016-see-who-changed-a-contact-or-an-organization-and-what.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
---

# Inspect a record’s changes over time
## 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-016-01` | `ATS-CRM-ENT-016-01`, `ATS-CRM-ENT-016-07`, `ATS-CRM-ENT-016-08`, `ATS-CRM-ENT-016-10` |
| `BR-CAP-CRM-ENT-016-02` | `ATS-CRM-ENT-016-02`, `ATS-CRM-ENT-016-09`, `ATS-CRM-ENT-016-11` |
| `BR-CAP-CRM-ENT-016-03` | `ATS-CRM-ENT-016-03` |
| `BR-CAP-CRM-ENT-016-07` | `ATS-CRM-ENT-016-04` |

## Interactions With Related Capabilities

The interaction scenarios exercise save corrections without overwriting another change; set records aside and restore them; remove records and their owned information; control record locks and system protection. 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.
