---
id: ATS-CRM-ENT-010
scope: CAP-CRM-ENT-010
product_area: crm
module: entities
revision: 1
status: proposed
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-CRM-ENT-010-01
    title: 'the workspace''s date decides, not UTC''s'
    level: api
    proves:
      - BR-CAP-CRM-ENT-010-01
      - BR-CAP-CRM-ENT-010-02
    preconditions: >-
      Prepare a workspace in a zone behind UTC and affiliations ending today and
      starting tomorrow.
    steps: >-
      Read and list the affiliations; save a primary starting on the workspace’s
      tomorrow; save one starting on its today.
    expected: >-
      Ending today is current; starting tomorrow is future; the first primary
      rejected; the second saved.
    negative: true
    data_needs: Use workspace time zone set.
    bound_to:
      - TST-CRM-ENT-790
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#refuses
      a primary starting on the tenant's tomorrow, though it is already UTC's
      and Sydney's today
    category: boundary
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#refuses
        a primary starting on the tenant's tomorrow, though it is already UTC's
        and Sydney's today
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#refuses
        a primary starting on the tenant's tomorrow, though it is already UTC's
        and Sydney's today
    test_anchors:
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#reads
        a tie ending on the tenant's today as current
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#reads
        a tie starting on the tenant's tomorrow, already UTC's today, as future
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#lists
        under current the ties effective on the tenant today, never the upcoming
        one
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#refuses
        a primary starting on the tenant's tomorrow, though it is already UTC's
        and Sydney's today
      - >-
        services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#starts
        the Organization field's primary on the tenant's today when the command
        names no date
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-010-02
    title: the console preserves to the workspace's day
    level: browser
    proves:
      - BR-CAP-CRM-ENT-010-03
    preconditions: Prepare a browser in a zone a day ahead of the workspace.
    steps: Open a contact's affiliations and add one near midnight.
    expected: >-
      Filters and counts match the service; the default start date is the
      workspace's today.
    negative: true
    data_needs: Use browser time zone override.
    bound_to:
      - TST-CRM-ENT-776
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0186.spec.ts#CRM-ACC-0186
    category: rule
    action_evidence:
      provenance: test
      source: >-
        react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0186.spec.ts#CRM-ACC-0186
    assertion_evidence:
      provenance: test
      source: >-
        react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0186.spec.ts#CRM-ACC-0186
    test_anchors:
      - >-
        react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0186.spec.ts#CRM-ACC-0186
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-010-03
    title: the window settles the right days
    level: unit
    proves:
      - BR-CAP-CRM-ENT-010-04
    preconditions: No additional setup is required.
    steps: >-
      Compute windows for a never-reconciled workspace, a skipped weekend, a
      settled day, a zone moved west.
    expected: Yesterday to today; every skipped day; nothing; nothing.
    negative: false
    data_needs: No additional fixtures.
    bound_to: []
    provenance: test
    source: >-
      services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#spans
      every day of a skipped weekend, so the next night makes them up
    category: boundary
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#spans
        every day of a skipped weekend, so the next night makes them up
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#spans
        every day of a skipped weekend, so the next night makes them up
    test_anchors:
      - >-
        services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#is
        yesterday to today for a tenant never reconciled, so switching the job
        on rewrites no history
      - >-
        services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#spans
        every day of a skipped weekend, so the next night makes them up
      - >-
        services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#is
        nothing for a day already settled
      - >-
        services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#is
        a boundary the night after its last day: a tie that ended yesterday has
        stopped today
      - >-
        services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#is
        not a boundary on its last day: a tie that ends today is still in effect
        today
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-010-04
    title: Starts and ends take effect without a save
    level: browser
    proves:
      - BR-CAP-CRM-ENT-010-05
    preconditions: >-
      Prepare a role ending yesterday and a affiliation starting today at
      organizations retained to rules.
    steps: Run the pass.
    expected: >-
      Compliance changes both ways; automatic roles given on the start day,
      never on the eve; every change listed with its reason.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-790
      - TST-CRM-ENT-776
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
      the organization out of compliance the next morning, with no save of the
      contact
    category: interaction
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact
    test_anchors:
      - >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact
      - >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#brings
        the organization into compliance on its start day, with no save of the
        contact
      - >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#gives
        the automatic roles on the start day and never on the eve
      - >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#names
        the organization, the contact and the reason of the change it made
      - >-
        react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0211.spec.ts#CRM-ACC-0211
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-010-05
    title: a pass is idempotent and only moves forward
    level: api
    proves:
      - BR-CAP-CRM-ENT-010-06
      - INV-DOM-CRM-ENT-033-14
    preconditions: Prepare a settled day.
    steps: Run again; retake an open window.
    expected: >-
      No record changes, the organization's version unmodified; the watermark
      only forward.
    negative: false
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-790
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#finds
      the day settled and changes nothing, the organization’s version included
    category: invariant
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#finds
        the day settled and changes nothing, the organization’s version included
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#finds
        the day settled and changes nothing, the organization’s version included
    test_anchors:
      - >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#finds
        the day settled and changes nothing, the organization’s version included
      - >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#on
        a window left open recalculates again and still writes nothing the first
        run wrote
      - >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#only
        moves forward
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-010-06
    title: On-demand runs need the bulk key; dry runs write nothing
    level: api
    proves:
      - BR-CAP-CRM-ENT-010-07
    preconditions: Prepare a caller with the bulk key and callers without.
    steps: >-
      Dry run; real run; real run naming a day; a bad day; an unknown property;
      callers with read or update only.
    expected: >-
      Window and changes, no record changes; settled; 400 each; 403 for the
      others.
    negative: true
    data_needs: No additional fixtures.
    bound_to:
      - TST-CRM-ENT-786
      - TST-CRM-ENT-790
    provenance: test
    source: >-
      services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
      a real run that names a day, 400 naming it
    category: permission
    action_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
        a real run that names a day, 400 naming it
    assertion_evidence:
      provenance: test
      source: >-
        services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
        a real run that names a day, 400 naming it
    test_anchors:
      - >-
        services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
        a caller who may only read contacts, 403
      - >-
        services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
        a caller who may update contacts but not run bulk work, 403
      - >-
        services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#answers
        a dry run to the holder of the bulk key, with the window and nothing
        changed
      - >-
        services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
        a real run that names a day, 400 naming it
      - >-
        services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
        a day that is not a calendar date, 400 naming it
      - >-
        services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
        a property it does not know, 400 naming it
      - >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#reports
        what the real run then writes, change for change
    binding_scope: >-
      contributions: the cited executable assertions collectively support only
      the observations they contain; additional matrix and journey checks remain
      proposed.
  - id: ATS-CRM-ENT-010-07
    title: the scheduled pass runs after the workspace's midnight where switched on
    level: api
    proves:
      - BR-CAP-CRM-ENT-010-08
    preconditions: >-
      Prepare a dev workspace with the switch on and an affiliation starting
      tomorrow.
    steps: Wait past the workspace's midnight without saving.
    expected: >-
      The affiliation is current, its roles given and compliance recalculated
      within one reconciler interval.
    negative: false
    data_needs: Use deployment with affiliationDateReconciliation=on.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:docs/affiliations/README.md#5.6b The overnight date
      reconciliation (D-46; CRM-M2 A6 and A7)
    category: transition
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:docs/affiliations/README.md#5.6b The overnight date
        reconciliation (D-46; CRM-M2 A6 and A7)
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:docs/affiliations/README.md#5.6b The overnight date
        reconciliation (D-46; CRM-M2 A6 and A7)
    test_anchors: []
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-010-08
    title: Keep a failed compliance day available for another pass
    category: failure
    level: api
    proves:
      - BR-CAP-CRM-ENT-010-06
    preconditions: >-
      A workspace has an unsettled date window and an organization needing
      recalculation.
    steps: >-
      Cause that organization’s recalculation to fail; inspect the watermark;
      remove the fault and repeat the pass.
    expected: >-
      The failed pass does not mark that compliance window settled; the retry
      reaches the previously failing organization.
    negative: true
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
      the organization out of compliance the next morning, with no save of the
      contact
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-010-09
    title: Apply a future tie’s selected contact-point defaults
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-006-12
      - BR-CAP-CRM-ENT-010-05
    preconditions: >-
      A future affiliation has pending selected mappings and empty destination
      purposes.
    steps: >-
      Run a date pass before its start, then on its local start day; read the
      person after each pass.
    expected: >-
      The early pass makes no links; the due pass fills the selected
      destinations once.
    negative: false
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.follow-ups.integration.spec.js#links
      every default of its type on the start day when the save stated no choice;
      services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
      the organization out of compliance the next morning, with no save of the
      contact
    exercises:
      - CAP-CRM-ENT-006
      - CAP-CRM-ENT-010
    workflows:
      - WF-CRM-ENT-002
      - WF-CRM-ENT-006
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.follow-ups.integration.spec.js#links
        every default of its type on the start day when the save stated no
        choice;
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.follow-ups.integration.spec.js#links
        every default of its type on the start day when the save stated no
        choice;
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-010-10
    title: Keep a one-day affiliation current on its last day
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-009-07
      - BR-CAP-CRM-ENT-010-02
    preconditions: >-
      A person has an affiliation whose start and end are the same workspace
      date.
    steps: Read the people list on that date and again on the next workspace date.
    expected: The tie is current on its single day and past on the following day.
    negative: false
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/contacts.integration.spec.js#refuses
      an affiliation that ends before it starts;
      services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#reads
      a tie ending on the tenant's today as current
    exercises:
      - CAP-CRM-ENT-009
      - CAP-CRM-ENT-010
    workflows:
      - WF-CRM-ENT-002
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.integration.spec.js#refuses
        an affiliation that ends before it starts;
        services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#reads
        a tie ending on the tenant's today as current
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/persistence/contacts.integration.spec.js#refuses
        an affiliation that ends before it starts;
        services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#reads
        a tie ending on the tenant's today as current
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-010-11
    title: Due dates settle automatic responsibilities
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-010-05
      - BR-CAP-CRM-ENT-011-07
    preconditions: A future affiliation has an eligible active automatic role.
    steps: 'Reconcile before the local start day, then on that day and once again.'
    expected: >-
      No role is assigned early; the due pass assigns it and the repeated pass
      adds no duplicate.
    negative: false
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
      the organization out of compliance the next morning, with no save of the
      contact;
      services-crm:modules/entities/tests/integration/services/contacts/role-assignment/automatic-role-reconciliation.integration.spec.js#gives
      the automatic and first-contact roles on the start day in the tenant
      calendar
    exercises:
      - CAP-CRM-ENT-010
      - CAP-CRM-ENT-011
    workflows:
      - WF-CRM-ENT-002
      - WF-CRM-ENT-006
      - WF-CRM-ENT-007
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact;
        services-crm:modules/entities/tests/integration/services/contacts/role-assignment/automatic-role-reconciliation.integration.spec.js#gives
        the automatic and first-contact roles on the start day in the tenant
        calendar
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact;
        services-crm:modules/entities/tests/integration/services/contacts/role-assignment/automatic-role-reconciliation.integration.spec.js#gives
        the automatic and first-contact roles on the start day in the tenant
        calendar
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-010-12
    title: An expired role changes organizational coverage
    category: interaction
    level: api
    proves:
      - BR-CAP-CRM-ENT-010-05
      - BR-CAP-CRM-ENT-012-03
    preconditions: An organization meets its minimum through a role ending today.
    steps: >-
      Read coverage on the inclusive end day; reconcile the next local day and
      reread coverage.
    expected: >-
      Coverage remains satisfied through the last day and becomes deficient
      after the ended role no longer counts.
    negative: false
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
      the organization out of compliance the next morning, with no save of the
      contact;
      services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#brings
      an organization into compliance for a role held on a current affiliation
      that is not primary
    exercises:
      - CAP-CRM-ENT-010
      - CAP-CRM-ENT-012
    workflows:
      - WF-CRM-ENT-006
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact;
        services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#brings
        an organization into compliance for a role held on a current affiliation
        that is not primary
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
        the organization out of compliance the next morning, with no save of the
        contact;
        services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#brings
        an organization into compliance for a role held on a current affiliation
        that is not primary
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
  - id: ATS-CRM-ENT-010-13
    title: Exercise every declared authority independently
    category: permission
    level: api
    proves:
      - BR-CAP-CRM-ENT-010-07
    preconditions: >-
      An eligible record and configuration fixture exist for each operation; the
      caller can reach only the run’s workspace.
    steps: >-
      For each declared permission, execute its matching operation with that
      permission, then without it while retaining the other required grants.
      Read affected records after every refused mutation.
    expected: >-
      The authorized case reaches the operation; the missing-grant case is
      refused and preserves saved data. Record access alone does not authorize
      the other declared actions.
    negative: true
    data_needs: Run-owned records and configuration in an isolated workspace.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:aws/crm.service.ts:ApplicationPermissions;
      services-crm:modules/entities/aws/api/entities.routes.ts
    permission_keys:
      - crm.contacts.bulk
      - crm.contacts.read
    test_anchors: []
    action_evidence:
      provenance: proposed
      source: >-
        services-crm:aws/crm.service.ts:ApplicationPermissions;
        services-crm:modules/entities/aws/api/entities.routes.ts
    assertion_evidence:
      provenance: proposed
      source: >-
        services-crm:aws/crm.service.ts:ApplicationPermissions;
        services-crm:modules/entities/aws/api/entities.routes.ts
    binding_scope: 'unbound: the detailed scenario still needs executable proof.'
