---
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
finding_evidence:
  - finding: FND-CRM-REG-001
    source:
      - 'services-crm:modules/regions/services/persistence/regions.ts:updateRegion'
      - >-
        services-crm:modules/regions/services/persistence/region-assignment-settings.ts:noteRuleRegionDeactivated
      - 'services-crm:modules/regions/services/region-assignment/region-matching.ts:matchRegionRule'
      - 'react-console:lib/configuration/regions-analysis.ts:analyzeRules'
      - 'react-console:acceptance/crm/inventory/business-rules.json#RUL-CRM-CFG-042'
      - 'react-console:acceptance/crm/journeys/configuration/CRM-ACC-0361.json (open_decisions)'
  - finding: FND-CRM-REG-002
    source:
      - 'services-crm:modules/regions/aws/api/regions.routes.ts:toWriteInput'
      - 'services-crm:lib/db/system-values.ts:clientSystemColumnsFromWire'
      - 'services-crm:modules/regions/services/persistence/regions.ts:updateRegionRow, deleteRegionRow'
      - 'react-console:lib/configuration/regions.ts:carriedThrough'
      - 'services-crm:docs/milestones/CRM-M3-crm-configuration.md#D-08'
  - finding: FND-CRM-REG-003
    source:
      - 'services-crm:modules/regions/services/persistence/regions.ts:updateRegionRow'
      - >-
        services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings
      - 'services-crm:modules/regions/aws/api/regions.routes.ts:updateRegionAssignmentSettings'
      - 'services-crm:docs/milestones/CRM-M1-contacts-and-organizations.md#D-05'
  - finding: FND-CRM-REG-004
    source:
      - >-
        react-console:lib/authz/backend-aliases.ts:crm.settings.view, crm.settings.manage,
        maintenance.operations.run
      - 'react-console:components/regions/use-regions.ts:useRegionsPermissions'
      - 'react-console:acceptance/crm/journeys/security/CRM-ACC-0575.json'
      - 'react-console:acceptance/crm/inventory/capabilities.json#CAP-CRM-CFG-017 (gaps)'
  - finding: FND-CRM-REG-005
    source:
      - 'react-console:lib/configuration/regions.ts:addressTypesFor'
      - 'services-crm:modules/regions/db/region-assignment-settings.table.ts (header)'
      - >-
        services-crm:modules/regions/tests/integration/services/persistence/region-assignment-settings.integration.spec.js#the
        capability › takes a contact address type marked for organizations, applies_to being a guide and
        not a rule
  - finding: FND-CRM-REG-006
    source:
      - 'services-crm:modules/regions/aws/api/regions.routes.ts (header)'
      - 'react-console:lib/configuration/regions.ts:createRegionsApi'
      - 'react-console:acceptance/crm/inventory/capabilities.json#CAP-CRM-CFG-016 (gaps)'
      - >-
        services-crm:docs/migrations/crm-regions/README.md#2026-10-15 — Final acceptance (console
        follow-ups) (Andrew approved 2026-10-15: two tabs, Test an Address dialog, drawers, a read-only
        Assignment Rules tab with its own editor screen and the banner)
  - finding: FND-CRM-REG-007
    source:
      - >-
        services-crm:docs/migrations/crm-regions/README.md#Assignment and recalculation triggers in
        Rolodex 2.0
      - 'services-crm:docs/migrations/crm-regions/README.md#2026-10-11 second pass (item 2)'
      - 'services-crm:modules/regions/aws/logic/regions-api.lambda.ts (header)'
      - 'services-crm:modules/regions/export/region-assignment-settings.dataset.ts (header)'
      - 'react-console:lib/configuration/regions.ts:updateRegion (comment)'
      - >-
        react-console:acceptance/crm/inventory/capabilities.json#CAP-CRM-CFG-016 (gaps: docs-2
        INV-RLX-REG-01)
  - finding: FND-CRM-REG-008
    source:
      - 'services-crm:modules/entities/services/persistence/contacts.ts:readContactRegionAddresses'
      - 'services-crm:modules/entities/services/affiliations/affiliation-date-reconciliation.ts'
      - >-
        services-crm:modules/regions/services/region-assignment/region-assignment.ts:linkedContactRegionAssignmentHandler
  - finding: FND-CRM-REG-009
    source:
      - 'services-crm:modules/regions/services/region-assignment/region-recalculation.ts:recalculateBatch'
      - >-
        services-crm:modules/regions/services/region-assignment/region-assignment.ts:reconcileRegionAssignments
      - >-
        services-crm:modules/entities/services/persistence/contacts.ts:lockContactIdsAfter,
        lockContactRegionTargets
  - finding: FND-CRM-REG-010
    source:
      - 'services-crm:modules/regions/aws/api/regions.routes.ts:regionsRoutes'
      - >-
        services-crm:modules/regions/services/region-assignment/region-recalculation.ts:startRegionRecalculation
      - 'react-console:acceptance/crm/inventory/capabilities.json#CAP-CRM-CFG-017 (gaps)'
      - 'react-console:acceptance/crm/journeys/configuration/CRM-ACC-0360.json (open_decisions)'
  - finding: FND-CRM-REG-011
    source:
      - >-
        services-crm:modules/regions/db/region-assignment-settings.table.ts:regionAssignmentRules
        (lockedCheck)
      - 'services-crm:modules/regions/aws/api/regions.routes.ts:toRuleInput'
      - 'services-crm:modules/regions/services/persistence/region-assignment-settings.ts:ruleRecordOf'
  - finding: FND-CRM-REG-012
    source:
      - 'services-crm:modules/regions/tests/'
      - 'services-crm:tests/unit/regions-authorization.spec.ts'
      - 'react-console:acceptance/crm/playwright/journeys/configuration/CRM-ACC-0361.spec.ts#CRM-ACC-0361'
      - 'react-console:acceptance/crm/playwright/journeys/configuration/CRM-ACC-0364.spec.ts#CRM-ACC-0364'
  - finding: FND-CRM-REG-013
    source:
      - 'react-console:acceptance/crm/journeys/configuration/CRM-ACC-0357.json (automation, execution)'
      - 'react-console:acceptance/crm/journeys/configuration/CRM-ACC-0360.json'
      - 'react-console:acceptance/crm/journeys/contacts/CRM-ACC-0023.json'
      - 'react-console:acceptance/crm/journeys/configuration/CRM-ACC-0361.json'
      - 'react-console:acceptance/crm/playwright/journeys/'
  - finding: FND-CRM-REG-014
    source:
      - >-
        services-crm:modules/regions/services/persistence/region-assignment-settings.ts:regionAssignmentRuleProblems
      - 'services-crm:modules/regions/services/region-assignment/region-matching.ts:matchRegionRule'
      - 'react-console:acceptance/crm/inventory/capabilities.json#CAP-CRM-CFG-016 (open_decisions)'
      - 'react-console:acceptance/crm/journeys/configuration/CRM-ACC-0358.json (open_decisions)'
  - finding: FND-CRM-REG-015
    source:
      - specs/PRODUCT-AREAS.md (MOD-CRM-REG row)
      - 'react-console:components/regions/'
      - 'react-console:lib/configuration/regions.ts'
      - >-
        react-console:app/(console)/console/[tenantId]/configuration/[module]/[area]/assignmentRules/page.tsx
  - finding: FND-CRM-REG-016
    source:
      - specs/crm/ACTORS.md
      - 'services-crm:aws/crm.service.ts:RegionsPermissions'
  - finding: FND-CRM-REG-024
    source:
      - 'services-crm:modules/regions/aws/api/regions.routes.ts:toWriteInput, replaceRequest'
      - 'react-console:lib/configuration/regions.ts:carriedThrough, updateRegion'
      - >-
        rhythm-v2-docs:specs/crm/entities/design/decisions/ADR-CRM-ENT-003-whole-record-saves-carry-the-complete-payload.md
  - finding: FND-CRM-REG-025
    source:
      - 'services-crm:modules/regions/services/persistence/regions.ts'
      - >-
        services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings
      - 'services-crm:docs/record-locks.md#Not covered yet'
      - 'services-crm:docs/milestones/CRM-M3-crm-configuration.md#D-08'
  - finding: FND-CRM-REG-026
    source:
      - >-
        services-crm:modules/regions/services/region-assignment/region-recalculation.ts:startRegionRecalculation,
        runBatch
      - 'services-crm:modules/regions/aws/api/regions.routes.ts:recalculateRegionAssignments'
      - 'react-console:components/regions/recalculation.tsx:useRecalculation (start)'
  - finding: FND-CRM-REG-027
    source:
      - 'services-platform:docs/standards/** (not readable with this job''s credential at ad3f6a65)'
      - >-
        services-crm:modules/regions/services/region-assignment/region-recalculation.ts (queued-work
        standard citation)
  - finding: FND-CRM-REG-028
    source:
      - 'rhythm-v2-docs:specs/CONVENTIONS.md#9.8 Inference Operation (IOP)'
      - specs/crm/regions/MODULE.md
  - finding: FND-CRM-REG-029
    source:
      - specs/crm/RESPONSIBILITIES.md (MOD-CRM-ENT delegates)
      - specs/PRODUCT-AREAS.md (CRM data jobs are not a module)
  - finding: FND-CRM-REG-030
    source:
      - 'services-crm:modules/regions/services/persistence/regions.ts:deleteRegion'
      - >-
        services-crm:modules/regions/services/persistence/region-assignment-settings.ts:deleteRegionAssignmentRule
