---
id: ATS-CRM-REG-009
scope: CAP-CRM-REG-009
product_area: crm
module: regions
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-CRM-REG-009-01
    title: Overrides preserve manual exceptions
    level: api
    proves:
      - BR-CAP-CRM-REG-009-01
      - AS-JNY-CRM-REG-003-01
    preconditions: A contact and organization are held in the first region.
    steps: Move their deciding addresses into the second region.
    expected: Both retain the held region.
    negative: false
    data_needs: A pair of CRM records.
    bound_to:
      - TST-CRM-REG-058
      - TST-CRM-REG-020
      - TST-CRM-REG-029
      - TST-CRM-REG-063
    provenance: test
    source: >-
      services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#manual
      regions and the override › never changes the region of a contact that overrides automatic
      assignment
    category: invariant
    test_assertions:
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#manual
        regions and the override › never changes the region of a contact that overrides automatic
        assignment
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#manual
        regions and the override › never changes the region of an organization that overrides automatic
        assignment
      - 'react-console:acceptance/crm/playwright/journeys/contacts/CRM-ACC-0023.spec.ts#CRM-ACC-0023'
      - 'react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0120.spec.ts#CRM-ACC-0120'
      - >-
        services-crm:modules/regions/tests/legacy/rolodex-regions/tests/unit/logic/assign-region.unit.spec.js#Address
        Region › Assign Region › should do nothing if region assignment is overriden forthis record
  - id: ATS-CRM-REG-009-02
    title: Manual placement without override follows changed input
    level: api
    proves:
      - BR-CAP-CRM-REG-009-02
    preconditions: A contact has a manual region without an override.
    steps: 'Save an unrelated field, then change the deciding address.'
    expected: The first save preserves placement and the address change permits reassignment.
    negative: false
    data_needs: A single contact record.
    bound_to:
      - TST-CRM-REG-058
    provenance: test
    source: >-
      services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#manual
      regions and the override › keeps a manual region while the deciding address is unchanged
    category: rule
    test_assertions:
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#manual
        regions and the override › keeps a manual region while the deciding address is unchanged
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#manual
        regions and the override › replaces a manual region when the deciding address changes
  - id: ATS-CRM-REG-009-03
    title: Releasing an override uses the current address
    level: api
    proves:
      - BR-CAP-CRM-REG-009-03
      - AS-JNY-CRM-REG-003-02
    preconditions: A contact and organization moved while overridden.
    steps: Disable their overrides.
    expected: Both are reconciled against their present deciding addresses.
    negative: false
    data_needs: A pair of CRM records.
    bound_to:
      - TST-CRM-REG-058
    provenance: test
    source: >-
      services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#manual
      regions and the override › a contact moved while overridden, then switched back to automatic › kept
      the region while the override was on, so the move was left undecided
    category: transition
    test_assertions:
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#manual
        regions and the override › a contact moved while overridden, then switched back to automatic ›
        kept the region while the override was on, so the move was left undecided
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#manual
        regions and the override › a contact moved while overridden, then switched back to automatic ›
        assigns the region of the address it moved to once the override is off
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#manual
        regions and the override › an organization moved while overridden, then switched back to
        automatic › assigns the region of the address it moved to once the override is off
  - id: ATS-CRM-REG-009-04
    title: Foreign regions cannot be saved on records
    level: api
    proves:
      - BR-CAP-CRM-REG-009-05
    preconditions: Two workspaces contain separate regional catalogues.
    steps: Set local contact and organization regions to a foreign region.
    expected: Both saves fail and preserve the previous records.
    negative: true
    data_needs: Two distinct customer workspaces.
    bound_to:
      - TST-CRM-REG-058
      - TST-CRM-REG-049
      - TST-CRM-REG-020
    provenance: test
    source: >-
      services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#refusals
      › refuses a contact naming a region the tenant does not have
    category: boundary
    test_assertions:
      - >-
        services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#refusals
        › refuses a contact naming a region the tenant does not have
      - >-
        services-crm:modules/regions/tests/integration/db/regions.table.integration.spec.js#references ›
        refuses a contact naming a region its tenant does not have
      - >-
        services-crm:modules/regions/tests/integration/db/regions.table.integration.spec.js#references ›
        refuses an organization naming a region its tenant does not have
      - 'react-console:acceptance/crm/playwright/journeys/contacts/CRM-ACC-0023.spec.ts#CRM-ACC-0023'
  - id: ATS-CRM-REG-009-05
    title: A held exception survives both automatic processing paths
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-REG-009-01
      - BR-CAP-CRM-REG-009-03
      - BR-CAP-CRM-REG-011-06
    preconditions: An addressed contact has a manual region protected by an override and another geographic target.
    steps: >-
      Move the deciding address, deliver assignment, run recalculation, then release the override and
      deliver its reaction.
    expected: >-
      The hold preserves the manual region through both processing paths and release follows the current
      changed address.
    negative: false
    data_needs: An addressed contact has a manual region protected by an override and another geographic target.
    bound_to: []
    provenance: proposed
    source: WF-CRM-REG-001
    exercises:
      - CAP-CRM-REG-008
      - CAP-CRM-REG-009
      - CAP-CRM-REG-011
  - id: ATS-CRM-REG-009-06
    title: Releasing an unchanged hold preserves its former selection
    category: transition
    level: api
    proves:
      - BR-CAP-CRM-REG-009-02
      - BR-CAP-CRM-REG-009-03
    preconditions: 'A contact remembers an address, then holds a different manual region without changing that address.'
    steps: 'Release the override and deliver its reaction, then move the deciding address and deliver again.'
    expected: >-
      Release keeps the value while its remembered input matches; the later changed input becomes
      eligible for assignment.
    negative: false
    data_needs: 'A contact remembers an address, then holds a different manual region without changing that address.'
    bound_to: []
    provenance: proposed
    source: STATE-CRM-REG-003