evidence:
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#refuses
    a primary starting on the tenant's tomorrow, though it is already UTC's and
    Sydney's today
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#reads
    a tie ending on the tenant's today as current
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#reads
    a tie starting on the tenant's tomorrow, already UTC's today, as future
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#lists
    under current the ties effective on the tenant today, never the upcoming one
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#starts
    the Organization field's primary on the tenant's today when the command
    names no date
  - >-
    react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0186.spec.ts#CRM-ACC-0186
  - >-
    services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#spans
    every day of a skipped weekend, so the next night makes them up
  - >-
    services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#is
    yesterday to today for a tenant never reconciled, so switching the job on
    rewrites no history
  - >-
    services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#is
    nothing for a day already settled
  - >-
    services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#is
    a boundary the night after its last day: a tie that ended yesterday has
    stopped today
  - >-
    services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#is
    not a boundary on its last day: a tie that ends today is still in effect
    today
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
    the organization out of compliance the next morning, with no save of the
    contact
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#brings
    the organization into compliance on its start day, with no save of the
    contact
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#gives
    the automatic roles on the start day and never on the eve
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#names
    the organization, the contact and the reason of the change it made
  - >-
    react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0211.spec.ts#CRM-ACC-0211
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#finds
    the day settled and changes nothing, the organization’s version included
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#on
    a window left open recalculates again and still writes nothing the first run
    wrote
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#only
    moves forward
  - >-
    services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
    a real run that names a day, 400 naming it
  - >-
    services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
    a caller who may only read contacts, 403
  - >-
    services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
    a caller who may update contacts but not run bulk work, 403
  - >-
    services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#answers
    a dry run to the holder of the bulk key, with the window and nothing changed
  - >-
    services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
    a day that is not a calendar date, 400 naming it
  - >-
    services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses
    a property it does not know, 400 naming it
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#reports
    what the real run then writes, change for change
  - >-
    services-crm:docs/affiliations/README.md#5.6b The overnight date
    reconciliation (D-46; CRM-M2 A6 and A7)
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.follow-ups.integration.spec.js#links
    every default of its type on the start day when the save stated no choice;
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
    the organization out of compliance the next morning, with no save of the
    contact
  - >-
    services-crm:modules/entities/tests/integration/services/persistence/contacts.integration.spec.js#refuses
    an affiliation that ends before it starts;
    services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#reads
    a tie ending on the tenant's today as current
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
    the organization out of compliance the next morning, with no save of the
    contact;
    services-crm:modules/entities/tests/integration/services/contacts/role-assignment/automatic-role-reconciliation.integration.spec.js#gives
    the automatic and first-contact roles on the start day in the tenant
    calendar
  - >-
    services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
    the organization out of compliance the next morning, with no save of the
    contact;
    services-crm:modules/entities/tests/integration/services/organizations/compliance/organization-compliance.integration.spec.js#brings
    an organization into compliance for a role held on a current affiliation
    that is not primary
  - >-
    services-crm:aws/crm.service.ts:ApplicationPermissions;
    services-crm:modules/entities/aws/api/entities.routes.ts
