---
id: ATS-CRM-DQ-019
scope: CAP-CRM-DQ-019
product_area: crm
module: data-quality
revision: 1
status: proposed
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-CRM-DQ-019-01
    title: Workspace history filters retain paging order
    level: api
    proves:
      - BR-CAP-CRM-DQ-019-01
    preconditions: 'Prepare both record types, several requesters and a failed attempt.'
    steps: 'List defaults, all statuses and each filter, then page.'
    expected: >-
      Default results contain successes, requested status and filters narrow
      correctly and pages preserve order.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - TST-CRM-DQ-181
      - TST-CRM-DQ-183
    provenance: test
    source: >-
      services-crm:modules/merges/tests/integration/services/merges/tenant-merge-history.integration.spec.js#answers
      the merges that succeeded, which is what a history screen asks for by
      default
    category: boundary
    execution_sources:
      - >-
        services-crm:modules/merges/tests/integration/services/merges/tenant-merge-history.integration.spec.js#answers
        the merges that succeeded, which is what a history screen asks for by
        default
      - >-
        services-crm:modules/merges/tests/integration/services/merges/tenant-merge-history.integration.spec.js#answers
        the merges one person asked for in a span, the filters narrowing
        together
      - >-
        services-crm:modules/merges/tests/integration/services/merges/tenant-merge-history.integration.spec.js#answers
        the next page from that position, in the same order
      - >-
        services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#refuses a page
        larger than the list will answer, rather than reading the whole history
  - id: ATS-CRM-DQ-019-02
    title: Absorbed and surviving identities share lineage
    level: api
    proves:
      - BR-CAP-CRM-DQ-019-02
    preconditions: A merge has succeeded.
    steps: Request history through survivor and absorbed identity.
    expected: Both return the survivor's same history.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - TST-CRM-DQ-183
    provenance: test
    source: >-
      services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#answers the merge
      in the survivor’s history
    category: rule
    execution_sources:
      - >-
        services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#answers the
        merge in the survivor’s history
      - >-
        services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#answers the
        same history when asked under an id the merge took away, under the
        survivor
  - id: ATS-CRM-DQ-019-03
    title: Historical identity remains readable after absorption
    level: api
    proves:
      - BR-CAP-CRM-DQ-019-03
    preconditions: Prepare deleted participants and visible or unavailable requesters.
    steps: List their merges.
    expected: >-
      Participant names come from originals and requester names are current or
      blank.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - TST-CRM-DQ-183
      - TST-CRM-DQ-181
    provenance: test
    source: >-
      services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#names the
      survivor and the records it took away, so a history list needs no further
      read
    category: rule
    execution_sources:
      - >-
        services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#names the
        survivor and the records it took away, so a history list needs no
        further read
      - >-
        services-crm:modules/merges/tests/integration/services/merges/tenant-merge-history.integration.spec.js#is
        the name Platform knows the requester by now, never the id a screen
        cannot read
      - >-
        services-crm:modules/merges/tests/integration/services/merges/tenant-merge-history.integration.spec.js#is
        nothing at all for a requester the view does not answer for, rather than
        their id
  - id: ATS-CRM-DQ-019-04
    title: Outcome details preserve decisions and gap fills
    level: api
    proves:
      - BR-CAP-CRM-DQ-019-04
    preconditions: A completed merge includes a reviewer choice and an automatic fill.
    steps: Inspect its details.
    expected: >-
      The choice retains author and source, the fill retains its source and
      originals accompany the stored outcome.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - TST-CRM-DQ-181
      - TST-CRM-DQ-183
    provenance: test
    source: >-
      services-crm:modules/merges/tests/integration/services/merges/merge-outcome.integration.spec.js#keeps
      the reviewer’s choice with what it was, who made it, and the record it was
      taken from
    category: rule
    execution_sources:
      - >-
        services-crm:modules/merges/tests/integration/services/merges/merge-outcome.integration.spec.js#keeps
        the reviewer’s choice with what it was, who made it, and the record it
        was taken from
      - >-
        services-crm:modules/merges/tests/integration/services/merges/merge-outcome.integration.spec.js#says
        which record a value was filled in from, where the survivor had none
      - >-
        services-crm:modules/merges/tests/integration/services/merges/merge-outcome.integration.spec.js#keeps
        the absorbed record’s original values beside the outcome
      - >-
        services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#answers the
        evidence of what it did on the details route, which the summary leaves
        out
  - id: ATS-CRM-DQ-019-05
    title: Permanent outcomes cannot be erased or relocated
    level: api
    proves:
      - BR-CAP-CRM-DQ-019-05
    preconditions: Prepare a merge record.
    steps: 'As the application, delete, truncate or move it between workspaces.'
    expected: Every attempted mutation is refused.
    negative: true
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - TST-CRM-DQ-181
    provenance: test
    source: >-
      services-crm:modules/merges/tests/integration/db/record-merges.table.integration.spec.js#may
      not erase a merge, which holds the only copy left of the records it
      deleted
    category: invariant
    execution_sources:
      - >-
        services-crm:modules/merges/tests/integration/db/record-merges.table.integration.spec.js#may
        not erase a merge, which holds the only copy left of the records it
        deleted
      - >-
        services-crm:modules/merges/tests/integration/db/record-merges.table.integration.spec.js#may
        not truncate the table, which would erase every tenant’s merges at once
      - >-
        services-crm:modules/merges/tests/integration/db/record-merges.table.integration.spec.js#may
        not move a merge into another tenant, the policy refusing the statement
  - id: ATS-CRM-DQ-019-06
    title: Record readers receive appropriately restricted lineage
    level: api
    proves:
      - BR-CAP-CRM-DQ-019-07
      - BR-CAP-CRM-DQ-019-08
    preconditions: >-
      Prepare a contact reader without merge management and an organization-only
      reader.
    steps: Read a contact's history and one outcome.
    expected: >-
      The contact reader sees history and field outcomes without login actions,
      carried decisions or checks; the other reader is denied.
    negative: true
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - TST-CRM-DQ-183
      - TST-CRM-DQ-181
    provenance: test
    source: >-
      services-crm:modules/merges/tests/e2e/merged-from-history.e2e.spec.js#answers
      the reader the survivor’s merged-from history, naming the merge and the
      record it absorbed
    category: permission
    execution_sources:
      - >-
        services-crm:modules/merges/tests/e2e/merged-from-history.e2e.spec.js#answers
        the reader the survivor’s merged-from history, naming the merge and the
        record it absorbed
      - >-
        services-crm:modules/merges/tests/e2e/merged-from-history.e2e.spec.js#answers
        the reader the merge’s outcome and the absorbed record as it was
      - >-
        services-crm:modules/merges/tests/integration/services/merges/merged-from-history.integration.spec.js#leaves
        what only merge management reads out of a reader’s details
      - >-
        services-crm:modules/merges/tests/e2e/merged-from-history.e2e.spec.js#refuses
        a reader of organizations a contact’s merged-from history
      - >-
        services-crm:modules/merges/tests/integration/services/merges/merged-from-history.integration.spec.js#refuses
        a merge that did not make this record, as not found
  - id: ATS-CRM-DQ-019-07
    title: Console history connects summaries and outcomes
    level: browser
    proves:
      - BR-CAP-CRM-DQ-019-09
    preconditions: Prepare several completed merges.
    steps: 'Filter Recently Merged, open details and follow a record history entry.'
    expected: >-
      Attribution and participants accompany retained, moved and discarded
      values, and history links open their merge.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - TST-CRM-DQ-176
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/merging/CRM-ACC-0266.spec.ts#CRM-ACC-0266
    category: permission
    execution_sources:
      - >-
        react-console:acceptance/crm/playwright/journeys/merging/CRM-ACC-0266.spec.ts#CRM-ACC-0266
      - >-
        react-console:acceptance/crm/playwright/journeys/merging/CRM-ACC-0253.spec.ts#CRM-ACC-0253
  - id: ATS-CRM-DQ-019-08
    title: An application cannot erase the only retained original
    category: invariant
    level: api
    proves:
      - INV-DOM-CRM-DQ-004-10
    preconditions: >-
      A completed merge with absorbed originals and the ordinary application
      role.
    steps: Attempt to delete the merge row.
    expected: The row remains and the operation is refused.
    negative: false
    data_needs: >-
      Records, versions and caller contexts owned by the run; transaction
      failure injection when the invariant concerns rollback.
    bound_to:
      - TST-CRM-DQ-181
    source: >-
      services-crm:modules/merges/tests/integration/db/record-merges.table.integration.spec.js#may
      not erase a merge, which holds the only copy left of the records it
      deleted
    design_sources:
      - DOM-CRM-DQ-004
    execution_sources:
      - >-
        services-crm:modules/merges/tests/integration/db/record-merges.table.integration.spec.js#may
        not erase a merge, which holds the only copy left of the records it
        deleted
    provenance: test
  - id: ATS-CRM-DQ-019-09
    title: Privacy removal preserves a minimal attributed outcome
    category: rule
    level: api
    proves:
      - BR-CAP-CRM-DQ-019-06
    preconditions: >-
      A completed merge with personal values in originals and discarded
      outcomes, plus an authorized privacy request.
    steps: >-
      Remove the requested person’s original values, then inspect history and
      retained non-personal merge metadata.
    expected: >-
      Requested personal values are unavailable while minimal attribution
      remains. This proposed obligation is not implemented by the pinned suites.
    negative: true
    data_needs: Run-owned records and caller permissions that distinguish the two cases.
    source: FND-CRM-DQ-010
    design_sources:
      - CAP-CRM-DQ-019
    bound_to: []
    provenance: proposed
    execution_sources: []
  - id: ATS-CRM-DQ-019-10
    title: History and workload retain the same committed outcome
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-DQ-019-01
      - BR-CAP-CRM-DQ-019-02
      - BR-CAP-CRM-DQ-019-03
      - BR-CAP-CRM-DQ-019-04
      - BR-CAP-CRM-DQ-019-05
      - BR-CAP-CRM-DQ-019-07
      - BR-CAP-CRM-DQ-019-08
      - BR-CAP-CRM-DQ-019-09
      - BR-CAP-CRM-DQ-019-06
    exercises:
      - CAP-CRM-DQ-019
      - CAP-CRM-DQ-011
      - CAP-CRM-DQ-018
      - CAP-CRM-ENT-016
    workflow_sources:
      - WF-CRM-DQ-006
      - WF-CRM-DQ-009
    preconditions: >-
      Run-owned contact and organization records, the relevant staff permissions
      and the related state described by the sequence.
    steps: >-
      Complete a merge, read it through the survivor and an alias, inspect
      record history as a reader and compare the recent-merge overview.
    expected: >-
      Lineage, attribution and the recent count agree; restricted management
      details remain unavailable to the record-only reader.
    negative: false
    data_needs: >-
      An isolated workspace with related records and fixed timestamps; owned
      participant failure injection where requested.
    source: >-
      CAP-CRM-DQ-019; CAP-CRM-DQ-011; CAP-CRM-DQ-018; CAP-CRM-ENT-016;
      WF-CRM-DQ-006; WF-CRM-DQ-009
    note: >-
      This cumulative seam scenario remains proposed until one executable
      sequence establishes all of its outcomes.
    bound_to: []
    provenance: proposed
    workflow_coverage_note: >-
      The workflows identify the handoffs under review. Separate assertions
      leave recovery and failure ordering unproved; the capability coverage
      finding records that limit.
    execution_sources: []