control_gap_evidence:
  - finding: FND-CRM-REG-041
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
      rhythm-v2-docs: 74bec48899048f6472ba876a4c2f9da463bd071f
    controls:
      - TC-DAT-001
    provenance: observed
    source:
      - 'services-crm:aws/crm.service.ts:crmService.dataClassification'
      - >-
        services-crm:modules/regions/services/region-assignment/region-assignment.ts:reconcileRegionAssignments
  - finding: FND-CRM-REG-042
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
      rhythm-v2-docs: 74bec48899048f6472ba876a4c2f9da463bd071f
    controls:
      - TC-AZ-001
      - TC-LOG-001
      - TC-LOG-002
      - TC-LOG-003
      - TC-PI-005
    provenance: observed
    source:
      - 'services-crm:modules/regions/aws/api/regions.routes.ts:toWriteInput'
      - 'services-crm:modules/regions/services/persistence/regions.ts:updateRegionRow'
      - >-
        services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings
      - 'rhythm-v2-docs:specs/crm/regions/FINDINGS.md#FND-CRM-REG-025'
  - finding: FND-CRM-REG-043
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
      rhythm-v2-docs: 74bec48899048f6472ba876a4c2f9da463bd071f
    controls:
      - TC-PI-003
    provenance: observed
    source:
      - >-
        services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings,insertRule,updateRegionAssignmentRule
  - finding: FND-CRM-REG-044
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
      rhythm-v2-docs: 74bec48899048f6472ba876a4c2f9da463bd071f
    controls:
      - TC-PI-004
    provenance: observed
    source:
      - 'react-console:components/regions/recalculation.tsx:useRecalculation,RecalculationPanel'
  - finding: FND-CRM-REG-045
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      rhythm-v2-docs: 74bec48899048f6472ba876a4c2f9da463bd071f
    controls:
      - TC-PI-004
      - TC-AVL-004
    provenance: observed
    source:
      - 'services-crm:modules/regions/services/region-assignment/region-recalculation.ts:recordFailure'
      - >-
        services-crm:modules/regions/services/persistence/region-recalculations.ts:recordRecalculationFailure
      - 'rhythm-v2-docs:specs/crm/regions/FINDINGS.md#FND-CRM-REG-037'