coverage:
  rule: covered
  transition: covered
  validation: 'gap: FND-CRM-ENT-058'
  permission: covered
  edge: 'gap: FND-CRM-ENT-058'
  failure: covered
  boundary: covered
  concurrency: 'gap: FND-CRM-ENT-058'
  invariant: covered
  interaction: covered
previous_approval:
  revision: 1
  approved_by: Andrew
  approved_at: '2026-10-22T00:00:00.000Z'
transition_coverage:
  - state_model: STATE-CRM-ENT-005
    from: upcoming
    to: current
    scenarios:
      - ATS-CRM-ENT-010-01
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/design/state-models/STATE-CRM-ENT-005-affiliation-and-role-period-lifecycle.md:transitions
coverage_notes:
  validation:
    reason: >-
      No detailed validation scenario currently specifies this aspect; the
      coverage finding records the required follow-through.
    provenance: unknown
    source: FND-CRM-ENT-058
  edge:
    reason: >-
      No detailed edge scenario currently specifies this aspect; the coverage
      finding records the required follow-through.
    provenance: unknown
    source: FND-CRM-ENT-058
  concurrency:
    reason: >-
      No detailed concurrency scenario currently specifies this aspect; the
      coverage finding records the required follow-through.
    provenance: unknown
    source: FND-CRM-ENT-058