evidence:
  - repository: services-crm
    source_sha: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
    paths:
      - modules/merges/tests/e2e/merged-from-history.e2e.spec.js
      - modules/merges/tests/e2e/merges.e2e.spec.js
      - >-
        modules/merges/tests/integration/db/record-merges.table.integration.spec.js
      - >-
        modules/merges/tests/integration/services/merges/merge-outcome.integration.spec.js
      - >-
        modules/merges/tests/integration/services/merges/merged-from-history.integration.spec.js
      - >-
        modules/merges/tests/integration/services/merges/tenant-merge-history.integration.spec.js
    note: >-
      Bindings identify authored proof; empty bindings remain proposed and
      findings record known limitations.
  - repository: react-console
    source_sha: baf6dae382d6f41dce976c7f848667ccc37e076f
    paths:
      - acceptance/crm/playwright/journeys/merging/CRM-ACC-0253.spec.ts
      - acceptance/crm/playwright/journeys/merging/CRM-ACC-0266.spec.ts
    note: >-
      Bindings identify authored proof; empty bindings remain proposed and
      findings record known limitations.
coverage:
  rule: covered
  transition: 'gap: FND-CRM-DQ-070'
  validation: 'gap: FND-CRM-DQ-070'
  permission: covered
  edge: 'gap: FND-CRM-DQ-070'
  failure: 'gap: FND-CRM-DQ-070'
  boundary: covered
  concurrency: 'gap: FND-CRM-DQ-070'
  invariant: covered
  interaction: covered