testing_coverage:
  - finding: FND-CRM-REG-046
    scope: CAP-CRM-REG-001
    categories:
      - permission
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-001-04
      - ATS-CRM-REG-001-09
      - ATS-CRM-REG-001-10
      - ATS-CRM-REG-001-11
    permissions_to_verify:
      - crm.regions.read
      - crm.regions.create
      - crm.regions.update
    transitions_to_verify:
      - STATE-CRM-REG-001
    related:
      - CAP-CRM-REG-002
      - CAP-CRM-REG-013
      - CAP-CRM-REG-014
      - CAP-CRM-REG-015
    source:
      - CAP-CRM-REG-001
      - CAP-CRM-REG-002
      - CAP-CRM-REG-013
      - CAP-CRM-REG-014
      - CAP-CRM-REG-015
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      permission: Each named action key needs an allowed and denied request with unchanged stored state on refusal.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-001
        from: active
        to: active
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/persistence/regions.integration.spec.js#creates
          a region active by default;
          services-crm:modules/regions/services/persistence/regions.ts:insertRegion, updateRegionRow;
          services-crm:modules/regions/aws/api/regions.routes.ts
        coverage: 'gap: FND-CRM-REG-046'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: active
        to: inactive
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegion'
        coverage: 'gap: FND-CRM-REG-046'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: inactive
        to: active
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegion'
        coverage: 'gap: FND-CRM-REG-046'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: inactive
        to: inactive
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegionRow'
        coverage: 'gap: FND-CRM-REG-046'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: active
        to: deleted
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/db/regions.table.integration.spec.js#regions
          table (integration) › references › refuses to delete a region a contact is in, naming what uses
          it; services-crm:modules/regions/services/persistence/regions.ts:deleteRegionRow;
          services-crm:modules/regions/aws/api/regions.routes.ts:deleteRegion
        coverage: 'gap: FND-CRM-REG-046'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: inactive
        to: deleted
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:deleteRegion'
        coverage: 'gap: FND-CRM-REG-046'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-047
    scope: CAP-CRM-REG-002
    categories:
      - rule
      - validation
      - failure
      - boundary
      - concurrency
    missing_rules:
      - BR-CAP-CRM-REG-002-05
    unbound_scenarios:
      - ATS-CRM-REG-002-04
      - ATS-CRM-REG-002-05
      - ATS-CRM-REG-002-07
      - ATS-CRM-REG-002-08
    permissions_to_verify:
      - crm.regions.update
      - crm.regions.delete
    transitions_to_verify:
      - STATE-CRM-REG-001
    related:
      - CAP-CRM-REG-001
      - CAP-CRM-REG-006
      - CAP-CRM-REG-010
    source:
      - CAP-CRM-REG-002
      - CAP-CRM-REG-001
      - CAP-CRM-REG-006
      - CAP-CRM-REG-010
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      rule: Missing required-rule proof.
      validation: Refused inputs need checks that the previous state is preserved.
      failure: A failed dependency needs a checked refusal or recovery outcome.
      boundary: 'Limits, local reference boundaries and exact endpoints need explicit checks.'
      concurrency: Competing writes and read-versus-write timing need explicit checks.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-001
        from: active
        to: active
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/persistence/regions.integration.spec.js#creates
          a region active by default;
          services-crm:modules/regions/services/persistence/regions.ts:insertRegion, updateRegionRow;
          services-crm:modules/regions/aws/api/regions.routes.ts
        coverage: 'gap: FND-CRM-REG-047'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: active
        to: inactive
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegion'
        coverage: 'gap: FND-CRM-REG-047'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: inactive
        to: active
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegion'
        coverage: 'gap: FND-CRM-REG-047'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: inactive
        to: inactive
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegionRow'
        coverage: 'gap: FND-CRM-REG-047'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: active
        to: deleted
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/db/regions.table.integration.spec.js#regions
          table (integration) › references › refuses to delete a region a contact is in, naming what uses
          it; services-crm:modules/regions/services/persistence/regions.ts:deleteRegionRow;
          services-crm:modules/regions/aws/api/regions.routes.ts:deleteRegion
        coverage: 'gap: FND-CRM-REG-047'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: inactive
        to: deleted
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:deleteRegion'
        coverage: 'gap: FND-CRM-REG-047'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-048
    scope: CAP-CRM-REG-003
    categories:
      - permission
      - invariant
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-003-08
      - ATS-CRM-REG-003-09
    permissions_to_verify:
      - crm.regions.read
      - crm.regions.update
    transitions_to_verify:
      - STATE-CRM-REG-002
    related:
      - CAP-CRM-REG-004
      - CAP-CRM-REG-008
      - CAP-CRM-REG-010
    source:
      - CAP-CRM-REG-003
      - CAP-CRM-REG-004
      - CAP-CRM-REG-008
      - CAP-CRM-REG-010
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      permission: Each named action key needs an allowed and denied request with unchanged stored state on refusal.
      invariant: Domain-object consistency across permitted writes needs explicit checks.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-002
        from: never saved
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:lockSettingsRowForRuleWrite
        coverage: 'gap: FND-CRM-REG-048'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: never saved
        to: on and needing recalculation
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings
        coverage: 'gap: FND-CRM-REG-048'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: 'off'
        to: on and needing recalculation
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says a
          recalculation is needed once the rules have been saved and nothing has recalculated
        coverage: 'gap: FND-CRM-REG-048'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and current
        to: on and needing recalculation
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says one is
          needed again as soon as a rule is added;
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings,
          stampRulesChanged, noteRuleRegionDeactivated
        coverage: 'gap: FND-CRM-REG-048'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and needing recalculation
        to: on and current
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says none is
          needed once a recalculation has succeeded against those rules
        coverage: 'gap: FND-CRM-REG-048'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and needing recalculation
        to: 'off'
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › assignment switched off › assigns nothing while assignment is off
        coverage: 'gap: FND-CRM-REG-048'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and current
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:recalculationNeeded
        coverage: 'gap: FND-CRM-REG-048'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: 'off'
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:stampRulesChanged
        coverage: 'gap: FND-CRM-REG-048'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-049
    scope: CAP-CRM-REG-004
    categories:
      - transition
      - permission
      - edge
      - failure
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-004-06
      - ATS-CRM-REG-004-09
      - ATS-CRM-REG-004-10
      - ATS-CRM-REG-004-11
    permissions_to_verify:
      - crm.regions.update
      - crm.regions.read
    transitions_to_verify:
      - STATE-CRM-REG-002
    related:
      - CAP-CRM-REG-003
      - CAP-CRM-REG-005
      - CAP-CRM-REG-006
      - CAP-CRM-REG-007
    source:
      - CAP-CRM-REG-004
      - CAP-CRM-REG-003
      - CAP-CRM-REG-005
      - CAP-CRM-REG-006
      - CAP-CRM-REG-007
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      transition: Complete lifecycle transitions and their guards need explicit checks.
      permission: Each named action key needs an allowed and denied request with unchanged stored state on refusal.
      edge: 'Absent configuration, empty results and unusual valid inputs need explicit checks.'
      failure: A failed dependency needs a checked refusal or recovery outcome.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-002
        from: never saved
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:lockSettingsRowForRuleWrite
        coverage: 'gap: FND-CRM-REG-049'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: never saved
        to: on and needing recalculation
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings
        coverage: 'gap: FND-CRM-REG-049'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: 'off'
        to: on and needing recalculation
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says a
          recalculation is needed once the rules have been saved and nothing has recalculated
        coverage: 'gap: FND-CRM-REG-049'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and current
        to: on and needing recalculation
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says one is
          needed again as soon as a rule is added;
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings,
          stampRulesChanged, noteRuleRegionDeactivated
        coverage: 'gap: FND-CRM-REG-049'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and needing recalculation
        to: on and current
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says none is
          needed once a recalculation has succeeded against those rules
        coverage: 'gap: FND-CRM-REG-049'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and needing recalculation
        to: 'off'
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › assignment switched off › assigns nothing while assignment is off
        coverage: 'gap: FND-CRM-REG-049'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and current
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:recalculationNeeded
        coverage: 'gap: FND-CRM-REG-049'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: 'off'
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:stampRulesChanged
        coverage: 'gap: FND-CRM-REG-049'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-050
    scope: CAP-CRM-REG-005
    categories:
      - permission
      - failure
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-005-02
      - ATS-CRM-REG-005-08
      - ATS-CRM-REG-005-09
    permissions_to_verify:
      - crm.regions.read
      - crm.regions.update
    transitions_to_verify:
      - STATE-CRM-REG-002
    related:
      - CAP-CRM-REG-004
      - CAP-CRM-REG-006
      - CAP-CRM-REG-010
    source:
      - CAP-CRM-REG-005
      - CAP-CRM-REG-004
      - CAP-CRM-REG-006
      - CAP-CRM-REG-010
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      permission: Each named action key needs an allowed and denied request with unchanged stored state on refusal.
      failure: A failed dependency needs a checked refusal or recovery outcome.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-002
        from: never saved
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:lockSettingsRowForRuleWrite
        coverage: 'gap: FND-CRM-REG-050'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: never saved
        to: on and needing recalculation
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings
        coverage: 'gap: FND-CRM-REG-050'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: 'off'
        to: on and needing recalculation
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says a
          recalculation is needed once the rules have been saved and nothing has recalculated
        coverage: 'gap: FND-CRM-REG-050'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and current
        to: on and needing recalculation
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says one is
          needed again as soon as a rule is added;
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings,
          stampRulesChanged, noteRuleRegionDeactivated
        coverage: 'gap: FND-CRM-REG-050'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and needing recalculation
        to: on and current
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says none is
          needed once a recalculation has succeeded against those rules
        coverage: 'gap: FND-CRM-REG-050'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and needing recalculation
        to: 'off'
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › assignment switched off › assigns nothing while assignment is off
        coverage: 'gap: FND-CRM-REG-050'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and current
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:recalculationNeeded
        coverage: 'gap: FND-CRM-REG-050'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: 'off'
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:stampRulesChanged
        coverage: 'gap: FND-CRM-REG-050'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-051
    scope: CAP-CRM-REG-006
    categories:
      - validation
      - concurrency
      - invariant
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-006-10
      - ATS-CRM-REG-006-12
      - ATS-CRM-REG-006-15
    permissions_to_verify: []
    transitions_to_verify: []
    related:
      - CAP-CRM-REG-002
      - CAP-CRM-REG-004
      - CAP-CRM-REG-007
      - CAP-CRM-REG-008
      - CAP-CRM-REG-011
    source:
      - CAP-CRM-REG-006
      - CAP-CRM-REG-002
      - CAP-CRM-REG-004
      - CAP-CRM-REG-007
      - CAP-CRM-REG-008
      - CAP-CRM-REG-011
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      validation: Refused inputs need checks that the previous state is preserved.
      concurrency: Competing writes and read-versus-write timing need explicit checks.
      invariant: Domain-object consistency across permitted writes needs explicit checks.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks: []
  - finding: FND-CRM-REG-052
    scope: CAP-CRM-REG-007
    categories:
      - failure
      - concurrency
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-007-06
      - ATS-CRM-REG-007-07
      - ATS-CRM-REG-007-08
    permissions_to_verify:
      - crm.regions.read
    transitions_to_verify: []
    related:
      - CAP-CRM-REG-004
      - CAP-CRM-REG-006
    source:
      - CAP-CRM-REG-007
      - CAP-CRM-REG-004
      - CAP-CRM-REG-006
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      failure: A failed dependency needs a checked refusal or recovery outcome.
      concurrency: Competing writes and read-versus-write timing need explicit checks.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks: []
  - finding: FND-CRM-REG-053
    scope: CAP-CRM-REG-008
    categories:
      - validation
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-008-07
      - ATS-CRM-REG-008-12
      - ATS-CRM-REG-008-15
      - ATS-CRM-REG-008-16
    permissions_to_verify: []
    transitions_to_verify:
      - STATE-CRM-REG-003
    related:
      - CAP-CRM-REG-003
      - CAP-CRM-REG-006
      - CAP-CRM-REG-009
      - CAP-CRM-REG-011
    source:
      - CAP-CRM-REG-008
      - CAP-CRM-REG-003
      - CAP-CRM-REG-006
      - CAP-CRM-REG-009
      - CAP-CRM-REG-011
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      validation: Refused inputs need checks that the previous state is preserved.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-003
        from: unplaced
        to: set by hand
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › initial assignment › keeps a region the client sends with a contact
          that has no address (nothing decides it)
        coverage: 'gap: FND-CRM-REG-053'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: unplaced
        to: placed by the rules
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › initial assignment › gives a contact created with a matching address
          that address's region
        coverage: 'gap: FND-CRM-REG-053'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: placed by the rules
        to: placed by the rules
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › moving › moves a contact from region A to region B when its address
          moves
        coverage: 'gap: FND-CRM-REG-053'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: placed by the rules
        to: unplaced
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › moving › clears the region when the new address matches no rule
        coverage: 'gap: FND-CRM-REG-053'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: placed by the rules
        to: set by hand
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › manual regions and the override › keeps a manual region while the
          deciding address is unchanged
        coverage: 'gap: FND-CRM-REG-053'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: set by hand
        to: placed by the rules
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › manual regions and the override › replaces a manual region when the
          deciding address changes
        coverage: 'gap: FND-CRM-REG-053'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: placed by the rules
        to: held
        provenance: observed
        source: >-
          services-crm:modules/regions/services/region-assignment/region-assignment.ts:regionAssignmentOverrideHandler
        coverage: 'gap: FND-CRM-REG-053'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: set by hand
        to: held
        provenance: observed
        source: >-
          services-crm:modules/regions/services/region-assignment/region-assignment.ts:regionAssignmentOverrideHandler
        coverage: 'gap: FND-CRM-REG-053'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: held
        to: placed by the rules
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › 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
        coverage: 'gap: FND-CRM-REG-053'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: held
        to: set by hand
        provenance: inferred
        source: >-
          services-crm:modules/regions/services/region-assignment/region-assignment.ts:reconcileRegionAssignments
        coverage: 'gap: FND-CRM-REG-053'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-054
    scope: CAP-CRM-REG-009
    categories:
      - validation
      - permission
      - edge
      - failure
      - concurrency
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-009-05
      - ATS-CRM-REG-009-06
    permissions_to_verify:
      - crm.contacts.update
      - crm.organizations.update
    transitions_to_verify:
      - STATE-CRM-REG-003
    related:
      - CAP-CRM-REG-008
      - CAP-CRM-REG-011
    source:
      - CAP-CRM-REG-009
      - CAP-CRM-REG-008
      - CAP-CRM-REG-011
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      validation: Refused inputs need checks that the previous state is preserved.
      permission: Each named action key needs an allowed and denied request with unchanged stored state on refusal.
      edge: 'Absent configuration, empty results and unusual valid inputs need explicit checks.'
      failure: A failed dependency needs a checked refusal or recovery outcome.
      concurrency: Competing writes and read-versus-write timing need explicit checks.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-003
        from: unplaced
        to: set by hand
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › initial assignment › keeps a region the client sends with a contact
          that has no address (nothing decides it)
        coverage: 'gap: FND-CRM-REG-054'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: unplaced
        to: placed by the rules
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › initial assignment › gives a contact created with a matching address
          that address's region
        coverage: 'gap: FND-CRM-REG-054'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: placed by the rules
        to: placed by the rules
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › moving › moves a contact from region A to region B when its address
          moves
        coverage: 'gap: FND-CRM-REG-054'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: placed by the rules
        to: unplaced
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › moving › clears the region when the new address matches no rule
        coverage: 'gap: FND-CRM-REG-054'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: placed by the rules
        to: set by hand
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › manual regions and the override › keeps a manual region while the
          deciding address is unchanged
        coverage: 'gap: FND-CRM-REG-054'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: set by hand
        to: placed by the rules
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › manual regions and the override › replaces a manual region when the
          deciding address changes
        coverage: 'gap: FND-CRM-REG-054'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: placed by the rules
        to: held
        provenance: observed
        source: >-
          services-crm:modules/regions/services/region-assignment/region-assignment.ts:regionAssignmentOverrideHandler
        coverage: 'gap: FND-CRM-REG-054'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: set by hand
        to: held
        provenance: observed
        source: >-
          services-crm:modules/regions/services/region-assignment/region-assignment.ts:regionAssignmentOverrideHandler
        coverage: 'gap: FND-CRM-REG-054'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: held
        to: placed by the rules
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › 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
        coverage: 'gap: FND-CRM-REG-054'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-003
        from: held
        to: set by hand
        provenance: inferred
        source: >-
          services-crm:modules/regions/services/region-assignment/region-assignment.ts:reconcileRegionAssignments
        coverage: 'gap: FND-CRM-REG-054'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-055
    scope: CAP-CRM-REG-010
    categories:
      - rule
      - validation
      - permission
      - failure
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-010-07
      - ATS-CRM-REG-010-08
      - ATS-CRM-REG-010-09
    permissions_to_verify:
      - crm.regions.read
    transitions_to_verify:
      - STATE-CRM-REG-002
    related:
      - CAP-CRM-REG-002
      - CAP-CRM-REG-003
      - CAP-CRM-REG-004
      - CAP-CRM-REG-005
      - CAP-CRM-REG-011
    source:
      - CAP-CRM-REG-010
      - CAP-CRM-REG-002
      - CAP-CRM-REG-003
      - CAP-CRM-REG-004
      - CAP-CRM-REG-005
      - CAP-CRM-REG-011
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      rule: Missing required-rule proof.
      validation: Refused inputs need checks that the previous state is preserved.
      permission: Each named action key needs an allowed and denied request with unchanged stored state on refusal.
      failure: A failed dependency needs a checked refusal or recovery outcome.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-002
        from: never saved
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:lockSettingsRowForRuleWrite
        coverage: 'gap: FND-CRM-REG-055'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: never saved
        to: on and needing recalculation
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings
        coverage: 'gap: FND-CRM-REG-055'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: 'off'
        to: on and needing recalculation
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says a
          recalculation is needed once the rules have been saved and nothing has recalculated
        coverage: 'gap: FND-CRM-REG-055'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and current
        to: on and needing recalculation
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says one is
          needed again as soon as a rule is added;
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings,
          stampRulesChanged, noteRuleRegionDeactivated
        coverage: 'gap: FND-CRM-REG-055'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and needing recalculation
        to: on and current
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says none is
          needed once a recalculation has succeeded against those rules
        coverage: 'gap: FND-CRM-REG-055'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and needing recalculation
        to: 'off'
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › assignment switched off › assigns nothing while assignment is off
        coverage: 'gap: FND-CRM-REG-055'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and current
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:recalculationNeeded
        coverage: 'gap: FND-CRM-REG-055'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: 'off'
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:stampRulesChanged
        coverage: 'gap: FND-CRM-REG-055'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-056
    scope: CAP-CRM-REG-011
    categories:
      - validation
      - edge
      - failure
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-011-10
      - ATS-CRM-REG-011-11
    permissions_to_verify:
      - crm.regions.recalculate
    transitions_to_verify:
      - STATE-CRM-REG-004
    related:
      - CAP-CRM-REG-008
      - CAP-CRM-REG-009
      - CAP-CRM-REG-010
      - CAP-CRM-REG-012
    source:
      - CAP-CRM-REG-011
      - CAP-CRM-REG-008
      - CAP-CRM-REG-009
      - CAP-CRM-REG-010
      - CAP-CRM-REG-012
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      validation: Refused inputs need checks that the previous state is preserved.
      edge: 'Absent configuration, empty results and unusual valid inputs need explicit checks.'
      failure: A failed dependency needs a checked refusal or recovery outcome.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-004
        from: requested
        to: running
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/persistence/region-recalculations.integration.spec.js#region
          recalculations table (integration) › refuses a second running run for the tenant;
          services-crm:modules/regions/services/region-assignment/region-recalculation.ts:startRegionRecalculation;
          services-crm:modules/regions/aws/api/regions.routes.ts:recalculateRegionAssignments
        coverage: 'gap: FND-CRM-REG-056'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-004
        from: running
        to: running
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-recalculation-errors.integration.spec.js#a
          region recalculation that fails (integration) › the reason it records › records the redacted
          reason on a run it leaves running, so the next delivery can get past the cause
        coverage: 'gap: FND-CRM-REG-056'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-004
        from: running
        to: completed
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-recalculation-errors.integration.spec.js#a
          region recalculation that fails (integration) › a run that gets past what stopped it › answers
          the whole record of the completed run, with no reason left on it
        coverage: 'gap: FND-CRM-REG-056'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-004
        from: running
        to: failed
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-recalculation-errors.integration.spec.js#a
          region recalculation that fails (integration) › the last delivery of a run’s event › fails the
          run, because nothing will deliver its event again;
          services-crm:modules/regions/services/region-assignment/region-recalculation.ts:recordFailure;
          services-crm:docs/change-events.md#7. Failures and recovery
        coverage: 'gap: FND-CRM-REG-056'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-057
    scope: CAP-CRM-REG-012
    categories:
      - validation
      - permission
      - edge
      - concurrency
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-012-07
      - ATS-CRM-REG-012-08
    permissions_to_verify:
      - crm.regions.read
    transitions_to_verify:
      - STATE-CRM-REG-004
    related:
      - CAP-CRM-REG-011
    source:
      - CAP-CRM-REG-012
      - CAP-CRM-REG-011
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      validation: Refused inputs need checks that the previous state is preserved.
      permission: Each named action key needs an allowed and denied request with unchanged stored state on refusal.
      edge: 'Absent configuration, empty results and unusual valid inputs need explicit checks.'
      concurrency: Competing writes and read-versus-write timing need explicit checks.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-004
        from: requested
        to: running
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/persistence/region-recalculations.integration.spec.js#region
          recalculations table (integration) › refuses a second running run for the tenant;
          services-crm:modules/regions/services/region-assignment/region-recalculation.ts:startRegionRecalculation;
          services-crm:modules/regions/aws/api/regions.routes.ts:recalculateRegionAssignments
        coverage: 'gap: FND-CRM-REG-057'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-004
        from: running
        to: running
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-recalculation-errors.integration.spec.js#a
          region recalculation that fails (integration) › the reason it records › records the redacted
          reason on a run it leaves running, so the next delivery can get past the cause
        coverage: 'gap: FND-CRM-REG-057'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-004
        from: running
        to: completed
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-recalculation-errors.integration.spec.js#a
          region recalculation that fails (integration) › a run that gets past what stopped it › answers
          the whole record of the completed run, with no reason left on it
        coverage: 'gap: FND-CRM-REG-057'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-004
        from: running
        to: failed
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-recalculation-errors.integration.spec.js#a
          region recalculation that fails (integration) › the last delivery of a run’s event › fails the
          run, because nothing will deliver its event again;
          services-crm:modules/regions/services/region-assignment/region-recalculation.ts:recordFailure;
          services-crm:docs/change-events.md#7. Failures and recovery
        coverage: 'gap: FND-CRM-REG-057'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-058
    scope: CAP-CRM-REG-013
    categories:
      - rule
      - validation
      - failure
      - concurrency
      - invariant
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-013-05
      - ATS-CRM-REG-013-07
    permissions_to_verify:
      - crm.regions.read
      - crm.regions.create
      - crm.regions.update
      - crm.regions.delete
      - crm.regions.bulk
      - crm.regions.recalculate
    transitions_to_verify: []
    related:
      - CAP-CRM-REG-001
      - CAP-CRM-REG-002
      - CAP-CRM-REG-003
      - CAP-CRM-REG-011
      - CAP-CRM-REG-014
    source:
      - CAP-CRM-REG-013
      - CAP-CRM-REG-001
      - CAP-CRM-REG-002
      - CAP-CRM-REG-003
      - CAP-CRM-REG-011
      - CAP-CRM-REG-014
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario:
      - CAP-CRM-REG-002
      - CAP-CRM-REG-003
    category_checks:
      rule: Missing required-rule proof.
      validation: Refused inputs need checks that the previous state is preserved.
      failure: A failed dependency needs a checked refusal or recovery outcome.
      concurrency: Competing writes and read-versus-write timing need explicit checks.
      invariant: Domain-object consistency across permitted writes needs explicit checks.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks: []
  - finding: FND-CRM-REG-059
    scope: CAP-CRM-REG-014
    categories:
      - transition
      - edge
      - boundary
      - concurrency
      - invariant
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-014-03
      - ATS-CRM-REG-014-04
      - ATS-CRM-REG-014-05
    permissions_to_verify:
      - crm.regions.bulk
      - crm.regions.update
    transitions_to_verify:
      - STATE-CRM-REG-001
    related:
      - CAP-CRM-REG-001
      - CAP-CRM-REG-013
    source:
      - CAP-CRM-REG-014
      - CAP-CRM-REG-001
      - CAP-CRM-REG-013
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      transition: Complete lifecycle transitions and their guards need explicit checks.
      edge: 'Absent configuration, empty results and unusual valid inputs need explicit checks.'
      boundary: 'Limits, local reference boundaries and exact endpoints need explicit checks.'
      concurrency: Competing writes and read-versus-write timing need explicit checks.
      invariant: Domain-object consistency across permitted writes needs explicit checks.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-001
        from: active
        to: active
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/persistence/regions.integration.spec.js#creates
          a region active by default;
          services-crm:modules/regions/services/persistence/regions.ts:insertRegion, updateRegionRow;
          services-crm:modules/regions/aws/api/regions.routes.ts
        coverage: 'gap: FND-CRM-REG-059'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: active
        to: inactive
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegion'
        coverage: 'gap: FND-CRM-REG-059'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: inactive
        to: active
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegion'
        coverage: 'gap: FND-CRM-REG-059'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: inactive
        to: inactive
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegionRow'
        coverage: 'gap: FND-CRM-REG-059'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: active
        to: deleted
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/db/regions.table.integration.spec.js#regions
          table (integration) › references › refuses to delete a region a contact is in, naming what uses
          it; services-crm:modules/regions/services/persistence/regions.ts:deleteRegionRow;
          services-crm:modules/regions/aws/api/regions.routes.ts:deleteRegion
        coverage: 'gap: FND-CRM-REG-059'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-001
        from: inactive
        to: deleted
        provenance: observed
        source: 'services-crm:modules/regions/services/persistence/regions.ts:deleteRegion'
        coverage: 'gap: FND-CRM-REG-059'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
  - finding: FND-CRM-REG-060
    scope: CAP-CRM-REG-015
    categories:
      - validation
      - edge
      - failure
      - boundary
      - concurrency
    missing_rules: []
    unbound_scenarios:
      - ATS-CRM-REG-015-01
      - ATS-CRM-REG-015-02
      - ATS-CRM-REG-015-03
    permissions_to_verify: []
    transitions_to_verify:
      - STATE-CRM-REG-002
    related:
      - CAP-CRM-REG-001
      - CAP-CRM-REG-003
    source:
      - CAP-CRM-REG-015
      - CAP-CRM-REG-001
      - CAP-CRM-REG-003
    provenance: inferred
    note: >-
      Covered means an authored scenario exists in the category, not that all variants execute. The
      remaining category checks, full transition guards, action-key refusal matrix and unbound scenarios
      need executable proof; related-capability chains are proposed unless a binding is present.
    related_without_interaction_scenario: []
    category_checks:
      validation: Refused inputs need checks that the previous state is preserved.
      edge: 'Absent configuration, empty results and unusual valid inputs need explicit checks.'
      failure: A failed dependency needs a checked refusal or recovery outcome.
      boundary: 'Limits, local reference boundaries and exact endpoints need explicit checks.'
      concurrency: Competing writes and read-versus-write timing need explicit checks.
    source_sha:
      services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
      react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
    transition_checks:
      - model: STATE-CRM-REG-002
        from: never saved
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:lockSettingsRowForRuleWrite
        coverage: 'gap: FND-CRM-REG-060'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: never saved
        to: on and needing recalculation
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings
        coverage: 'gap: FND-CRM-REG-060'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: 'off'
        to: on and needing recalculation
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says a
          recalculation is needed once the rules have been saved and nothing has recalculated
        coverage: 'gap: FND-CRM-REG-060'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and current
        to: on and needing recalculation
        provenance: observed
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says one is
          needed again as soon as a rule is added;
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings,
          stampRulesChanged, noteRuleRegionDeactivated
        coverage: 'gap: FND-CRM-REG-060'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and needing recalculation
        to: on and current
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment-rules.integration.spec.js#region
          assignment rules and slots (integration) › whether a recalculation is needed › says none is
          needed once a recalculation has succeeded against those rules
        coverage: 'gap: FND-CRM-REG-060'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and needing recalculation
        to: 'off'
        provenance: test
        source: >-
          services-crm:modules/regions/tests/integration/services/region-assignment/region-assignment.integration.spec.js#region
          assignment (integration) › assignment switched off › assigns nothing while assignment is off
        coverage: 'gap: FND-CRM-REG-060'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: on and current
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:recalculationNeeded
        coverage: 'gap: FND-CRM-REG-060'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
      - model: STATE-CRM-REG-002
        from: 'off'
        to: 'off'
        provenance: observed
        source: >-
          services-crm:modules/regions/services/persistence/region-assignment-settings.ts:stampRulesChanged
        coverage: 'gap: FND-CRM-REG-060'
        note: >-
          Existing scenarios exercise some outcomes; the full guard and side-effect combinations of this
          transition are not bound to an executable proof.