coverage_findings:
  - FND-CRM-ENT-058
  - FND-CRM-ENT-075
permission_coverage:
  - key: crm.contacts.bulk
    where_checked: api
    scenario: ATS-CRM-ENT-010-13
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-010-keep-affiliations-true-to-the-workspace-s-calendar.md
  - key: crm.contacts.read
    where_checked: api
    scenario: ATS-CRM-ENT-010-13
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-010-keep-affiliations-true-to-the-workspace-s-calendar.md
related_coverage:
  - capability: CAP-CRM-ENT-006
    scenarios:
      - ATS-CRM-ENT-010-09
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-010-keep-affiliations-true-to-the-workspace-s-calendar.md:related
  - capability: CAP-CRM-ENT-009
    scenarios:
      - ATS-CRM-ENT-010-10
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-010-keep-affiliations-true-to-the-workspace-s-calendar.md:related
  - capability: CAP-CRM-ENT-011
    scenarios:
      - ATS-CRM-ENT-010-11
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-010-keep-affiliations-true-to-the-workspace-s-calendar.md:related
  - capability: CAP-CRM-ENT-012
    scenarios:
      - ATS-CRM-ENT-010-12
    provenance: documented
    source: >-
      rhythm-v2-docs:specs/crm/entities/planning/capabilities/CAP-CRM-ENT-010-keep-affiliations-true-to-the-workspace-s-calendar.md:related
