Skip to content

CAP-CRM-DQ-016Execute the approved merge atomically

Markdown

CAP-CRM-DQ-016

Execute the approved merge atomically

Markdown
  • DocumentDraft
  • Product intentConfirmed
  • ImplementationObserved

KindCapabilityProduct areaCRMModuleDuplicate Review and Record MergingRevision1

Read atservices-crm a8d1364freact-console baf6dae3

The Formal Contract

The narrative above explains; the sections below are authoritative — the rules, scenarios and tests this document binds.

Outcomes
Record and participant changes commit together or roll back together.Material changes after approval require renewed review.Repeated submissions and overlapping work cannot absorb one identity twice.
Surfaces
consoleapijob
Constraints
Rows changed by execution remain locked through commit, so simultaneous ordinary edits wait for the transaction.
Intent sources
services-crm:docs/merging/decisions.md#D1 (decided 2026-10-11: option 1)services-crm:docs/milestones/CRM-M4-duplicates-and-merge.md#D-31services-crm:docs/merging/decisions.md#D7 (decided 2026-10-12), D8 (decided 2026-10-12), D9 and D10 (decided 2026-10-14)services-crm:docs/merging/experience/functional-requirements.md#EXE-1 to EXE-7, CFM-1 to CFM-5, INT-3, INT-4 (package approved by Andrew 2026-10-13)

Controls

34 controls apply, from the corpus control catalogue.

TC-AVL-004 TC-AZ-001 TC-AZ-002 TC-AZ-003 TC-AZ-004 TC-AZ-005 TC-AZ-006 TC-DAT-001 TC-DAT-002 TC-DAT-003 TC-DAT-004 TC-IAM-001 TC-IAM-002 TC-IAM-004 TC-IAM-005 TC-IAM-006 TC-LOG-001 TC-LOG-002 TC-LOG-003 TC-LOG-004 TC-LOG-005 TC-MON-001 TC-MON-002 TC-PI-001 TC-PI-002 TC-PI-003 TC-PI-004 TC-PI-005 TC-PRV-001 TC-PRV-002 TC-PRV-003 TC-TEN-001 TC-TEN-002 TC-TEN-003

Permissions

KeyChecked atScope
crm.contacts.mergeapitenant
crm.organizations.mergeapitenant
crm.merges.readapitenant

Business Rules

15 rules, 15 to be proved before approval. A rule's product intent is derived from its origin: 15 confirmed by a product decision, the rest inheriting this capability's confirmed.

