---
id: ATS-PFM-NOT-010
scope: CAP-PFM-NOT-010
product_area: platform
module: notifications
revision: 2
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-PFM-NOT-010-01
    title: Read explanation only for an owned item
    level: api
    proves:
      - BR-CAP-PFM-NOT-010-01
    preconditions: Jane's notice and a colleague's.
    steps: Jane reads hers with its why; next the colleague's.
    expected: >-
      Personal detail returns channel selection, skipped reasons, audience rules
      and contribution lists; a colleague's item is not found.
    negative: true
    data_needs: Use only records created and owned by this suite.
    bound_to:
      - >-
        services-platform:modules/notifications/tests/e2e/notifications.e2e.spec.js#reads
        one of its own with its why, and nobody else’s
      - >-
        services-platform:modules/notifications/tests/integration/services/centre/notification-centre.integration.spec.js#answers
        the lists of a notification’s resolution as lists, whatever the stored
        resolution lacks
      - TST-PFM-NOT-069
      - TST-PFM-NOT-073
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/e2e/notifications.e2e.spec.js#reads
      one of its own with its why, and nobody else’s
    category: permission
    binding_scope: >-
      Each binding supplies its own assertions; the aggregate references do not
      imply that one executable file proves every step.
  - id: ATS-PFM-NOT-010-02
    title: Render readable audience reasons
    level: unit
    proves:
      - BR-CAP-PFM-NOT-010-02
    preconditions: >-
      Prepare every audience type, delegation with known and unnamed delegators,
      and responsibility fallback selection.
    steps: Render the explanation for each selection type.
    expected: Each recipient-rule type receives the corresponding product explanation.
    negative: false
    data_needs: Use only records created and owned by this suite.
    bound_to:
      - >-
        services-platform:modules/notifications/tests/unit/audience-planner.spec.js#says
        a person named directly was named directly
      - >-
        services-platform:modules/notifications/tests/unit/audience-planner.spec.js#says
        a holder holds the responsibility, by its label
      - >-
        services-platform:modules/notifications/tests/unit/audience-planner.spec.js#says
        a delegate covers the responsibility for the person they cover
      - >-
        services-platform:modules/notifications/tests/unit/audience-planner.spec.js#says
        a delegate whose delegator is unknown covers the responsibility
      - >-
        services-platform:modules/notifications/tests/unit/audience-planner.spec.js#says
        the responsibility fell back to the fallback’s holder
      - >-
        services-platform:modules/notifications/tests/unit/audience-planner.spec.js#says
        a role holder holds the role, by its name
      - >-
        services-platform:modules/notifications/tests/unit/audience-planner.spec.js#says
        a permission holder holds the permission, by its key
      - >-
        services-platform:modules/notifications/tests/integration/services/orchestration/resolve-audience.integration.spec.js#words
        a delegate’s reason as covering the responsibility for the person who
        delegated, and the holder’s as holding it
      - TST-PFM-NOT-080
      - TST-PFM-NOT-104
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/unit/audience-planner.spec.js#says
      a person named directly was named directly
    category: rule
    binding_scope: >-
      Each binding supplies its own assertions; the aggregate references do not
      imply that one executable file proves every step.
  - id: ATS-PFM-NOT-010-03
    title: Prefer the producer's supplied explanation
    level: api
    proves:
      - BR-CAP-PFM-NOT-010-03
    preconditions: >-
      Prepare a request whose audience entry carries a reason; one with a empty
      reason.
    steps: >-
      Process both audience-reason forms and inspect their recipient
      explanations.
    expected: >-
      A nonblank producer reason is displayed; blank input uses standard
      recipient wording.
    negative: false
    data_needs: Use only records created and owned by this suite.
    bound_to:
      - >-
        services-platform:modules/notifications/tests/unit/audience-planner.spec.js#uses
        the producer’s own words for the rule when the entry carries a reason
      - >-
        services-platform:modules/notifications/tests/unit/audience-planner.spec.js#falls
        back to the kind’s words when the reason is blank
      - >-
        services-platform:modules/notifications/tests/integration/services/centre/notification-centre.integration.spec.js#puts
        the producer’s reason in the words of the rule that reached the person
      - >-
        services-platform:modules/notifications/tests/integration/services/requests/submit-notification-request.integration.spec.js#accepts
        an audience reason and carries it to the words of the rule
      - TST-PFM-NOT-073
      - TST-PFM-NOT-102
      - TST-PFM-NOT-104
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/unit/audience-planner.spec.js#uses
      the producer’s own words for the rule when the entry carries a reason
    category: edge
    binding_scope: >-
      Each binding supplies its own assertions; the aggregate references do not
      imply that one executable file proves every step.
  - id: ATS-PFM-NOT-010-04
    title: Explain skipped channels consistently
    level: api
    proves:
      - BR-CAP-PFM-NOT-010-04
    preconditions: Prepare a notice with e-mail skipped until its milestone.
    steps: Retrieve the notice and its delivery summary.
    expected: >-
      Both explanation and delivery summary identify e-mail as awaiting its
      milestone.
    negative: false
    data_needs: Use only records created and owned by this suite.
    bound_to:
      - >-
        services-platform:modules/notifications/tests/integration/services/centre/notification-centre.integration.spec.js#says
        the milestone of a channel not yet available on the delivery summary, as
        the resolution does
      - >-
        services-platform:modules/notifications/tests/unit/channel-resolution.spec.js#words
        a skipped channel with the adapter’s own sentence when it has one
      - TST-PFM-NOT-073
      - TST-PFM-NOT-105
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/centre/notification-centre.integration.spec.js#says
      the milestone of a channel not yet available on the delivery summary, as
      the resolution does
    category: interaction
    binding_scope: >-
      Each binding supplies its own assertions; the aggregate references do not
      imply that one executable file proves every step.
  - id: ATS-PFM-NOT-010-05
    title: Display the explanation without raw reason tokens
    level: browser
    proves:
      - BR-CAP-PFM-NOT-010-05
    preconditions: Jane has received an item announcing her assignment.
    steps: Select the item's Why Did I Get This? action.
    expected: >-
      The sheet shows the producer reason, console delivery and unavailable
      e-mail explanation, with no raw token.
    negative: false
    data_needs: Use only records created and owned by this suite.
    bound_to:
      - >-
        react-console:components/notifications/__tests__/notifications.test.tsx#tells
        why in a sentence in the Why sheet
      - >-
        react-console:components/notifications/__tests__/notifications.test.tsx#words
        the milestone from the delivery summary while the resolution is not
        there yet
      - >-
        react-console:lib/notifications/__tests__/model.test.ts#never shows a
        token in the whole sentence
      - >-
        react-console:lib/notifications/__tests__/model.test.ts#joins several of
        the producer's reasons with and
      - >-
        react-console:acceptance/notifications/playwright/journeys/history/NT-ACC-0101.spec.ts#NT-ACC-0101
      - TST-PFM-NOT-003
      - TST-PFM-NOT-021
      - TST-PFM-NOT-022
    provenance: test
    source: >-
      react-console:components/notifications/__tests__/notifications.test.tsx#tells
      why in a sentence in the Why sheet
    category: rule
    binding_scope: >-
      Each binding supplies its own assertions; the aggregate references do not
      imply that one executable file proves every step.
  - id: ATS-PFM-NOT-010-06
    title: Inspect an assignment explanation in the console
    level: browser
    proves:
      - AS-JNY-PFM-NOT-001-03
    preconditions: Jane's assignment notice.
    steps: Display the recipient explanation sheet using Why Did I Get This?.
    expected: >-
      Jane sees the producer reason, console routing and the pending e-mail
      milestone.
    negative: false
    data_needs: The journey's own personas and Northeast unit.
    bound_to:
      - >-
        react-console:acceptance/notifications/playwright/journeys/history/NT-ACC-0101.spec.ts#NT-ACC-0101
      - TST-PFM-NOT-003
    provenance: test
    source: >-
      react-console:acceptance/notifications/playwright/journeys/history/NT-ACC-0101.spec.ts#NT-ACC-0101
    category: interaction
    binding_scope: >-
      Each binding supplies its own assertions; the aggregate references do not
      imply that one executable file proves every step.
  - id: ATS-PFM-NOT-010-07
    title: Personal and administrator explanations agree without expanding access
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-NOT-010-07
    exercises:
      - CAP-PFM-NOT-010
      - CAP-PFM-NOT-009
      - CAP-PFM-NOT-011
    preconditions: >-
      Prepare an explained responsibility notice and a second staff account
      lacking authority for its destination.
    steps: >-
      Read the notice personally and through administrator History, compare
      selection and channel explanations, then attempt its destination action as
      the second account.
    expected: >-
      Both read surfaces describe the same selection and skipped channels.
      Seeing an explanation supplies no authority for the destination action.
    negative: false
    data_needs: >-
      A suite-owned workspace, named staff accounts and unique occurrence keys;
      external adapters record attempts without shared writes.
    bound_to: []
    provenance: proposed
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-010-understand-why-i-was-told.md#frontmatter
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-009-work-through-my-own-notifications.md#frontmatter
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-011-see-what-the-organization-told-whom.md#frontmatter
    interaction_with:
      - CAP-PFM-NOT-009
      - CAP-PFM-NOT-011