evidence:
  - >-
    services-crm: Examined the pinned regional implementation, its declared constraints and the
    supporting records.
  - 'react-console: Examined the pinned regional configuration surfaces and their available test evidence.'
  - >-
    services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js
  - 'react-console:acceptance/crm/playwright/journeys/contacts/CRM-ACC-0023.spec.ts'
  - 'react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0120.spec.ts'
  - 'services-crm:modules/regions/tests/legacy/rolodex-regions/tests/unit/logic/assign-region.unit.spec.js'
  - 'services-crm:modules/regions/tests/integration/db/regions.table.integration.spec.js'
coverage:
  rule: covered
  transition: covered
  validation: 'gap: FND-CRM-REG-054'
  permission: 'gap: FND-CRM-REG-054'
  edge: 'gap: FND-CRM-REG-054'
  failure: 'gap: FND-CRM-REG-054'
  boundary: covered
  concurrency: 'gap: FND-CRM-REG-054'
  invariant: covered
  interaction: covered
---

# Preserve a deliberate regional exception: Capability Test Specification

## Coverage

Each row links a required rule to its authored proof. A covered category records a specification; executable and remaining variant gaps stay in the finding register.

| Rule | Proved By |
|---|---|
| `BR-CAP-CRM-REG-009-01` | `ATS-CRM-REG-009-01`, `ATS-CRM-REG-009-05` |
| `BR-CAP-CRM-REG-009-02` | `ATS-CRM-REG-009-02`, `ATS-CRM-REG-009-06` |
| `BR-CAP-CRM-REG-009-03` | `ATS-CRM-REG-009-03`, `ATS-CRM-REG-009-05`, `ATS-CRM-REG-009-06` |
| `BR-CAP-CRM-REG-009-05` | `ATS-CRM-REG-009-04` |

## Interactions With Related Capabilities

A held exception survives both automatic processing paths. The interaction scenario connects keep placements aligned with address changes, apply the current policy across existing records with this capability. Cross-workflow expectations are proposed where no executable binding is present.