testing_contradictions:
  - finding: FND-CRM-REG-061
    provenance: observed
    source:
      - >-
        react-console:acceptance/crm/playwright/journeys/configuration/CRM-ACC-0362.spec.ts#CRM-ACC-0362
        step 5
      - 'services-crm:modules/regions/aws/api/regions.routes.ts:updateRegionAssignmentRule'
      - >-
        services-crm:modules/regions/tests/e2e/regions.e2e.spec.js#the rules, one at a time › answers 409
        for a replace from a stale read
    affects:
      - TST-CRM-REG-011
      - CAP-CRM-REG-005
    note: >-
      The journey expects two versionless individual replacements to return success; the route rejects
      missing versions. Registration retains the file, but this assertion is not bound as proof of the
      version policy.
---

# Regions Findings and Open Questions

## Findings

| id | severity | statement | affects | evidence | kind |
|---|---|---|---|---|---|
| `FND-CRM-REG-001` | medium | An inactive regional target remains eligible for matching even though deactivating it records a policy change and requests recalculation. Console analysis warns about the target, but the retirement workflow does not resolve the mismatch; Product must choose the intended policy. | `CAP-CRM-REG-002`, `BR-CAP-CRM-REG-002-07`, `BR-CAP-CRM-REG-002-08`, `BR-CAP-CRM-REG-010-03`, `CAP-CRM-REG-006`, `JNY-CRM-REG-004`, `OQ-CRM-REG-001` | services-crm:modules/regions/services/persistence/regions.ts:updateRegion; services-crm:modules/regions/services/persistence/region-assignment-settings.ts:noteRuleRegionDeactivated; services-crm:modules/regions/services/region-assignment/region-matching.ts:matchRegionRule; react-console:lib/configuration/regions-analysis.ts:analyzeRules; react-console:acceptance/crm/inventory/business-rules.json#RUL-CRM-CFG-042; react-console:acceptance/crm/journeys/configuration/CRM-ACC-0361.json (open_decisions) | inconsistency |
| `FND-CRM-REG-002` | high | Regional locks travel through ordinary creation, replacement, patching and import. An updater can set a full lock that these operations cannot remove, while omitting a delete lock during replacement clears it. This differs from the recorded requirement for narrowly authorized, reversible and audited lock actions. | `BR-CAP-CRM-REG-002-04`, `BR-CAP-CRM-REG-002-05`, `BR-CAP-CRM-REG-001-06`, `BR-CAP-CRM-REG-001-11`, `BR-CAP-CRM-REG-014-04`, `CAP-CRM-REG-002` | services-crm:modules/regions/aws/api/regions.routes.ts:toWriteInput; services-crm:lib/db/system-values.ts:clientSystemColumnsFromWire; services-crm:modules/regions/services/persistence/regions.ts:updateRegionRow, deleteRegionRow; react-console:lib/configuration/regions.ts:carriedThrough; services-crm:docs/milestones/CRM-M3-crm-configuration.md#D-08 | defect |
| `FND-CRM-REG-003` | medium | Region replacement and patching advance the version even without a field change. Settings accept versionless replacement and count every save as a policy change, including an unchanged one. The recorded current-version and unchanged-save standard therefore remains incompletely applied. | `BR-CAP-CRM-REG-001-12`, `BR-CAP-CRM-REG-003-08`, `BR-CAP-CRM-REG-010-08`, `CAP-CRM-REG-001`, `CAP-CRM-REG-003`, `CAP-CRM-REG-010` | services-crm:modules/regions/services/persistence/regions.ts:updateRegionRow; services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings; services-crm:modules/regions/aws/api/regions.routes.ts:updateRegionAssignmentSettings; services-crm:docs/milestones/CRM-M1-contacts-and-organizations.md#D-05 | inconsistency |
| `FND-CRM-REG-004` | medium | The console’s viewing alias accepts regional or contact-role read authority, and its management alias accepts several regional or contact-role write keys. The service requires the exact regional key for the operation, so a visitor can receive entry or controls followed by a refusal. The recalculation alias itself maps directly to regional recalculation authority. | `BR-CAP-CRM-REG-013-07`, `CAP-CRM-REG-013`, `CAP-CRM-REG-011` | react-console:lib/authz/backend-aliases.ts:crm.settings.view, crm.settings.manage, maintenance.operations.run; react-console:components/regions/use-regions.ts:useRegionsPermissions; react-console:acceptance/crm/journeys/security/CRM-ACC-0575.json; react-console:acceptance/crm/inventory/capabilities.json#CAP-CRM-CFG-017 (gaps) | inconsistency |
| `FND-CRM-REG-005` | low | Address-source validation differs between surfaces: the service accepts any existing workspace address type regardless of its applicability label, whereas the console filters new choices by record kind and preserves an existing selection. | `BR-CAP-CRM-REG-003-05`, `BR-CAP-CRM-REG-003-10` | react-console:lib/configuration/regions.ts:addressTypesFor; services-crm:modules/regions/db/region-assignment-settings.table.ts (header); services-crm:modules/regions/tests/integration/services/persistence/region-assignment-settings.integration.spec.js#the capability › takes a contact address type marked for organizations, applies_to being a guide and not a rule | inconsistency |
| `FND-CRM-REG-006` | low | The API retains individual-rule editing added for an earlier console workflow, while the current editor replaces the complete staged policy. Settings-version increments protect whole-list drafts from intervening individual writes, but do not provide symmetric protection when whole-list replacement resets individual versions. | `CAP-CRM-REG-005`, `BR-CAP-CRM-REG-005-06` | services-crm:modules/regions/aws/api/regions.routes.ts (header); react-console:lib/configuration/regions.ts:createRegionsApi; react-console:acceptance/crm/inventory/capabilities.json#CAP-CRM-CFG-016 (gaps); services-crm:docs/migrations/crm-regions/README.md#2026-10-15 — Final acceptance (console follow-ups) (Andrew approved 2026-10-15: two tabs, Test an Address dialog, drawers, a read-only Assignment Rules tab with its own editor screen and the banner) | undocumented |
| `FND-CRM-REG-007` | low | Historical migration text and comments describe superseded behavior: copied organization-address propagation, timestamp-based need comparison, retired operation paths, regional custom fields and placement inside a save. Those references remain evidence of earlier work and should not define the current design. | `CAP-CRM-REG-008`, `CAP-CRM-REG-010`, `CAP-CRM-REG-015`, `CAP-CRM-REG-001` | services-crm:docs/migrations/crm-regions/README.md#Assignment and recalculation triggers in Rolodex 2.0; services-crm:docs/migrations/crm-regions/README.md#2026-10-11 second pass (item 2); services-crm:modules/regions/aws/logic/regions-api.lambda.ts (header); services-crm:modules/regions/export/region-assignment-settings.dataset.ts (header); react-console:lib/configuration/regions.ts:updateRegion (comment); react-console:acceptance/crm/inventory/capabilities.json#CAP-CRM-CFG-016 (gaps: docs-2 INV-RLX-REG-01) | debt |
| `FND-CRM-REG-008` | medium | An effective affiliation can supply a linked deciding address. Passing its end date alone does not generate the address change that regional handlers require, so the contact can retain an outdated placement until another relevant event or recalculation. | `BR-CAP-CRM-REG-008-12`, `CAP-CRM-REG-008`, `JNY-CRM-REG-005` | services-crm:modules/entities/services/persistence/contacts.ts:readContactRegionAddresses; services-crm:modules/entities/services/affiliations/affiliation-date-reconciliation.ts; services-crm:modules/regions/services/region-assignment/region-assignment.ts:linkedContactRegionAssignmentHandler | undocumented |
| `FND-CRM-REG-009` | low | Recalculation counts every traversed identifier as examined, including records that assignment skips for update locks. Event-driven reconciliation counts its eligible locked targets instead. The same label therefore describes different work populations. | `BR-CAP-CRM-REG-011-10` | services-crm:modules/regions/services/region-assignment/region-recalculation.ts:recalculateBatch; services-crm:modules/regions/services/region-assignment/region-assignment.ts:reconcileRegionAssignments; services-crm:modules/entities/services/persistence/contacts.ts:lockContactIdsAfter, lockContactRegionTargets | undocumented |
| `FND-CRM-REG-010` | low | Regional recalculation has no cancellation operation. A run marked failed does not restart itself, so staff must request a new run; the acceptance catalogue leaves cancellation as an unresolved extension. | `BR-CAP-CRM-REG-012-07`, `BR-CAP-CRM-REG-012-08`, `CAP-CRM-REG-012` | services-crm:modules/regions/aws/api/regions.routes.ts:regionsRoutes; services-crm:modules/regions/services/region-assignment/region-recalculation.ts:startRegionRecalculation; react-console:acceptance/crm/inventory/capabilities.json#CAP-CRM-CFG-017 (gaps); react-console:acceptance/crm/journeys/configuration/CRM-ACC-0360.json (open_decisions) | undocumented |
| `FND-CRM-REG-011` | low | The rule table contains lock storage, but route mapping drops incoming lock values and rule reads omit them. Individual and whole-policy writes do not enforce those stored locks, leaving the fields without an operational contract. | `CAP-CRM-REG-004`, `CAP-CRM-REG-005` | services-crm:modules/regions/db/region-assignment-settings.table.ts:regionAssignmentRules (lockedCheck); services-crm:modules/regions/aws/api/regions.routes.ts:toRuleInput; services-crm:modules/regions/services/persistence/region-assignment-settings.ts:ruleRecordOf | debt |
| `FND-CRM-REG-012` | medium | Proof remains incomplete for several refusals and side effects, including lock behavior, targeted insertion, maximum policy size, imported-row validation, permission aliases and expiry-trigger processing. Proposed scenarios document the needed proof without claiming a passing service test. | `BR-CAP-CRM-REG-002-04`, `BR-CAP-CRM-REG-002-07`, `BR-CAP-CRM-REG-005-01`, `BR-CAP-CRM-REG-004-08`, `BR-CAP-CRM-REG-014-03`, `BR-CAP-CRM-REG-013-07`, `BR-CAP-CRM-REG-001-12`, `BR-CAP-CRM-REG-010-08`, `BR-CAP-CRM-REG-008-12` | services-crm:modules/regions/tests/; services-crm:tests/unit/regions-authorization.spec.ts; react-console:acceptance/crm/playwright/journeys/configuration/CRM-ACC-0361.spec.ts#CRM-ACC-0361; react-console:acceptance/crm/playwright/journeys/configuration/CRM-ACC-0364.spec.ts#CRM-ACC-0364 | debt |
| `FND-CRM-REG-013` | low | The acceptance catalogue marks regional journeys unstarted or unexecuted despite existing Playwright specifications. Bindings establish intended test coverage only; this examination does not establish that those live workflows pass at the pinned commits. | `JNY-CRM-REG-001`, `JNY-CRM-REG-002`, `JNY-CRM-REG-003`, `JNY-CRM-REG-004`, `JNY-CRM-REG-005` | react-console:acceptance/crm/journeys/configuration/CRM-ACC-0357.json (automation, execution); react-console:acceptance/crm/journeys/configuration/CRM-ACC-0360.json; react-console:acceptance/crm/journeys/contacts/CRM-ACC-0023.json; react-console:acceptance/crm/journeys/configuration/CRM-ACC-0361.json; react-console:acceptance/crm/playwright/journeys/ | inconsistency |
| `FND-CRM-REG-014` | low | Postal validation accepts endpoints without checking interval order. A reversed interval silently matches nothing, and postal comparison remains lexical even when codes resemble numbers. Product must decide whether to reject reversed intervals without silently changing the retained matching semantics. | `BR-CAP-CRM-REG-006-12`, `CAP-CRM-REG-004`, `OQ-CRM-REG-002` | services-crm:modules/regions/services/persistence/region-assignment-settings.ts:regionAssignmentRuleProblems; services-crm:modules/regions/services/region-assignment/region-matching.ts:matchRegionRule; react-console:acceptance/crm/inventory/capabilities.json#CAP-CRM-CFG-016 (open_decisions); react-console:acceptance/crm/journeys/configuration/CRM-ACC-0358.json (open_decisions) | undocumented |
| `FND-CRM-REG-015` | low | The earlier registry named a nonexistent console directory. The corrected row points to regional components, configuration libraries, the dedicated editor route and shared configuration host, together with the external tests and records used as evidence. | `MOD-CRM-REG` | specs/PRODUCT-AREAS.md (MOD-CRM-REG row); react-console:components/regions/; react-console:lib/configuration/regions.ts; react-console:app/(console)/console/[tenantId]/configuration/[module]/[area]/assignmentRules/page.tsx | inconsistency |
| `FND-CRM-REG-016` | low | The shared CRM actor description originally omitted regional authority from the administrator even though this module uses that actor. Examination proposes the regional responsibilities and keys in the actor row; the revised actor file returns to draft pending approval. | `ACT-CRM-003`, `ACT-CRM-001` | specs/crm/ACTORS.md; services-crm:aws/crm.service.ts:RegionsPermissions | inconsistency |