evidence:
  - >-
    Pinned evidence inventory 1:
    services-platform:modules/notifications/tests/e2e/notifications.e2e.spec.js;
    services-platform:modules/notifications/tests/unit/audience-planner.spec.js;
    services-platform:modules/notifications/tests/integration/services/requests/submit-notification-request.integration.spec.js;
    react-console:components/notifications/__tests__/notifications.test.tsx;
    react-console:acceptance/notifications/playwright/journeys/history/NT-ACC-0101.spec.ts
  - >-
    Pinned evidence inventory 2:
    services-platform:modules/notifications/tests/integration/services/centre/notification-centre.integration.spec.js;
    services-platform:modules/notifications/tests/integration/services/orchestration/resolve-audience.integration.spec.js;
    services-platform:modules/notifications/tests/unit/channel-resolution.spec.js;
    react-console:lib/notifications/__tests__/model.test.ts
coverage:
  rule: covered
  transition: not-applicable
  validation: 'gap: FND-PFM-NOT-071'
  permission: covered
  edge: covered
  failure: 'gap: FND-PFM-NOT-071'
  boundary: 'gap: FND-PFM-NOT-071'
  concurrency: 'gap: FND-PFM-NOT-071'
  invariant: 'gap: FND-PFM-NOT-071'
  interaction: covered