IdRuleKindEnforced atProvenance
01must prove
Confirmed
Execution rejects open required questions and blockers with their details, and accepts defaulted recommendations only when the request explicitly accepts them.
origin: services-crm:docs/merging/README.md#Status (architecture and plan approved by Andrew 2026-10-11)
no proof recorded yet
validationapi, servicetest
services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#names the conflict that is still open, so a console can take the reader to it
02must prove
Confirmed
Before queueing, execution compares the current preview with the stored last-shown plan and rejects participant, dependent-row identity/version or chosen-source changes as stale with refreshed details, including requests without a submitted plan fingerprint.
no proof recorded yet
validationservicetest
services-crm:modules/merges/tests/integration/services/merges/approval-binding.integration.spec.js#refuses an execution that submits no hash too, because the stored plan is the one last shown
03must prove
Confirmed
Presentation wording, labels, duration estimates, survivor suggestions and carried dismissals do not affect approval binding.
no proof recorded yet
policyservicetest
services-crm:modules/merges/tests/integration/services/merges/lookup-labels.integration.spec.js#answers the same material hash, a name being no part of what staff are approving
04must prove
Confirmed
Duplicate or simultaneous execution submissions return the same merge and job, with later requests reporting no new creation.
no proof recorded yet
invariantservice, databasetest
05must prove
Confirmed
A durable background job exposes plan-check, record-lock, participant-change and merge-commit steps; merge and job creation commit together, and reconciliation starts or fails jobs whose start was lost.
origin: services-crm:docs/merging/decisions.md#D9 (decided 2026-10-14)
no proof recorded yet
lifecycleservicetest
services-crm:modules/merges/tests/integration/services/jobs/job-reconciliation.integration.spec.js#settles the job failed, rather than leaving it in flight for ever
06must prove
Confirmed
Execution re-plans under lock in one transaction and rolls back all changes on stale data, already-merged participants, blockers, participant refusals, ordinary survivor validation or internal failure, recording the reason.
origin: services-crm:docs/merging/decisions.md#D1 (decided 2026-10-11: option 1)
no proof recorded yet
invariantservice, databasetest
services-crm:modules/merges/tests/integration/services/merges/approval-binding.integration.spec.js#fails the merge Stale inside its transaction rather than moving a task nobody approved
07must prove
Confirmed
Of overlapping merges sharing a participant, only one succeeds; the other reports already merged with record names and numbers, preventing two survivor destinations.
origin: services-crm:docs/merging/README.md#Status (architecture and plan approved by Andrew 2026-10-11)
no proof recorded yet
invariantservice, databasetest
08must prove
Confirmed
A record or owned detail locked against deletion also blocks merging.
no proof recorded yet
validationservicetest
09must prove
Confirmed
Merges above 100,000 related writes are rejected; those above 10,000 are classified large and warn about moved records, estimated duration and editing waits.
origin: services-crm:docs/merging/decisions.md#D7 (decided 2026-10-12) and D10 (decided 2026-10-14)
no proof recorded yet
validationservicetest
services-crm:modules/merges/tests/unit/services/planning/merge-decisions.spec.js#blocks a merge above the row ceiling of this release (decision D7)
10must prove
Confirmed
Failure restores the plan's earlier status and decisions; another execution creates a new attempt while preserving the failed merge in history.
no proof recorded yet
lifecycleservicetest
services-crm:modules/merges/tests/integration/services/merges/merge-settlement.integration.spec.js#returns the plan to the status it had before it was executed, rather than leaving it executing
11must prove
Confirmed
Workflow retries apply only to transient errors such as lock waits, excluding business refusals.
no proof recorded yet
policyserviceobserved
12must prove
Confirmed
Every successful participant record receives an audit merge pointer naming the merge, survivor and participant role within the merge transaction.
origin: services-crm:docs/merging/decisions.md#D8 (decided 2026-10-12)
no proof recorded yet
lifecycleservicetest
services-crm:modules/merges/tests/integration/services/merges/merged-from-history.integration.spec.js#says who merged which record into which, and when: the merge pointer
13must prove
Confirmed
After a contact merge commits, a business event announces the survivor and absorbed identities to subscribers; organization merges publish no corresponding event.
no proof recorded yet
lifecycleservicetest
services-crm:modules/merges/tests/e2e/business-events.e2e.spec.js#hands the subscriber the envelope of crm.contact.merged, about the survivor, in the merge’s tenant
14must prove
Confirmed
Console confirmation identifies the survivor and deleted records, states irreversibility, labels the outcome and polls every second for 30 seconds then every five seconds, while allowing staff to leave.
no proof recorded yet
policyconsoletest
15must prove
Confirmed
Estimated duration is the rounded sum of half a second and 1.7 milliseconds per estimated touched row, with negative row counts treated as zero and a minimum of one second.
no proof recorded yet
calculationserviceobserved

Scenarios

IdGivenWhenThenProvenance
01An approved preview exists before a task is added to an absorbed record.The administrator confirms execution.The stale response names the added task; renewed review allows it to move.test
services-crm:modules/merges/tests/integration/services/merges/approval-binding.integration.spec.js#executes once the plan is looked at again and confirmed, moving the task the reviewer saw
02Two administrators submit overlapping merges and one repeats confirmation.The jobs attempt execution.One merge succeeds, the conflicting merge reports already merged and repeated confirmation creates no extra attempt.test

Edge Cases

IdGivenWhenThenProvenance
03A merge has a durable job whose execution never starts.Job reconciliation settles the lost work.The merge records internal failure and its plan becomes available for another attempt.test
services-crm:modules/merges/tests/integration/services/jobs/job-reconciliation.integration.spec.js#returns the plan to the status it had before it was executed, so it can be executed again (gap G4)

The Markdown files under specs/ in rhythmsoftware/rhythm-v2-docs are the canonical source of truth. This reader is a generated, read-only projection of them.