| `FND-CRM-REG-017` | medium | The requested regional planning brief does not exist in the starting corpus. Examination can compare the draft with the registered module scope and cited source records, but cannot verify alignment with that absent brief. | `MOD-CRM-REG` | rhythm-v2-docs:briefs/planning/crm-regions.brief.md (absent at 28d07581f283a535fe72168c5c4b781194434711) | undocumented |
| `FND-CRM-REG-018` | high | Whole-policy replacement deletes and recreates rules, retaining submitted identifiers but resetting their versions. An old individual-rule edit based on version one can pass after a newer whole-list save, while a previous higher version conflicts with the reset. A dedicated regression scenario is still needed. | `BR-CAP-CRM-REG-004-14`, `CAP-CRM-REG-005` | services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings, insertRule, updateRegionAssignmentRule | defect |
| `FND-CRM-REG-019` | medium | Preview belongs to the saved-policy view and evaluates saved coverage. The draft setup journey incorrectly placed it in the unsaved editor workflow; the corrected journey saves first and then previews from the read-only tab. | `JNY-CRM-REG-001`, `CAP-CRM-REG-007` | react-console:components/regions/assignment-rules-editor.tsx; react-console:components/regions/assignment-rules-view.tsx; react-console:lib/configuration/regions.ts:createRegionsApi | inconsistency |
| `FND-CRM-REG-020` | medium | The browser evidence records that the contact regional picker uses sample choices and can fail to display a saved inactive region. The catalogue’s inactive-choice requirement therefore remains documented intent rather than established working behavior. | `BR-CAP-CRM-REG-002-11`, `JNY-CRM-REG-003` | react-console:acceptance/crm/playwright/journeys/configuration/CRM-ACC-0373.spec.ts#CRM-ACC-0373; react-console:acceptance/crm/playwright/journeys/contacts/CRM-ACC-0023.spec.ts#CRM-ACC-0023 | defect |
| `FND-CRM-REG-021` | medium | The deactivation binding does not test the unused-target negative case, and the regional-import binding tests identifier grammar without the blank-name or conflicting-workspace cases. Complete scenarios are proposed. Expectations for unchanged writes, ordinary lock edits, expiry and aliases now describe observed behavior, leaving product recommendations in findings. | `ATS-CRM-REG-002-05`, `ATS-CRM-REG-014-03`, `ATS-CRM-REG-001-09`, `ATS-CRM-REG-002-04`, `ATS-CRM-REG-008-12`, `ATS-CRM-REG-010-07`, `ATS-CRM-REG-013-05` | react-console:acceptance/crm/playwright/journeys/configuration/CRM-ACC-0361.spec.ts#CRM-ACC-0361; react-console:acceptance/crm/playwright/journeys/configuration/CRM-ACC-0364.spec.ts#CRM-ACC-0364 | debt |
| `FND-CRM-REG-022` | medium | Compound statements sometimes exceed the assertions of their named test. Examination adds enforcing code and downgrades provenance where appropriate, and unbinds incomplete replacement-version, insertion and lock-skip scenarios. Complete proof is still needed for editor validation, normalized geographic inputs, address presence and disabled-assignment preview. | `BR-CAP-CRM-REG-004-12`, `BR-CAP-CRM-REG-006-08`, `BR-CAP-CRM-REG-006-11`, `BR-CAP-CRM-REG-007-07` | react-console:components/regions/assignment-draft.ts:assignmentIssues; services-crm:modules/regions/services/region-assignment/region-matching.ts:hasAddress, geographicAddressOf; services-crm:modules/regions/services/region-assignment/region-assignment.ts:previewRegionAssignment | debt |
| `FND-CRM-REG-023` | medium | A repeated start request can advance the current run while returning its identity. Affiliation expiry alone leaves placement untouched, but a later organization-address event can reconcile an expired link and clear the old region. The draft overstated both guarantees. | `BR-CAP-CRM-REG-011-02`, `JNY-CRM-REG-005` | services-crm:modules/regions/services/region-assignment/region-recalculation.ts:startRegionRecalculation; services-crm:modules/regions/services/region-assignment/region-assignment.ts:linkedContactRegionAssignmentHandler, reconcileRegionAssignments | inconsistency |
| `FND-CRM-REG-024` | medium | Region replacement and patching drop null values and treat any omitted property as a removal, so a client that does not know a field (the console never shows the external identifier) erases it unless it carries every read field back. The complete-payload rule decided for contacts and organizations has not been extended to regional records. | `BR-CAP-CRM-REG-001-06`, `DOM-CRM-REG-001`, `ADR-CRM-REG-008`, `OQ-CRM-REG-004` | services-crm:modules/regions/aws/api/regions.routes.ts:toWriteInput, replaceRequest; react-console:lib/configuration/regions.ts:carriedThrough, updateRegion; rhythm-v2-docs:specs/crm/entities/design/decisions/ADR-CRM-ENT-003 | inconsistency |
| `FND-CRM-REG-025` | medium | Regions, the assignment policy and its rules keep no record history: a change leaves only its last-modified stamp, a whole-list save leaves no trace of the rules it deleted, and lock values change through ordinary writes without the audit that the lock decision requires. | `DOM-CRM-REG-001`, `DOM-CRM-REG-002`, `ADR-CRM-REG-010`, `OQ-CRM-REG-003` | services-crm:modules/regions/services/persistence/regions.ts; services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings; services-crm:docs/record-locks.md#Not covered yet; services-crm:docs/milestones/CRM-M3-crm-configuration.md#D-08 | undocumented |
| `FND-CRM-REG-026` | medium | When a batch fails inside the start request, the request answers an error and skips the dispatcher nudge, although the run is already recorded and stays running. The worker picks it up only when the dispatcher's minute schedule publishes the insert event, and the console reports a failed start without showing the run until the page is reloaded. The start should answer the recorded run with its failure reason and still nudge. | `WF-CRM-REG-003`, `STATE-CRM-REG-004`, `SCR-CRM-REG-002`, `BR-CAP-CRM-REG-011-03` | services-crm:modules/regions/services/region-assignment/region-recalculation.ts:startRegionRecalculation, runBatch; services-crm:modules/regions/aws/api/regions.routes.ts:recalculateRegionAssignments; react-console:components/regions/recalculation.tsx:useRecalculation | defect |
| `FND-CRM-REG-027` | low | The Platform standards repository could not be read with this job's credential. The design names the queued-work, record-write, custom-field and submission-compatibility standards through the CRM records and code that cite them and through earlier corpus designs, so the verification pass should confirm each citation against the standards themselves. | `ADR-CRM-REG-004`, `ADR-CRM-REG-009`, `ADR-CRM-REG-012`, `SVC-CRM-REG-regions` | services-platform:docs/standards/** (not readable at ad3f6a65); services-crm:modules/regions/services/region-assignment/region-recalculation.ts | undocumented |
| `FND-CRM-REG-028` | low | No regional service, workflow or screen asks a model a question, so the module has no inference directory. The conventions require the module charter to say so in one sentence, and the approved charter does not; this is a planning correction for the charter's next revision. | `MOD-CRM-REG` | rhythm-v2-docs:specs/CONVENTIONS.md#9.8; specs/crm/regions/MODULE.md | inconsistency |
| `FND-CRM-REG-029` | low | The product area's responsibilities delegate bulk changes and imports from Entities to a CRM data-jobs module that the registry says is not a module: CRM data jobs run on the Platform Data Job Engine. The Regions row delegates its imports to the engine; the Entities row needs the same correction. | `RESP-CRM` | specs/crm/RESPONSIBILITIES.md (MOD-CRM-ENT delegates); specs/PRODUCT-AREAS.md | inconsistency |
| `FND-CRM-REG-030` | low | Deleting a region or a single rule requires no version, so a deletion can remove a region or rule changed since the deleting user read it. Rule deletion also advances the policy version, so a whole-list save prepared before the deletion is refused rather than restoring the rule. | `ADR-CRM-REG-009`, `STATE-CRM-REG-001` | services-crm:modules/regions/services/persistence/regions.ts:deleteRegion; services-crm:modules/regions/services/persistence/region-assignment-settings.ts:deleteRegionAssignmentRule | undocumented |