coverage_notes:
  transition: >-
    No complete scenario currently isolates this category; the finding lists the
    remaining proof obligation.
  validation: >-
    No complete scenario currently isolates this category; the finding lists the
    remaining proof obligation.
  edge: >-
    No complete scenario currently isolates this category; the finding lists the
    remaining proof obligation.
  failure: >-
    No complete scenario currently isolates this category; the finding lists the
    remaining proof obligation.
  concurrency: >-
    No complete scenario currently isolates this category; the finding lists the
    remaining proof obligation.
permission_coverage:
  - key: crm.merges.read
    scenario_ids:
      - ATS-CRM-DQ-019-06
      - ATS-CRM-DQ-019-07
    finding: FND-CRM-DQ-070
  - key: crm.contacts.read
    scenario_ids:
      - ATS-CRM-DQ-019-06
      - ATS-CRM-DQ-019-07
    finding: FND-CRM-DQ-070
  - key: crm.organizations.read
    scenario_ids:
      - ATS-CRM-DQ-019-06
      - ATS-CRM-DQ-019-07
    finding: FND-CRM-DQ-070
proof_matrix:
  - rule: BR-CAP-CRM-DQ-019-01
    scenarios:
      - ATS-CRM-DQ-019-01
      - ATS-CRM-DQ-019-10
  - rule: BR-CAP-CRM-DQ-019-02
    scenarios:
      - ATS-CRM-DQ-019-02
      - ATS-CRM-DQ-019-10
  - rule: BR-CAP-CRM-DQ-019-03
    scenarios:
      - ATS-CRM-DQ-019-03
      - ATS-CRM-DQ-019-10
  - rule: BR-CAP-CRM-DQ-019-04
    scenarios:
      - ATS-CRM-DQ-019-04
      - ATS-CRM-DQ-019-10
  - rule: BR-CAP-CRM-DQ-019-05
    scenarios:
      - ATS-CRM-DQ-019-05
      - ATS-CRM-DQ-019-10
  - rule: BR-CAP-CRM-DQ-019-06
    scenarios:
      - ATS-CRM-DQ-019-09
      - ATS-CRM-DQ-019-10
  - rule: BR-CAP-CRM-DQ-019-07
    scenarios:
      - ATS-CRM-DQ-019-06
      - ATS-CRM-DQ-019-10
  - rule: BR-CAP-CRM-DQ-019-08
    scenarios:
      - ATS-CRM-DQ-019-06
      - ATS-CRM-DQ-019-10
  - rule: BR-CAP-CRM-DQ-019-09
    scenarios:
      - ATS-CRM-DQ-019-07
      - ATS-CRM-DQ-019-10