coverage_notes:
  transition: >-
    This capability computes or reads an outcome and owns no lifecycle
    transition; state changes are tested in the owning capability.
  validation: Malformed input is not isolated in a dedicated category scenario.
  failure: The suite lacks an isolated dependency failure and recovery case.
  boundary: >-
    The suite does not independently prove both sides of every size, time or
    workspace limit.
  concurrency: >-
    The suite lacks a complete race case with controlled interleaving and
    post-race assertions.
  invariant: >-
    The suite does not isolate every persistent guarantee in a dedicated
    category scenario.
findings:
  - FND-PFM-NOT-071
transition_coverage: []
workflow_coverage: []
domain_invariant_coverage: []
---

# Explain notification selection and delivery: Capability Test Specification

## Coverage

Each scenario names the guarantee it proves. Category coverage describes specified cases; executable bindings retain their narrower assertion boundaries. Lifecycle coverage remains a gap wherever guards and effects lack independent verification.

| Rule | Proof |
|---|---|
| `BR-CAP-PFM-NOT-010-01` | `ATS-PFM-NOT-010-01`, `ATS-PFM-NOT-010-07` |
| `BR-CAP-PFM-NOT-010-02` | `ATS-PFM-NOT-010-02` |
| `BR-CAP-PFM-NOT-010-03` | `ATS-PFM-NOT-010-03` |
| `BR-CAP-PFM-NOT-010-04` | `ATS-PFM-NOT-010-04` |
| `BR-CAP-PFM-NOT-010-05` | `ATS-PFM-NOT-010-05` |

## Interactions With Related Capabilities

Prepare an explained responsibility notice and a second staff account lacking authority for its destination. Read the notice personally and through administrator History, compare selection and channel explanations, then attempt its destination action as the second account.

The interaction case combines the producing, processing and reading outcomes named in its frontmatter. It remains proposed until an executable suite performs that complete sequence.