| `FND-CRM-REG-031` | medium | The requested design brief is absent from the starting corpus. Alignment with that brief remains unknown; the examination uses the charter, planning artifacts and cited product records. | `MOD-CRM-REG` | rhythm-v2-docs:briefs/design/crm-regions.brief.md (absent at 5b13fe7647ea0e2529cfc341f5a90ec1e50fa1de) | undocumented |
| `FND-CRM-REG-032` | high | The planning layer is described as approved in the job, but its charter, features, concepts, capabilities and journeys remain draft, and acceptance sets remain proposed. No approval record is supplied. Design examination cannot establish the required planning gate or approve it on Andrew’s behalf. | `MOD-CRM-REG` | rhythm-v2-docs:specs/crm/regions/planning/** (frontmatter); specs/crm/regions/MODULE.md | inconsistency |
| `FND-CRM-REG-033` | high | Placement, preview and settings reads do not request the available policy read lock. Separate reads of settings, rules and postal ranges can observe different committed saves, so a record row lock alone does not establish one consistent policy snapshot. The interleaving needs a regression test and a decision on read locking or isolation. | `DOM-CRM-REG-003`, `SVC-CRM-REG-regions`, `WF-CRM-REG-001`, `WF-CRM-REG-003` | services-crm:modules/regions/services/persistence/region-assignment-settings.ts:readRegionAssignmentSettings, readRules; services-crm:modules/regions/services/region-assignment/region-assignment.ts:reconcileRegionAssignments, previewRegionAssignment | defect |
| `FND-CRM-REG-034` | medium | Policy writers serialize once a settings row exists. Two first writes can both read an absent row and attempt insertion; neither settings persistence path catches the duplicate settings key to retry or report a version conflict. The database preserves one policy, but successful serialization of every first write is not established. | `DOM-CRM-REG-002`, `WF-CRM-REG-004` | services-crm:modules/regions/services/persistence/region-assignment-settings.ts:saveRegionAssignmentSettings, lockSettingsRowForRuleWrite, settingsSaveRefusal | defect |
| `FND-CRM-REG-035` | medium | The recalculation hook adopts only running history and keeps history and polling errors out of its returned screen state. A failed historical run is not restored on reload, a running run’s recoverable reason is not displayed, and monitoring failures have no visible retry control. The draft promised broader failure visibility. | `SCR-CRM-REG-002`, `WF-CRM-REG-003`, `STATE-CRM-REG-004` | react-console:components/regions/recalculation.tsx:useRecalculation, RecalculationPanel | defect |
| `FND-CRM-REG-036` | low | The settings response includes the policy change time, but the saved-policy view never renders it. The rule editor also uses the shared right-hand drawer despite its component name suggesting a dialog. The design now describes those built behaviors. | `SCR-CRM-REG-002`, `SCR-CRM-REG-003`, `DOM-CRM-REG-002` | react-console:components/regions/assignment-rules-view.tsx; react-console:components/regions/rule-dialog.tsx:RuleDialog | inconsistency |
| `FND-CRM-REG-037` | high | Recording a batch failure is best effort. If failure settlement itself fails on the final queue delivery, the code logs that failure and rethrows the batch error; the run can remain running after its message is dead-lettered, preventing a new start from creating a replacement run. Manual recovery is not provided by regional routes. | `DOM-CRM-REG-004`, `STATE-CRM-REG-004`, `WF-CRM-REG-003` | services-crm:modules/regions/services/region-assignment/region-recalculation.ts:recordFailure; services-crm:modules/regions/services/persistence/region-recalculations.ts:recordRecalculationFailure | defect |
| `FND-CRM-REG-038` | low | Several compound invariant, transition and hop claims cite tests that assert only one part, including identifier grammar, reference checks, run starting and dead-lettering. Verification retains the real test anchors and adds enforcing code or the shared delivery record, using observed or documented provenance where the broader claim is not proved by the named test. | `DOM-CRM-REG-001`, `DOM-CRM-REG-002`, `DOM-CRM-REG-004`, `STATE-CRM-REG-001`, `STATE-CRM-REG-004`, `WF-CRM-REG-001`, `WF-CRM-REG-003` | services-crm:modules/regions/tests/integration/**; services-crm:modules/regions/services/**; services-crm:docs/change-events.md#7. Failures and recovery | debt |
| `FND-CRM-REG-039` | medium | Database declarations enforce unique positive rule positions and kind-specific state and country lists, but do not enforce dense positions or the existence of postal ranges. Legacy contact and organization regional references are also retained by initially unvalidated foreign keys. Universal database guarantees in the draft are narrowed to their actual enforcement and legacy exceptions. | `DOM-CRM-REG-001`, `DOM-CRM-REG-002`, `DOM-CRM-REG-003`, `ADR-CRM-REG-013` | services-crm:modules/regions/db/region-assignment-settings.table.ts; services-crm:db/migrations/0019_regions.sql; services-crm:modules/regions/services/persistence/region-assignment-settings.ts:setRulePositions, regionAssignmentRuleProblems | inconsistency |
| `FND-CRM-REG-040` | medium | Regional imports support insert, upsert and update with distinct duplicate behavior. Shared import configuration explicitly allows an overwrite conflict policy and can use a current version when no expected version is supplied. The draft’s unconditional promise that imports never overwrite a changed record is removed; delegated engine execution and idempotency remain outside the regional examination’s proof. | `WF-CRM-REG-005`, `SVC-CRM-REG-regions` | services-crm:modules/data-jobs/services/operations/configuration-import.ts:configurationWriteOf, expectedVersionOf (header: reject and overwrite); services-crm:modules/data-jobs/services/operations/configuration-imports.ts:regionImports | inconsistency |
| `FND-CRM-REG-041` | medium | The regional declaration inherits the service’s internal-use classification without a separate classification for geographic processing that reads personal address information and records its results. | `CAP-CRM-REG-008`, `WF-CRM-REG-001`, `SVC-CRM-REG-regions` | `TC-DAT-001`; structured control evidence | control-gap |
| `FND-CRM-REG-042` | high | Regional locks change through ordinary record writes and imports without a dedicated permission or append-only lock-change event; regional definitions and geographic policy retain only their latest modification attribution. | `CAP-CRM-REG-002`, `CAP-CRM-REG-014`, `SVC-CRM-REG-regions`, `WF-CRM-REG-004` | `TC-AZ-001`, `TC-LOG-001`, `TC-LOG-002`, `TC-LOG-003`, `TC-PI-005`; structured control evidence | control-gap |
| `FND-CRM-REG-043` | high | Settings replacement accepts an omitted version, and whole-policy replacement recreates retained rules at their initial version; a stale individual edit can therefore pass after a newer complete policy save. | `CAP-CRM-REG-003`, `CAP-CRM-REG-004`, `CAP-CRM-REG-005`, `WF-CRM-REG-004`, `SVC-CRM-REG-regions` | `TC-PI-003`; structured control evidence | control-gap |
| `FND-CRM-REG-044` | medium | The recalculation screen drops polling and history failures from its returned state and does not restore a failed historical run on reload, leaving the customer without the complete visible failure and recovery outcome. | `SCR-CRM-REG-002`, `WF-CRM-REG-003`, `CAP-CRM-REG-012` | `TC-PI-004`; structured control evidence | control-gap |
| `FND-CRM-REG-045` | high | Final-delivery failure settlement is best effort; if recording failure also fails, a recalculation can remain running after its delivery is dead-lettered, with no regional recovery operation to settle it. | `CAP-CRM-REG-012`, `WF-CRM-REG-003`, `SVC-CRM-REG-regions` | `TC-PI-004`, `TC-AVL-004`; structured control evidence | control-gap |
| `FND-CRM-REG-046` | medium | Maintain the region catalogue still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-001` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-047` | medium | Retire regions while preserving their references still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-002` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-048` | medium | Configure automatic placement and its address sources still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-003` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-049` | medium | Build the geographic assignment policy still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-004` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-050` | medium | Maintain individual rules alongside the shared policy still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-005` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-051` | medium | Determine an address’s geographic region still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-006` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-052` | medium | Check an address against the saved policy still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-007` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-053` | medium | Keep placements aligned with address changes still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-008` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-054` | medium | Preserve a deliberate regional exception still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-009` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-055` | medium | Identify placements that need recalculation still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-010` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-056` | medium | Apply the current policy across existing records still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-011` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-057` | medium | Monitor recalculation and recover from failure still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-012` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-058` | medium | Restrict regional work to authorised users still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-013` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-059` | medium | Import a catalogue of regions still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-014` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-060` | medium | Share regions through record references and exports still needs the listed category, transition, permission and executable proofs. | `CAP-CRM-REG-015` | testing_coverage frontmatter | coverage-gap |
| `FND-CRM-REG-061` | medium | A browser acceptance journey expects versionless individual-rule replacements to succeed, while the pinned route requires a version. Its success expectation contradicts the service contract and is not used as proof of the version policy. | `CAP-CRM-REG-005`, `TST-CRM-REG-011` | testing_contradictions frontmatter | inconsistency |

## Open Questions

| id | question | why_it_matters | options | recommendation | affects |
|---|---|---|---|---|---|
| `OQ-CRM-REG-001` | How should enabled rules treat a retired regional target? | Retirement currently leaves assignment active while requesting recalculation, making staff’s expected outcome unclear. | A: retain matching and remove the retirement signal. B: skip inactive targets and let coverage fall through. C: prevent retirement while enabled rules reference the target. | The product should choose B so retirement, warnings and recalculation lead to a coherent result. | `CAP-CRM-REG-002`, `CAP-CRM-REG-006`, `CAP-CRM-REG-010`, `FND-CRM-REG-001` |
| `OQ-CRM-REG-002` | Should saving reject a reversed postal interval? | Reversed endpoints silently produce no coverage, while numeric reinterpretation would also change the retained matching behavior. | A: reject reversed lexical endpoints. B: additionally introduce country-specific numeric comparisons. C: retain acceptance and warn in the console. | The product should choose A; a numeric matching change requires a separate decision. | `CAP-CRM-REG-004`, `CAP-CRM-REG-006`, `FND-CRM-REG-014` |
| `OQ-CRM-REG-003` | Should regions, the assignment policy and lock changes keep record history? | Staff and auditors cannot tell who changed a region, a rule or a lock, or recover a rule a whole-list save deleted, and the lock decision requires audit. | A: give regions and the policy record history with actor and source, as contacts and organizations have. B: record audit events only for lock changes and policy saves. C: keep last-modified stamps only. | The product should choose A, which also satisfies the lock audit when dedicated lock actions arrive. | `DOM-CRM-REG-001`, `DOM-CRM-REG-002`, `ADR-CRM-REG-010`, `FND-CRM-REG-025` |
| `OQ-CRM-REG-004` | Should region replacement follow the complete-payload rule decided for contacts and organizations? | Omission currently erases fields a client does not know, and imports and integrations replace regions too. | A: require every replaceable property, with null clearing and a missing property refused. B: keep omission as removal. C: treat omission as no change. | The product should choose A so every CRM replacement behaves the same way. | `ADR-CRM-REG-008`, `CAP-CRM-REG-001`, `FND-CRM-REG-024` |
| `OQ-CRM-REG-005` | How should a whole-policy save treat the versions of the rules it keeps? | Recreating retained rules at version one lets an older single-rule edit overwrite a newer rule. | A: update retained rules in place and advance their versions. B: retire the individual rule operations and keep only whole-policy saves. C: make individual rule writes also require the policy version. | The product should choose A, which keeps both editing styles safe without breaking API clients. | `ADR-CRM-REG-006`, `CAP-CRM-REG-004`, `CAP-CRM-REG-005`, `FND-CRM-REG-018`, `FND-CRM-REG-006` |