examination_evidence:
  provenance: documented
  source: 'rhythm-v2-docs:specs/crm/entities/reports/EXAMINATION-2026-10-23.md'
  heading_conflict: FND-CRM-ENT-075
---

# Keep dated relationships current
## Coverage

The category map separates specified cases from recorded gaps. A proposed case describes proof to implement; a binding identifies the assertions supplied by an existing executable file. The permission and transition ledgers record the individual checks needed for the capability.

| Required rule | Scenario or finding |
|---|---|
| `BR-CAP-CRM-ENT-010-01` | `ATS-CRM-ENT-010-01` |
| `BR-CAP-CRM-ENT-010-02` | `ATS-CRM-ENT-010-01`, `ATS-CRM-ENT-010-10` |
| `BR-CAP-CRM-ENT-010-03` | `ATS-CRM-ENT-010-02` |
| `BR-CAP-CRM-ENT-010-04` | `ATS-CRM-ENT-010-03` |
| `BR-CAP-CRM-ENT-010-05` | `ATS-CRM-ENT-010-04`, `ATS-CRM-ENT-010-09`, `ATS-CRM-ENT-010-11`, `ATS-CRM-ENT-010-12` |
| `BR-CAP-CRM-ENT-010-06` | `ATS-CRM-ENT-010-05`, `ATS-CRM-ENT-010-08` |
| `BR-CAP-CRM-ENT-010-07` | `ATS-CRM-ENT-010-06`, `ATS-CRM-ENT-010-13` |
| `BR-CAP-CRM-ENT-010-08` | `ATS-CRM-ENT-010-07` |

## Interactions With Related Capabilities

The interaction scenarios exercise share organization contact points with affiliated people; maintain a person’s organizational relationships; maintain responsibilities on organizational relationships; review organization role compliance and prepare notices. They change one part of a prepared record and inspect the dependent outcome. Unbound interactions remain proposed rather than implying an existing end-to-end implementation.

## Source Evidence

The frontmatter pins the repositories and identifies the source anchors for each scenario. Bindings record inspected assertions, while unbound cases remain proposed. Source inspection supplies no execution result or product approval.