interaction_coverage:
  related:
    - CAP-CRM-DQ-011
    - CAP-CRM-DQ-018
    - CAP-CRM-ENT-016
  workflow_sources:
    - WF-CRM-DQ-006
    - WF-CRM-DQ-009
  scenarios:
    - ATS-CRM-DQ-019-10
---

# Inspect merge outcomes and attribution: Capability Test Specification

## Coverage

The rule matrix names the authored checks. A covered category means that a scenario exists; it does not report a passing execution. The coverage notes and findings identify missing checks, while execution sources retain the exact assertions inspected.

| Required Rule | Scenarios |
|---|---|
| `BR-CAP-CRM-DQ-019-01` | `ATS-CRM-DQ-019-01`, `ATS-CRM-DQ-019-10` |
| `BR-CAP-CRM-DQ-019-02` | `ATS-CRM-DQ-019-02`, `ATS-CRM-DQ-019-10` |
| `BR-CAP-CRM-DQ-019-03` | `ATS-CRM-DQ-019-03`, `ATS-CRM-DQ-019-10` |
| `BR-CAP-CRM-DQ-019-04` | `ATS-CRM-DQ-019-04`, `ATS-CRM-DQ-019-10` |
| `BR-CAP-CRM-DQ-019-05` | `ATS-CRM-DQ-019-05`, `ATS-CRM-DQ-019-10` |
| `BR-CAP-CRM-DQ-019-06` | `ATS-CRM-DQ-019-09`, `ATS-CRM-DQ-019-10` |
| `BR-CAP-CRM-DQ-019-07` | `ATS-CRM-DQ-019-06`, `ATS-CRM-DQ-019-10` |
| `BR-CAP-CRM-DQ-019-08` | `ATS-CRM-DQ-019-06`, `ATS-CRM-DQ-019-10` |
| `BR-CAP-CRM-DQ-019-09` | `ATS-CRM-DQ-019-07`, `ATS-CRM-DQ-019-10` |

## Interactions With Related Capabilities

Complete a merge, read it through the survivor and an alias, inspect record history as a reader and compare the recent-merge overview.

These sequences test the handoffs named in the interaction coverage record. A proposed sequence remains unbound until an executable run checks its combined outcome; component assertions alone leave that obligation open.
