---
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
finding_evidence:
  - finding: FND-PFM-NOT-001
    source: >-
      services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#D1. How
      Rhythm's own staff (HQ) receive notifications;
      modules/notifications/services/system-scope/ensure-system-scope.ts;
      modules/notifications/notifications.settings.ts:RHYTHM_SYSTEM_TENANT_ID;
      docs/forge-handoff/notifications.md#C. Decisions (assumptions; open
      question 6)
  - finding: FND-PFM-NOT-002
    source: >-
      services-platform:docs/milestones/PLAT-M23-notifications-core-and-in-app.md
      (Plan row); docs/notifications.md (opening paragraph);
      docs/milestones/plans/ (only PLAT-M23-plan.humanized.md present);
      react-console:acceptance/notifications/README.md
  - finding: FND-PFM-NOT-003
    source: >-
      react-console:components/console/alerts-popover.tsx (no notifications
      section);
      services-platform:docs/proposals/notifications/23-decisions.md#D-06;
      docs/forge-handoff/notifications.md#F. Remaining work (item 4)
  - finding: FND-PFM-NOT-004
    source: >-
      services-platform:docs/milestones/PLAT-M23-notifications-core-and-in-app.md#Runs
      (run fleetntm23r4c); docs/forge-handoff/notifications.md#D. Current state;
      modules/notifications/tests/provider/slack-system.provider.spec.ts
  - finding: FND-PFM-NOT-005
    source: >-
      services-platform:modules/notifications/db/notification-preferences.table.ts
      and the eight sibling tables;
      modules/notifications/services/orchestration/orchestrate-request.ts
      (header comment: every definition counts as enabled);
      docs/milestones/plans/PLAT-M23-plan.humanized.md#2. Scope (Out);
      docs/milestones/PLAT-M25-notifications-preferences-and-identities.md
      (Proposed, no plan)
  - finding: FND-PFM-NOT-006
    source: >-
      services-platform:modules/notifications/notifications.settings.ts:REQUEST_OUTCOMES;
      modules/notifications/services/orchestration/orchestrate-request.ts
  - finding: FND-PFM-NOT-007
    source: >-
      react-console:acceptance/notifications/reports/defects/notifications.md
      (DEF-NT-0015); components/notifications/notification-chain-sheet.tsx
  - finding: FND-PFM-NOT-008
    source: >-
      react-console:acceptance/notifications/reports/defects/notifications.md
      (DEF-NT-0009);
      acceptance/notifications/playwright/journeys/inbox/NT-ACC-0005.spec.ts#NT-ACC-0005
  - finding: FND-PFM-NOT-009
    source: >-
      services-platform:docs/forge-handoff/notifications.md#B. Implementation
      inventory (Infrastructure)
  - finding: FND-PFM-NOT-010
    source: >-
      services-platform:docs/debt/notifications-system-audience-in-the-producer-library.md;
      modules/notifications/services/requests/publish-system-notification.ts
  - finding: FND-PFM-NOT-011
    source: >-
      specs/PRODUCT-AREAS.md (MOD-PFM-NOT row as registered);
      react-console:app/(console)/console/[tenantId]/alerts/page.tsx (a redirect
      to attention);
      app/(console)/console/[tenantId]/settings/notifications/page.tsx;
      app/(console)/hq/notifications/page.tsx; components/notifications/;
      lib/notifications/
  - finding: FND-PFM-NOT-012
    source: >-
      services-platform:docs/milestones/ (no communications milestone);
      docs/communications/architecture.md#15. Decisions for Andrew, #2026-10-09
      — Final acceptance, #20. Caller-rendered purposes (2026-10-17), #21. The
      marketing lane (MKT-M1, 2026-10-21), #22. Owned-template purposes (MKT-M1
      F2, 2026-10-21)
  - finding: FND-PFM-NOT-013
    source: >-
      services-platform:docs/communications/architecture.md (headings "22.
      Owned-template purposes" and "22. Staff notifications")
  - finding: FND-PFM-NOT-014
    source: >-
      services-platform:docs/communications/architecture.md#2026-10-09 — Final
      acceptance;
      react-console:app/(console)/console/[tenantId]/settings/notifications/page.tsx
  - finding: FND-PFM-NOT-015
    source: >-
      services-platform:docs/communications/architecture.md#21.3 The 24-hour
      quota brake (Not built: tenant fairness)
  - finding: FND-PFM-NOT-016
    source: >-
      services-platform:docs/debt/owned-template-requesting-service.md;
      docs/communications/architecture.md#22. Owned-template purposes (MKT-M1
      F2, 2026-10-21)
  - finding: FND-PFM-NOT-017
    source: >-
      services-platform:docs/proposals/notifications/23-decisions.md#D-04;
      modules/notifications/tests/unit/audience-planner.spec.js#plans a system
      audience in the Rhythm system scope as one lookup that resolves no people
  - finding: FND-PFM-NOT-018
    source: >-
      services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#2.
      Scope (the Rhythm-wide HQ scope bullet) and #D1;
      docs/forge-handoff/notifications.md#C. Decisions (open question 5)
  - finding: FND-PFM-NOT-019
    source: >-
      services-platform:aws/platform.service.ts:HQ_NOTIFICATIONS_PERMISSIONS
      (comment); modules/notifications/tests/unit/permissions.spec.js
  - finding: FND-PFM-NOT-020
    source: >-
      services-platform:docs/notifications.md#9. Producers;
      docs/forge-handoff/notifications.md#C. Decisions (open question 4)
  - finding: FND-PFM-NOT-021
    source: >-
      services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#4.
      Assumptions (A4); docs/proposals/notifications/23-decisions.md#D-06
  - finding: FND-PFM-NOT-022
    source: >-
      services-platform:docs/forge-handoff/notifications.md#B. Implementation
      inventory (Producers, Tests):
      modules/responsibilities/responsibilities-notifications.ts,
      services/notices/responsibility-notices.ts and
      modules/responsibilities/tests/**/responsibilities-notifications* (outside
      this module's read scope)
  - finding: FND-PFM-NOT-023
    source: >-
      services-platform:docs/notifications.md#6. The pipeline (The test hook of
      the responsibilities routes)
  - finding: FND-PFM-NOT-024
    source: >-
      services-platform:modules/communications/db/communication-message-events.table.ts
      (header comment: partitioned by month, retention by dropping partitions);
      docs/communications/architecture.md#16.2 Differences from the design, and
      why; no registration of the table with the partition manager was found in
      the module
  - finding: FND-PFM-NOT-025
    source: >-
      rhythm-v2-docs:briefs/planning/platform-notifications.brief.md (absent at
      starting commit)
  - finding: FND-PFM-NOT-026
    source: >-
      react-console:acceptance/notifications/playwright/journeys/inbox/NT-ACC-0001.spec.ts;
      services-platform:modules/notifications/tests/unit/render-message.spec.js
  - finding: FND-PFM-NOT-027
    source: >-
      services-platform:modules/notifications/services/registration/register-service-notifications.ts:cancelRetiredRequests
  - finding: FND-PFM-NOT-028
    source: >-
      services-platform:modules/notifications/services/dispatch/deliver-delivery.ts:deliverQueuedDelivery
  - finding: FND-PFM-NOT-029
    source: >-
      services-platform:modules/notifications/services/orchestration/orchestrate-request.ts:rerenderMessage
  - finding: FND-PFM-NOT-030
    source: >-
      services-platform:modules/communications/services/persistence/messages.ts:claimMessageForSubmission;
      modules/communications/tests/integration/services/persistence/messages.integration.spec.js#claims
      it again once the ambiguity window has passed, the unknown attempt closed
  - finding: FND-PFM-NOT-031
    source: >-
      services-platform:modules/communications/services/sender-identity/provision-sender-identity.ts:purgeSenderIdentityIdentities;
      modules/communications/services/sender-identity/ses-identity-store.ts
  - finding: FND-PFM-NOT-032
    source: >-
      services-platform:docs/forge-handoff/notifications.md;
      docs/communications/architecture.md#2026-10-09 — Final acceptance;
      react-console:app/(console)/console/[tenantId]/settings/notifications/page.tsx
  - finding: FND-PFM-NOT-033
    source: >-
      services-platform:docs/communications/architecture.md#20. Caller-rendered
      purposes; #21. The marketing lane; #22. Owned-template purposes
  - finding: FND-PFM-NOT-034
    source: >-
      services-platform:modules/notifications/aws/logic/notifications-functions.lambda.ts:NOTIFICATIONS_FUNCTIONS
  - finding: FND-PFM-NOT-035
    source: >-
      services-platform:modules/communications/services/requests/handle-invocation.ts:run
  - finding: FND-PFM-NOT-036
    source: >-
      services-platform:modules/notifications/services/centre/hq-notifications.ts:listDeadLetters;
      modules/notifications/services/centre/hq-notifications.ts:retryDeadDelivery;
      modules/notifications/services/centre/notification-centre.ts:toDeliveryRecord;
      modules/notifications/aws/api/notifications.routes.ts
  - finding: FND-PFM-NOT-037
    source: >-
      services-platform:modules/notifications/services/registration/register-service-notifications.ts:cancelRetiredRequests;
      modules/notifications/services/persistence/requests.ts:cancelOpenRequestsOfDefinition
      (header: "The instances and deliveries of those requests are the
      orchestrator's to supersede");
      modules/notifications/services/persistence/instances.ts:markInstancesSuperseded
      (no caller in the module's services);
      modules/notifications/services/dispatch/deliver-delivery.ts:deliverQueuedDelivery
      (checks the notice status and the request's expiry, not the request's
      outcome)
  - finding: FND-PFM-NOT-038
    source: >-
      specs/CONVENTIONS.md#9.8 Inference Operation (`IOP`);
      specs/platform/notifications/MODULE.md;
      services-platform:modules/notifications and modules/communications (no
      call into the LLM module or a model provider);
      react-console:components/notifications, lib/notifications
  - finding: FND-PFM-NOT-039
    source: >-
      services-platform:modules/tenants/aws/api/tenants.routes.ts:getHqTenantEmailSender
      (GET that calls refreshSenderIdentityVerification);
      modules/communications/services/sender-identity/provision-sender-identity.ts:refreshSenderIdentityVerification
  - finding: FND-PFM-NOT-040
    source: >-
      services-platform:modules/notifications/notifications.settings.ts:INSTANCE_STATUSES,
      DELIVERY_STATUSES; modules/notifications/services (no path writes an
      instance status cancelled or a delivery status deferred)
  - finding: FND-PFM-NOT-041
    source: >-
      services-platform:modules/notifications/services/persistence/deliveries.ts:settleAmbiguousDeliveries;
      modules/notifications/services/reconcile/reconcile-tenant.ts;
      modules/communications/services/persistence/messages.ts:claimMessageForSubmission;
      docs/communications/architecture.md#7.5 The ambiguous case: SES accepted
      but we did not record it
  - finding: FND-PFM-NOT-042
    source: >-
      services-platform:modules/notifications/services/dispatch/dispatch-notifications.ts
      (queue entries deleted once published);
      modules/notifications/services/orchestration/orchestrate-request.ts (the
      request record is written only in the orchestration transaction);
      modules/notifications/services/reconcile/reconcile-tenant.ts (expired
      unprocessed work is found only among undispatched queue entries);
      modules/notifications/aws/resources/notifications-queues.sqs.ts
  - finding: FND-PFM-NOT-043
    source: >-
      services-platform:modules/communications/db/communication-templates.table.ts
      (no actor column for draft edits or archiving);
      modules/communications/db/communication-template-versions.table.ts:published_by_id;
      modules/notifications/services/persistence/template-overrides.ts (header:
      publish and deactivation are audited)
  - finding: FND-PFM-NOT-044
    source: >-
      services-platform:modules/notifications/services/dispatch/deliver-delivery.ts:deliverQueuedDelivery;
      modules/notifications/services/reconcile/reconcile-tenant.ts:reconcileTenant
    provenance: observed
  - finding: FND-PFM-NOT-045
    source: >-
      services-platform:modules/communications/services/feedback/process-ses-event.ts:processSesEvent;
      modules/communications/services/persistence/messages.ts:recordMessageEvent
    provenance: observed
  - finding: FND-PFM-NOT-046
    source: >-
      services-platform:modules/notifications/services/persistence/identities.ts:transitionIdentity;
      modules/notifications/services/persistence/digests.ts:settleDigest
    provenance: observed
  - finding: FND-PFM-NOT-047
    source: >-
      react-console:components/notifications/notification-chain-sheet.tsx:NotificationChainSheet;
      react-console:lib/notifications/use-notifications.ts:useNotificationChain;
      services-platform:modules/notifications/aws/api/notifications.routes.ts
    provenance: observed
  - finding: FND-PFM-NOT-048
    source: >-
      rhythm-v2-docs:briefs/design/platform-notifications.brief.md (absent at
      starting commit)
    provenance: observed
  - finding: FND-PFM-NOT-049
    source: >-
      services-platform:docs/notifications.md#9. Producers;
      services-platform:docs/communications/architecture.md#16.7 A record
      composes a template it owns;
      rhythm-v2-docs:specs/platform/notifications/MODULE.md:repositories
    provenance: documented
  - finding: FND-PFM-NOT-050
    provenance: observed
    source: >-
      services-platform:modules/communications/services/templates/owned-templates.ts:mergeContent;
      services-platform:modules/communications/services/templates/owned-templates.ts:publishIfChanged;
      services-platform:modules/communications/services/persistence/templates.ts:replaceOwnedTemplateDraft
  - finding: FND-PFM-NOT-051
    provenance: observed
    source: >-
      services-platform:modules/communications/services/templates/template-publishing.ts:publishTemplate;
      services-platform:modules/communications/services/persistence/templates.ts:publishTemplateDraft;
      services-platform:modules/communications/services/persistence/templates.ts:updateTemplateDraft
  - finding: FND-PFM-NOT-052
    provenance: observed
    source: >-
      services-platform:modules/communications/services/dispatch/process-communication-request.ts:processCommunicationRequest;
      rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-018-deliver-association-e-mail-reliably-and-within-sending.md
  - finding: FND-PFM-NOT-062
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-001-register-the-kinds-of-notification-an-application-can-send.md
    missing_categories:
      - transition
      - edge
      - concurrency
    unproved_rules: []
    permissions_to_audit:
      - hq.notifications.read
    state_transitions:
      - state_model: STATE-PFM-NOT-001
        transition_index: 1
        from: undeclared
        to: active
        trigger: A release submits its notification manifest.
        source: >-
          services-platform:modules/notifications/tests/integration/services/registration/register-service-notifications.integration.spec.js#refuses
          a key that belongs to another application
        existing_candidates:
          - ATS-PFM-NOT-001-09
          - ATS-PFM-NOT-001-10
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-001
        transition_index: 2
        from: active
        to: active
        trigger: A subsequent release includes the definition.
        source: >-
          services-platform:modules/notifications/tests/integration/services/registration/register-service-notifications.integration.spec.js#refuses
          a category that changes between releases, telling the owner to re-key
          the definition
        existing_candidates:
          - ATS-PFM-NOT-001-09
          - ATS-PFM-NOT-001-10
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-001
        transition_index: 3
        from: active
        to: retired
        trigger: A valid release removes the definition from its manifest.
        source: >-
          services-platform:modules/notifications/services/registration/register-service-notifications.ts:cancelRetiredRequests;
          services-platform:modules/notifications/services/persistence/requests.ts:cancelOpenRequestsOfDefinition
        existing_candidates:
          - ATS-PFM-NOT-001-09
          - ATS-PFM-NOT-001-10
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-001
        transition_index: 4
        from: retired
        to: active
        trigger: A release restores a retired declaration.
        source: >-
          services-platform:modules/notifications/services/persistence/definitions.ts:upsertDefinition
        existing_candidates:
          - ATS-PFM-NOT-001-09
          - ATS-PFM-NOT-001-10
        decision: 'gap: independent guard and side-effect proof has not been verified'
  - finding: FND-PFM-NOT-063
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-002-tell-people-that-something-happened-with-one-call.md
    missing_categories:
      - rule
      - edge
      - failure
      - concurrency
    unproved_rules: []
    permissions_to_audit:
      - platform.notifications.publish
    state_transitions: []
  - finding: FND-PFM-NOT-064
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-003-reach-the-right-people-and-only-people-of-the-organization.md
    missing_categories:
      - edge
      - failure
      - concurrency
    unproved_rules: []
    permissions_to_audit: []
    state_transitions: []
  - finding: FND-PFM-NOT-065
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-004-word-each-notice-for-the-person-who-receives-it.md
    missing_categories:
      - validation
      - edge
      - failure
      - concurrency
    unproved_rules: []
    permissions_to_audit: []
    state_transitions: []
  - finding: FND-PFM-NOT-066
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-005-fold-quick-repeats-into-one-notice.md
    missing_categories:
      - validation
      - failure
    unproved_rules: []
    permissions_to_audit: []
    state_transitions: []
  - finding: FND-PFM-NOT-067
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-006-withdraw-or-expire-a-notice-that-no-longer-applies.md
    missing_categories:
      - rule
      - transition
      - validation
      - failure
      - concurrency
      - invariant
    unproved_rules: []
    permissions_to_audit: []
    state_transitions:
      - state_model: STATE-PFM-NOT-002
        transition_index: 1
        from: queued
        to: open
        trigger: The processor accepts queued work.
        source: >-
          services-platform:modules/notifications/tests/integration/services/orchestration/orchestrate-request.integration.spec.js#writes
          the console delivery delivered at once and records every other
          supported channel as not available until its milestone
        existing_candidates:
          - ATS-PFM-NOT-006-01
          - ATS-PFM-NOT-006-02
          - ATS-PFM-NOT-006-04
          - ATS-PFM-NOT-006-07
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-002
        transition_index: 2
        from: queued
        to: queued
        trigger: The processor encounters work scheduled for later.
        source: >-
          services-platform:modules/notifications/tests/integration/services/dispatch/process-request-batch.integration.spec.js#replaces
          a request that is not due with a fresh delayed copy when the next
          receive would be the last
        existing_candidates:
          - ATS-PFM-NOT-006-01
          - ATS-PFM-NOT-006-02
          - ATS-PFM-NOT-006-04
          - ATS-PFM-NOT-006-07
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-002
        transition_index: 3
        from: queued
        to: no recipients
        trigger: Audience resolution produces an empty result.
        source: >-
          services-platform:modules/notifications/tests/integration/services/orchestration/orchestrate-request.integration.spec.js#notifies
          nobody when everyone named is outside the organization, recording
          no_recipients with the refusal
        existing_candidates:
          - ATS-PFM-NOT-006-01
          - ATS-PFM-NOT-006-02
          - ATS-PFM-NOT-006-04
          - ATS-PFM-NOT-006-07
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-002
        transition_index: 4
        from: queued
        to: invalid
        trigger: Acceptance validation rejects the request.
        source: >-
          services-platform:modules/notifications/tests/integration/services/orchestration/orchestrate-request.integration.spec.js#records
          an unknown definition as invalid
        existing_candidates:
          - ATS-PFM-NOT-006-01
          - ATS-PFM-NOT-006-02
          - ATS-PFM-NOT-006-04
          - ATS-PFM-NOT-006-07
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-002
        transition_index: 5
        from: queued
        to: expired
        trigger: Processing or reconciliation detects an elapsed deadline.
        source: >-
          services-platform:modules/notifications/tests/integration/services/orchestration/orchestrate-request.integration.spec.js#expires
          a request older than its definition’s expires_after from the instant
          the producer wrote it
        existing_candidates:
          - ATS-PFM-NOT-006-01
          - ATS-PFM-NOT-006-02
          - ATS-PFM-NOT-006-04
          - ATS-PFM-NOT-006-07
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-002
        transition_index: 6
        from: queued
        to: cancelled
        trigger: >-
          Withdrawal arrives before acceptance, or processing discovers a later
          replacement-key cancellation.
        source: >-
          services-platform:modules/notifications/tests/integration/services/orchestration/cancel-and-supersede.integration.spec.js#leaves
          nobody told and records the request cancelled when the cancel names
          the publish’s key
        existing_candidates:
          - ATS-PFM-NOT-006-01
          - ATS-PFM-NOT-006-02
          - ATS-PFM-NOT-006-04
          - ATS-PFM-NOT-006-07
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-002
        transition_index: 7
        from: open
        to: superseded
        trigger: An open request is withdrawn or replaced by an accepted occurrence.
        source: >-
          services-platform:modules/notifications/tests/integration/services/orchestration/cancel-and-supersede.integration.spec.js#marks
          the instance superseded, leaves it readable and takes it out of the
          unread count
        existing_candidates:
          - ATS-PFM-NOT-006-01
          - ATS-PFM-NOT-006-02
          - ATS-PFM-NOT-006-04
          - ATS-PFM-NOT-006-07
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-002
        transition_index: 8
        from: open
        to: settled
        trigger: The nightly sweep completes expired work.
        source: >-
          services-platform:modules/notifications/tests/integration/services/reconcile/reconcile-tenant.integration.spec.js#settles
          a request past its expiry whose notification was delivered, so a late
          cancel reaches nothing
        existing_candidates:
          - ATS-PFM-NOT-006-01
          - ATS-PFM-NOT-006-02
          - ATS-PFM-NOT-006-04
          - ATS-PFM-NOT-006-07
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-002
        transition_index: 9
        from: open
        to: cancelled
        trigger: Registration retires the definition.
        source: >-
          services-platform:modules/notifications/services/persistence/requests.ts:cancelOpenRequestsOfDefinition
        existing_candidates:
          - ATS-PFM-NOT-006-01
          - ATS-PFM-NOT-006-02
          - ATS-PFM-NOT-006-04
          - ATS-PFM-NOT-006-07
        decision: 'gap: independent guard and side-effect proof has not been verified'
  - finding: FND-PFM-NOT-068
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-007-deliver-each-notice-on-the-channels-it-may-use.md
    missing_categories:
      - transition
      - concurrency
    unproved_rules: []
    permissions_to_audit: []
    state_transitions:
      - state_model: STATE-PFM-NOT-003
        transition_index: 1
        from: pending
        to: delivered
        trigger: Creation records a delivered console item.
        source: >-
          services-platform:modules/notifications/instance-status.ts:deriveInstanceStatus;
          services-platform:modules/notifications/services/persistence/instances.ts:refreshInstanceStatus
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-003
        transition_index: 2
        from: pending
        to: routed
        trigger: Creation queues a chat or text channel.
        source: >-
          services-platform:modules/notifications/tests/integration/services/system/system-audience.integration.spec.js#is
          accepted as one request, one instance with no recipient and one queued
          slack_system delivery with the Block Kit payload
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-003
        transition_index: 3
        from: routed
        to: delivering
        trigger: A consumer claims a delivery for sending.
        source: >-
          services-platform:modules/notifications/services/dispatch/deliver-delivery.ts:deliverQueuedDelivery
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-003
        transition_index: 4
        from: delivering
        to: delivered
        trigger: Delivery completes with a successful channel result.
        source: >-
          services-platform:modules/notifications/instance-status.ts:deriveInstanceStatus
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-003
        transition_index: 5
        from: delivering
        to: partially delivered
        trigger: A channel fails while another has delivered.
        source: >-
          services-platform:modules/notifications/tests/unit/instance-status.spec.js#is
          partially delivered when one delivered and another failed, none still
          active
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-003
        transition_index: 6
        from: delivering
        to: failed
        trigger: All selected delivery attempts fail.
        source: >-
          services-platform:modules/notifications/services/dispatch/deliver-delivery.ts:deliverQueuedDelivery
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-003
        transition_index: 7
        from: routed
        to: no channel
        trigger: The remaining queued channel is skipped.
        source: >-
          services-platform:modules/notifications/instance-status.ts:deriveInstanceStatus
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-003
        transition_index: 8
        from: failed
        to: routed
        trigger: HQ retries an exhausted delivery.
        source: >-
          services-platform:modules/notifications/tests/integration/services/dispatch/deliver-delivery.integration.spec.js#queues
          a delivery that ran out of receives again, with its work row, and
          nothing else
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-003
        transition_index: 9
        from: delivered
        to: superseded
        trigger: Withdrawal reaches a notice with console delivery.
        source: >-
          services-platform:modules/notifications/tests/integration/services/orchestration/cancel-and-supersede.integration.spec.js#cancels
          the queued delivery and its work row, and does not recall one that
          already left
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-003
        transition_index: 10
        from: routed
        to: superseded
        trigger: Withdrawal reaches a notice before channel sending.
        source: >-
          services-platform:modules/notifications/tests/integration/services/dispatch/deliver-delivery.integration.spec.js#cancels,
          not sends, a delivery whose notification was superseded after it was
          queued
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-003
        transition_index: 11
        from: routed
        to: expired
        trigger: A consumer or nightly sweep detects expiry.
        source: >-
          services-platform:modules/notifications/services/orchestration/expire-request.ts;
          services-platform:modules/notifications/services/reconcile/reconcile-tenant.ts:reconcileTenant
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-005
        transition_index: 1
        from: queued
        to: sending
        trigger: The channel consumer claims queued work.
        source: >-
          services-platform:modules/notifications/tests/integration/services/persistence/deliveries.integration.spec.js#lets
          only one of two consumers racing for the send win it
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-005
        transition_index: 2
        from: sending
        to: sent
        trigger: The adapter accepts the delivery.
        source: >-
          services-platform:modules/notifications/services/dispatch/deliver-delivery.ts:deliverQueuedDelivery
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-005
        transition_index: 3
        from: sent
        to: delivered
        trigger: The adapter or provider confirms delivery.
        source: >-
          services-platform:modules/notifications/services/dispatch/deliver-delivery.ts:deliverQueuedDelivery
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-005
        transition_index: 4
        from: sending
        to: queued
        trigger: >-
          A retryable adapter result or exception leaves another receive
          available.
        source: >-
          services-platform:modules/notifications/tests/unit/slack-system-adapter.spec.js#answers
          a 429 as a retryable failure carrying Retry-After
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-005
        transition_index: 5
        from: sending
        to: failed
        trigger: >-
          The adapter refuses permanently, the last receive fails, or
          reconciliation detects fifteen minutes of ambiguity.
        source: >-
          services-platform:modules/notifications/tests/integration/services/dispatch/deliver-delivery.integration.spec.js#fails
          the delivery attempts_exhausted on the last receive and gives the item
          back at once to reach the dead-letter queue
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-005
        transition_index: 6
        from: sending
        to: skipped
        trigger: The adapter reports that delivery is unavailable.
        source: >-
          services-platform:modules/notifications/services/channels/slack-system/slack-system-adapter.ts
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-005
        transition_index: 7
        from: queued
        to: skipped
        trigger: Dispatch cannot find the named adapter.
        source: >-
          services-platform:modules/notifications/services/dispatch/deliver-delivery.ts:deliverQueuedDelivery
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-005
        transition_index: 8
        from: queued
        to: cancelled
        trigger: Withdrawal or replacement reaches queued work.
        source: >-
          services-platform:modules/notifications/tests/integration/services/dispatch/deliver-delivery.integration.spec.js#cancels,
          not sends, a delivery whose notification was superseded after it was
          queued
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-005
        transition_index: 9
        from: queued
        to: expired
        trigger: Processing or reconciliation detects an expired request.
        source: >-
          services-platform:modules/notifications/services/orchestration/expire-request.ts
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-005
        transition_index: 10
        from: failed
        to: queued
        trigger: An HQ operator requests an exhausted-delivery retry.
        source: >-
          services-platform:modules/notifications/tests/integration/services/dispatch/deliver-delivery.integration.spec.js#queues
          a delivery that ran out of receives again, with its work row, and
          nothing else
        existing_candidates:
          - ATS-PFM-NOT-007-06
        decision: 'gap: independent guard and side-effect proof has not been verified'
  - finding: FND-PFM-NOT-069
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-008-keep-notifications-whole-when-part-of-the-pipeline-fails.md
    missing_categories:
      - rule
      - validation
      - edge
    unproved_rules: []
    permissions_to_audit: []
    state_transitions: []
  - finding: FND-PFM-NOT-070
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-009-work-through-my-own-notifications.md
    missing_categories:
      - transition
      - failure
      - boundary
      - concurrency
    unproved_rules:
      - BR-CAP-PFM-NOT-009-09
    permissions_to_audit:
      - platform.notifications.use
      - platform.notifications.use
    state_transitions:
      - state_model: STATE-PFM-NOT-004
        transition_index: 1
        from: unread
        to: read
        trigger: 'The person opens a notice, marks it read, or invokes bulk reading.'
        source: >-
          services-platform:modules/notifications/tests/e2e/notifications.e2e.spec.js#marks
          one read and unread, archives and unarchives it, answering it each
          time
        existing_candidates:
          - ATS-PFM-NOT-009-05
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-004
        transition_index: 2
        from: read
        to: unread
        trigger: The person chooses to mark the notice unread.
        source: >-
          services-platform:modules/notifications/tests/e2e/notifications.e2e.spec.js#marks
          one read and unread, archives and unarchives it, answering it each
          time
        existing_candidates:
          - ATS-PFM-NOT-009-05
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-004
        transition_index: 3
        from: unread
        to: archived unread
        trigger: The person archives an unread notice.
        source: >-
          services-platform:modules/notifications/tests/e2e/notifications.e2e.spec.js#marks
          one read and unread, archives and unarchives it, answering it each
          time
        existing_candidates:
          - ATS-PFM-NOT-009-05
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-004
        transition_index: 4
        from: read
        to: archived read
        trigger: The person archives a read notice.
        source: >-
          services-platform:modules/notifications/tests/e2e/notifications.e2e.spec.js#marks
          one read and unread, archives and unarchives it, answering it each
          time
        existing_candidates:
          - ATS-PFM-NOT-009-05
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-004
        transition_index: 5
        from: archived unread
        to: unread
        trigger: The person restores an unread archived notice.
        source: >-
          services-platform:modules/notifications/tests/e2e/notifications.e2e.spec.js#marks
          one read and unread, archives and unarchives it, answering it each
          time
        existing_candidates:
          - ATS-PFM-NOT-009-05
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-004
        transition_index: 6
        from: archived read
        to: read
        trigger: The person restores a read archived notice.
        source: >-
          services-platform:modules/notifications/tests/e2e/notifications.e2e.spec.js#marks
          one read and unread, archives and unarchives it, answering it each
          time
        existing_candidates:
          - ATS-PFM-NOT-009-05
        decision: 'gap: independent guard and side-effect proof has not been verified'
  - finding: FND-PFM-NOT-071
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-010-understand-why-i-was-told.md
    missing_categories:
      - validation
      - failure
      - boundary
      - concurrency
      - invariant
    unproved_rules: []
    permissions_to_audit:
      - platform.notifications.use
    state_transitions: []
  - finding: FND-PFM-NOT-072
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-011-see-what-the-organization-told-whom.md
    missing_categories:
      - rule
      - failure
      - concurrency
      - invariant
    unproved_rules:
      - BR-CAP-PFM-NOT-011-08
    permissions_to_audit:
      - platform.notifications.manage
      - platform.notifications.manage
    state_transitions: []
  - finding: FND-PFM-NOT-073
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-012-support-a-customers-notifications-from-rhythm-hq.md
    missing_categories:
      - rule
      - validation
      - edge
      - failure
      - concurrency
      - invariant
    unproved_rules: []
    permissions_to_audit:
      - hq.notifications.read
      - hq.notifications.operate
    state_transitions: []
  - finding: FND-PFM-NOT-074
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-013-alert-rhythms-own-staff-in-slack.md
    missing_categories:
      - edge
      - concurrency
    unproved_rules: []
    permissions_to_audit: []
    state_transitions: []
  - finding: FND-PFM-NOT-075
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-014-tell-staff-about-changes-to-their-own-responsibilities.md
    missing_categories:
      - validation
      - edge
      - boundary
      - concurrency
    unproved_rules:
      - BR-CAP-PFM-NOT-014-09
    permissions_to_audit: []
    state_transitions: []
  - finding: FND-PFM-NOT-076
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-015-let-the-organization-and-its-people-choose-how-they-hear.md
    missing_categories:
      - transition
      - failure
    unproved_rules:
      - BR-CAP-PFM-NOT-015-13
    permissions_to_audit: []
    state_transitions:
      - state_model: STATE-PFM-NOT-006
        transition_index: 1
        from: pending verification
        to: active
        trigger: A caller invokes dormant identity activation.
        source: >-
          services-platform:modules/notifications/services/persistence/identities.ts:transitionIdentity
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-006
        transition_index: 2
        from: pending verification
        to: revoked
        trigger: The pending link is removed or abandoned.
        source: >-
          services-platform:modules/notifications/services/persistence/identities.ts:TRANSITIONS
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-006
        transition_index: 3
        from: active
        to: unreachable
        trigger: A channel reports loss of reachability.
        source: >-
          services-platform:modules/notifications/services/persistence/identities.ts:TRANSITIONS
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-006
        transition_index: 4
        from: active
        to: opted out
        trigger: The person or carrier withdraws consent.
        source: >-
          services-platform:modules/notifications/services/persistence/identities.ts:TRANSITIONS
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-006
        transition_index: 5
        from: unreachable
        to: active
        trigger: The channel reports restored reachability or another verification.
        source: >-
          services-platform:modules/notifications/services/persistence/identities.ts:TRANSITIONS
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-006
        transition_index: 6
        from: opted out
        to: active
        trigger: The person restores consent.
        source: >-
          services-platform:modules/notifications/services/persistence/identities.ts:TRANSITIONS
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-006
        transition_index: 7
        from: active
        to: revoked
        trigger: The person or administrator removes the active link.
        source: >-
          services-platform:modules/notifications/services/persistence/identities.ts:TRANSITIONS
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-007
        transition_index: 1
        from: draft
        to: active
        trigger: An administrator publishes edited wording.
        source: >-
          services-platform:modules/notifications/tests/integration/services/persistence/template-overrides.integration.spec.js#leaves
          exactly one active version per definition, channel and locale
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-007
        transition_index: 2
        from: active
        to: superseded
        trigger: Another override becomes active for the same selection.
        source: >-
          services-platform:modules/notifications/services/persistence/template-overrides.ts
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-007
        transition_index: 3
        from: active
        to: deactivated
        trigger: An administrator withdraws the active wording.
        source: >-
          services-platform:modules/notifications/services/persistence/template-overrides.ts
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-008
        transition_index: 1
        from: open
        to: delivering
        trigger: A caller begins delivery at the end of a window.
        source: >-
          services-platform:modules/notifications/services/persistence/digests.ts:DIGEST_TRANSITIONS
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-008
        transition_index: 2
        from: open
        to: empty
        trigger: A caller closes a window as empty.
        source: >-
          services-platform:modules/notifications/services/persistence/digests.ts:DIGEST_TRANSITIONS
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-008
        transition_index: 3
        from: delivering
        to: delivered
        trigger: The channel confirms digest sending.
        source: >-
          services-platform:modules/notifications/services/persistence/digests.ts:DIGEST_TRANSITIONS
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-008
        transition_index: 4
        from: delivering
        to: failed
        trigger: The channel reports terminal digest failure.
        source: >-
          services-platform:modules/notifications/services/persistence/digests.ts:DIGEST_TRANSITIONS
        existing_candidates:
          - ATS-PFM-NOT-015-05
          - ATS-PFM-NOT-015-08
        decision: 'gap: independent guard and side-effect proof has not been verified'
  - finding: FND-PFM-NOT-077
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-016-compose-the-e-mails-an-association-sends.md
    missing_categories:
      - transition
    unproved_rules: []
    permissions_to_audit:
      - platform.communication-templates.read
      - platform.communication-templates.create
      - platform.communication-templates.update
      - platform.communication-templates.delete
      - platform.communication-templates.publish
      - platform.communication-templates.test-send
    state_transitions:
      - state_model: STATE-PFM-NOT-009
        transition_index: 1
        from: draft only
        to: published
        trigger: 'An author publishes, or an owning record saves its initial content.'
        source: >-
          services-platform:modules/communications/tests/e2e/templates.e2e.spec.js#froze
          the draft as version 1, with the content hash and the variables it
          reads
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-009
        transition_index: 2
        from: published
        to: published
        trigger: An author republishes or an owner saves changed content.
        source: >-
          services-platform:modules/communications/tests/integration/services/templates/owned-templates.integration.spec.js#keeps
          every field the partial content left out
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-009
        transition_index: 3
        from: published
        to: archived
        trigger: An author archives the template or its owner clears the setting.
        source: >-
          services-platform:modules/communications/tests/e2e/templates.e2e.spec.js#keeps
          it readable by id, because it is kept for history
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-009
        transition_index: 4
        from: draft only
        to: archived
        trigger: An author archives an unpublished template or its owner clears it.
        source: >-
          services-platform:modules/communications/services/persistence/templates.ts:archiveTemplate
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
  - finding: FND-PFM-NOT-078
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-017-ask-platform-to-send-an-association-e-mail.md
    missing_categories:
      - transition
      - concurrency
    unproved_rules: []
    permissions_to_audit:
      - platform.communications.request
    state_transitions:
      - state_model: STATE-PFM-NOT-010
        transition_index: 1
        from: received
        to: accepted
        trigger: The consumer processes a request without an outcome.
        source: >-
          services-platform:modules/communications/tests/integration/lifecycle/contact-role-compliance-communication.integration.spec.js#accepts
          the request with the owner’s published version pinned
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-010
        transition_index: 2
        from: received
        to: configuration blocked
        trigger: Content resolution cannot produce a usable version.
        source: >-
          services-platform:modules/communications/tests/e2e/requests.e2e.spec.js#blocks
          a request that names no template, recording the reason staff can act
          on
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-010
        transition_index: 3
        from: received
        to: suppressed
        trigger: Every recipient is excluded by protection checks.
        source: >-
          services-platform:modules/communications/services/requests/accept-communication-request.ts:acceptResolved
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-010
        transition_index: 4
        from: received
        to: invalid
        trigger: 'Stored content is absent, mismatched or invalid.'
        source: >-
          services-platform:modules/communications/tests/integration/services/storage/communication-objects.integration.spec.js#refuses
          an object that names another tenant, which is what the grant cannot
          prevent
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
  - finding: FND-PFM-NOT-079
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-018-deliver-association-e-mail-reliably-and-within-sending.md
    missing_categories:
      - transition
    unproved_rules: []
    permissions_to_audit:
      - platform.communication-messages.update
    state_transitions:
      - state_model: STATE-PFM-NOT-011
        transition_index: 1
        from: draft
        to: submitting
        trigger: The consumer claims a rendered message.
        source: >-
          services-platform:modules/communications/services/persistence/messages.ts:claimMessageForSubmission
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-011
        transition_index: 2
        from: draft
        to: withheld
        trigger: The final send check rejects the address or environment policy.
        source: >-
          services-platform:modules/communications/tests/integration/services/dispatch/reserved-domain-suppression.integration.spec.js#withholds
          its message with the reserved-domain reason, so the history says why
          it was not sent
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-011
        transition_index: 3
        from: draft
        to: expired
        trigger: The final send check detects expiry.
        source: >-
          services-platform:modules/communications/services/persistence/messages.ts:claimMessageForSubmission
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-011
        transition_index: 4
        from: draft
        to: cancelled
        trigger: Staff request cancellation.
        source: >-
          services-platform:modules/communications/services/persistence/messages.ts:cancelMessage
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-011
        transition_index: 5
        from: submitting
        to: submitted
        trigger: >-
          Provider acceptance or qualifying feedback resolves an unfinished
          submission.
        source: >-
          services-platform:modules/communications/services/persistence/messages.ts:recordMessageSubmitted;
          services-platform:modules/communications/services/feedback/process-ses-event.ts:processSesEvent
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-011
        transition_index: 6
        from: submitting
        to: draft
        trigger: A throttle or temporary failure permits another receive.
        source: >-
          services-platform:modules/communications/services/persistence/messages.ts:recordMessageSubmissionFailed
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-011
        transition_index: 7
        from: submitting
        to: failed
        trigger: A permanent refusal or final-receive failure ends the attempt.
        source: >-
          services-platform:modules/communications/services/persistence/messages.ts:recordMessageSubmissionFailed
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-011
        transition_index: 8
        from: submitting
        to: submitting
        trigger: A later claim encounters an old unresolved submission.
        source: >-
          services-platform:modules/communications/tests/integration/services/persistence/messages.integration.spec.js#claims
          it again once the ambiguity window has passed, the unknown attempt
          closed
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-011
        transition_index: 9
        from: failed
        to: draft
        trigger: An operator redrives exhausted request work.
        source: >-
          services-platform:modules/communications/services/persistence/messages.ts:retryExhaustedMessages
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-015
        transition_index: 1
        from: unlimited
        to: running
        trigger: The quota guard obtains its first rate observation.
        source: >-
          services-platform:modules/communications/services/dispatch/quota-guard.ts:runQuotaGuard
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-015
        transition_index: 2
        from: running
        to: paused
        trigger: Daily usage reaches ninety percent of the account quota.
        source: >-
          services-platform:modules/communications/services/dispatch/quota-guard.ts:runQuotaGuard
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-015
        transition_index: 3
        from: paused
        to: running
        trigger: Daily usage drops below the pause threshold.
        source: >-
          services-platform:modules/communications/services/dispatch/quota-guard.ts:runQuotaGuard
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-015
        transition_index: 4
        from: unlimited
        to: paused
        trigger: The first quota observation already exceeds the daily threshold.
        source: >-
          services-platform:modules/communications/services/dispatch/quota-guard.ts:runQuotaGuard
        existing_candidates:
          - ATS-PFM-NOT-018-04
          - ATS-PFM-NOT-018-11
        decision: 'gap: independent guard and side-effect proof has not been verified'
  - finding: FND-PFM-NOT-080
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-019-record-what-became-of-each-e-mail.md
    missing_categories:
      - rule
      - transition
      - failure
    unproved_rules: []
    permissions_to_audit:
      - platform.communication-messages.read
      - platform.communication-messages.read-content
    state_transitions:
      - state_model: STATE-PFM-NOT-012
        transition_index: 1
        from: unknown
        to: delivered
        trigger: Primary-recipient feedback reports delivery.
        source: >-
          services-platform:modules/communications/services/feedback/process-ses-event.ts:processSesEvent
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-012
        transition_index: 2
        from: unknown
        to: deferred
        trigger: Feedback reports delivery delay.
        source: >-
          services-platform:modules/communications/db/communication-messages.table.ts:DELIVERY_STATE_PRECEDENCE
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-012
        transition_index: 3
        from: delivered
        to: bounced permanent
        trigger: Feedback reports a permanent bounce after delivery.
        source: >-
          services-platform:modules/communications/services/feedback/process-ses-event.ts:processSesEvent
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-012
        transition_index: 4
        from: delivered
        to: complained
        trigger: Feedback reports a complaint after delivery.
        source: >-
          services-platform:modules/communications/services/feedback/process-ses-event.ts:processSesEvent
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-012
        transition_index: 5
        from: deferred
        to: delivered
        trigger: Delayed delivery later succeeds.
        source: >-
          services-platform:modules/communications/db/communication-messages.table.ts:DELIVERY_STATE_PRECEDENCE
        existing_candidates: []
        decision: 'gap: independent guard and side-effect proof has not been verified'
  - finding: FND-PFM-NOT-081
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/capabilities/CAP-PFM-NOT-020-protect-deliverability-and-the-associations-sending-address.md
    missing_categories:
      - transition
      - permission
      - concurrency
    unproved_rules: []
    permissions_to_audit:
      - platform.communication-suppressions.read
      - platform.communication-suppressions.create
      - platform.communication-suppressions.update
    state_transitions:
      - state_model: STATE-PFM-NOT-013
        transition_index: 1
        from: not suppressed
        to: active
        trigger: 'Staff add protection, or provider feedback triggers it.'
        source: >-
          services-platform:modules/communications/tests/integration/lifecycle/contact-role-compliance-communication.integration.spec.js#suppresses
          the address for the tenant
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-013
        transition_index: 2
        from: active
        to: active
        trigger: Protection is requested for an already protected address.
        source: >-
          services-platform:modules/communications/services/persistence/suppressions.ts:suppressAddress
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-013
        transition_index: 3
        from: active
        to: released
        trigger: Staff release address protection.
        source: >-
          services-platform:modules/communications/services/persistence/suppressions.ts:releaseSuppression
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-013
        transition_index: 4
        from: released
        to: active
        trigger: New provider feedback or a staff addition protects a released address.
        source: >-
          services-platform:modules/communications/services/persistence/suppressions.ts:suppressAddress
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-014
        transition_index: 1
        from: none
        to: pending
        trigger: Workspace setup requests a custom sender setting.
        source: >-
          rhythm-v2-docs:specs/platform/notifications/FINDINGS.md:FND-PFM-NOT-049
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-014
        transition_index: 2
        from: pending
        to: verified
        trigger: An HQ sender read refreshes provider verification.
        source: >-
          services-platform:modules/communications/services/sender-identity/provision-sender-identity.ts:refreshSenderIdentityVerification
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-014
        transition_index: 3
        from: pending
        to: failed
        trigger: An HQ sender read finds failed verification.
        source: >-
          services-platform:modules/communications/services/sender-identity/provision-sender-identity.ts:verificationStateOf
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-014
        transition_index: 4
        from: verified
        to: pending
        trigger: An HQ sender read finds verification no longer ready.
        source: >-
          services-platform:modules/communications/services/sender-identity/provision-sender-identity.ts:verificationStateOf
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-014
        transition_index: 5
        from: verified
        to: none
        trigger: Workspace deletion removes the sender.
        source: >-
          services-platform:modules/communications/services/sender-identity/provision-sender-identity.ts:purgeSenderIdentityIdentities
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-014
        transition_index: 6
        from: failed
        to: verified
        trigger: An HQ sender read observes recovered verification.
        source: >-
          services-platform:modules/communications/services/sender-identity/provision-sender-identity.ts:verificationStateOf
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-014
        transition_index: 7
        from: failed
        to: pending
        trigger: An HQ sender read observes verification still awaiting completion.
        source: >-
          services-platform:modules/communications/services/sender-identity/provision-sender-identity.ts:verificationStateOf
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-014
        transition_index: 8
        from: verified
        to: failed
        trigger: An HQ sender read observes provider verification failure.
        source: >-
          services-platform:modules/communications/services/sender-identity/provision-sender-identity.ts:verificationStateOf
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-014
        transition_index: 9
        from: pending
        to: none
        trigger: Workspace deletion removes the pending sender.
        source: >-
          services-platform:modules/communications/services/sender-identity/provision-sender-identity.ts:purgeSenderIdentityIdentities
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
      - state_model: STATE-PFM-NOT-014
        transition_index: 10
        from: failed
        to: none
        trigger: Workspace deletion removes the failed sender.
        source: >-
          services-platform:modules/communications/services/sender-identity/provision-sender-identity.ts:purgeSenderIdentityIdentities
        existing_candidates:
          - ATS-PFM-NOT-020-04
          - ATS-PFM-NOT-020-10
          - ATS-PFM-NOT-020-13
          - ATS-PFM-NOT-020-14
        decision: 'gap: independent guard and side-effect proof has not been verified'
  - finding: FND-PFM-NOT-082
    provenance: inferred
    source:
      - FND-PFM-NOT-026
    verification: >-
      Each existing executable reference contributes only the assertions in its
      named test. A complete qualification run is still required.
  - finding: FND-PFM-NOT-083
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/acceptance/FAS-PFM-NOT-01-notification-registry.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/acceptance/FAS-PFM-NOT-02-notification-pipeline.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/acceptance/FAS-PFM-NOT-03-notification-centre.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/acceptance/FAS-PFM-NOT-04-notification-history-and-support.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/acceptance/FAS-PFM-NOT-05-rhythm-hq-alerts.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/acceptance/FAS-PFM-NOT-06-notification-preferences-and-channels.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/planning/acceptance/FAS-PFM-NOT-07-association-e-mail.md
    unbound_scenarios:
      - FAS-PFM-NOT-01-01
      - FAS-PFM-NOT-01-02
      - FAS-PFM-NOT-01-03
      - FAS-PFM-NOT-01-04
      - FAS-PFM-NOT-01-05
      - FAS-PFM-NOT-02-01
      - FAS-PFM-NOT-02-02
      - FAS-PFM-NOT-02-03
      - FAS-PFM-NOT-02-04
      - FAS-PFM-NOT-02-05
      - FAS-PFM-NOT-03-01
      - FAS-PFM-NOT-03-02
      - FAS-PFM-NOT-04-01
      - FAS-PFM-NOT-04-02
      - FAS-PFM-NOT-04-03
      - FAS-PFM-NOT-04-05
      - FAS-PFM-NOT-05-01
      - FAS-PFM-NOT-05-02
      - FAS-PFM-NOT-05-03
      - FAS-PFM-NOT-05-04
      - FAS-PFM-NOT-05-05
      - FAS-PFM-NOT-06-01
      - FAS-PFM-NOT-06-02
      - FAS-PFM-NOT-06-03
      - FAS-PFM-NOT-06-04
      - FAS-PFM-NOT-06-05
      - FAS-PFM-NOT-07-04
  - finding: FND-PFM-NOT-084
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-001-register-the-kinds-of-notification-an-application-can-send.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-002-tell-people-that-something-happened-with-one-call.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-003-reach-the-right-people-and-only-people-of-the-organization.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-004-word-each-notice-for-the-person-who-receives-it.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-005-fold-quick-repeats-into-one-notice.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-006-withdraw-or-expire-a-notice-that-no-longer-applies.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-007-deliver-each-notice-on-the-channels-it-may-use.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-008-keep-notifications-whole-when-part-of-the-pipeline-fails.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-009-work-through-my-own-notifications.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-010-understand-why-i-was-told.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-011-see-what-the-organization-told-whom.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-012-support-a-customers-notifications-from-rhythm-hq.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-013-alert-rhythms-own-staff-in-slack.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-014-tell-staff-about-changes-to-their-own-responsibilities.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-015-let-the-organization-and-its-people-choose-how-they-hear.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-016-compose-the-e-mails-an-association-sends.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-017-ask-platform-to-send-an-association-e-mail.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-018-deliver-association-e-mail-reliably-and-within-sending.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-019-record-what-became-of-each-e-mail.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/tests/ATS-PFM-NOT-020-protect-deliverability-and-the-associations-sending-address.md
    unbound_scenarios:
      - ATS-PFM-NOT-001-14
      - ATS-PFM-NOT-002-09
      - ATS-PFM-NOT-003-09
      - ATS-PFM-NOT-004-05
      - ATS-PFM-NOT-005-10
      - ATS-PFM-NOT-006-10
      - ATS-PFM-NOT-007-10
      - ATS-PFM-NOT-008-11
      - ATS-PFM-NOT-009-10
      - ATS-PFM-NOT-010-07
      - ATS-PFM-NOT-011-07
      - ATS-PFM-NOT-012-06
      - ATS-PFM-NOT-013-10
      - ATS-PFM-NOT-014-02
      - ATS-PFM-NOT-014-07
      - ATS-PFM-NOT-015-12
      - ATS-PFM-NOT-016-15
      - ATS-PFM-NOT-017-15
      - ATS-PFM-NOT-018-14
      - ATS-PFM-NOT-019-09
      - ATS-PFM-NOT-020-15
    workflow_gaps:
      - workflow: WF-PFM-NOT-001
        capabilities:
          - CAP-PFM-NOT-001
          - CAP-PFM-NOT-013
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-001-register-an-applications-notification-definitions.md
      - workflow: WF-PFM-NOT-002
        capabilities:
          - CAP-PFM-NOT-002
          - CAP-PFM-NOT-008
          - CAP-PFM-NOT-009
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-002-publish-a-staff-notification-with-its-business-change.md
      - workflow: WF-PFM-NOT-003
        capabilities:
          - CAP-PFM-NOT-003
          - CAP-PFM-NOT-004
          - CAP-PFM-NOT-005
          - CAP-PFM-NOT-006
          - CAP-PFM-NOT-007
          - CAP-PFM-NOT-008
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-003-turn-one-request-into-recipient-notices.md
      - workflow: WF-PFM-NOT-004
        capabilities:
          - CAP-PFM-NOT-006
          - CAP-PFM-NOT-005
          - CAP-PFM-NOT-014
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-004-withdraw-or-replace-a-notice.md
      - workflow: WF-PFM-NOT-005
        capabilities:
          - CAP-PFM-NOT-007
          - CAP-PFM-NOT-008
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-005-deliver-queued-chat-and-text-deliveries.md
      - workflow: WF-PFM-NOT-006
        capabilities:
          - CAP-PFM-NOT-013
          - CAP-PFM-NOT-003
          - CAP-PFM-NOT-007
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-006-alert-rhythm-hq-in-slack.md
      - workflow: WF-PFM-NOT-007
        capabilities:
          - CAP-PFM-NOT-008
          - CAP-PFM-NOT-006
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-007-reconcile-and-trim-notification-records-nightly.md
      - workflow: WF-PFM-NOT-008
        capabilities:
          - CAP-PFM-NOT-012
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-008-retry-an-exhausted-delivery-from-rhythm-hq.md
      - workflow: WF-PFM-NOT-009
        capabilities:
          - CAP-PFM-NOT-014
          - CAP-PFM-NOT-002
          - CAP-PFM-NOT-006
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-009-announce-responsibility-changes.md
      - workflow: WF-PFM-NOT-010
        capabilities:
          - CAP-PFM-NOT-017
          - CAP-PFM-NOT-018
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-010-submit-an-association-communication-request.md
      - workflow: WF-PFM-NOT-011
        capabilities:
          - CAP-PFM-NOT-017
          - CAP-PFM-NOT-018
          - CAP-PFM-NOT-020
          - CAP-PFM-NOT-016
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-011-accept-and-send-association-e-mail.md
      - workflow: WF-PFM-NOT-012
        capabilities:
          - CAP-PFM-NOT-018
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-012-pace-association-sending-across-lanes.md
      - workflow: WF-PFM-NOT-013
        capabilities:
          - CAP-PFM-NOT-019
          - CAP-PFM-NOT-020
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-013-record-provider-feedback.md
      - workflow: WF-PFM-NOT-014
        capabilities:
          - CAP-PFM-NOT-016
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-014-compose-a-record-owned-template-across-services.md
      - workflow: WF-PFM-NOT-015
        capabilities:
          - CAP-PFM-NOT-020
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-015-provision-verify-and-remove-the-association-sender.md
      - workflow: WF-PFM-NOT-016
        capabilities:
          - CAP-PFM-NOT-008
          - CAP-PFM-NOT-020
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/workflows/WF-PFM-NOT-016-purge-or-reset-a-workspaces-notifications-and-communications.md
  - finding: FND-PFM-NOT-085
    provenance: inferred
    source:
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-004-association-e-mail-template.md
      - >-
        rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
    invariant_coverage:
      - invariant: INV-DOM-PFM-NOT-003-01
        scenarios:
          - ATS-PFM-NOT-002-01
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-003-02
        scenarios:
          - ATS-PFM-NOT-002-03
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-003-03
        scenarios:
          - ATS-PFM-NOT-005-07
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-003-04
        scenarios:
          - ATS-PFM-NOT-003-07
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-003-05
        scenarios:
          - ATS-PFM-NOT-003-06
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-003-06
        scenarios:
          - ATS-PFM-NOT-013-02
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-003-07
        scenarios:
          - ATS-PFM-NOT-007-07
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-003-08
        scenarios:
          - ATS-PFM-NOT-009-04
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-003-09
        scenarios:
          - ATS-PFM-NOT-008-08
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-003-10
        scenarios:
          - ATS-PFM-NOT-001-07
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-003-11
        scenarios: []
        coverage: 'gap: FND-PFM-NOT-085'
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          A complete proof of this combined guarantee is not established by the
          inspected scenario bindings.
      - invariant: INV-DOM-PFM-NOT-003-12
        scenarios:
          - ATS-PFM-NOT-005-05
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-003-staff-notification.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-004-01
        scenarios:
          - ATS-PFM-NOT-016-07
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-004-association-e-mail-template.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-004-02
        scenarios:
          - ATS-PFM-NOT-016-06
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-004-association-e-mail-template.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-004-03
        scenarios:
          - ATS-PFM-NOT-016-02
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-004-association-e-mail-template.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-004-04
        scenarios:
          - ATS-PFM-NOT-016-08
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-004-association-e-mail-template.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-004-05
        scenarios:
          - ATS-PFM-NOT-016-09
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-004-association-e-mail-template.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-004-06
        scenarios: []
        coverage: 'gap: FND-PFM-NOT-085'
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-004-association-e-mail-template.md
        verification_note: >-
          A complete proof of this combined guarantee is not established by the
          inspected scenario bindings.
      - invariant: INV-DOM-PFM-NOT-004-07
        scenarios:
          - ATS-PFM-NOT-016-04
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-004-association-e-mail-template.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-004-08
        scenarios:
          - ATS-PFM-NOT-016-10
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-004-association-e-mail-template.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-004-09
        scenarios: []
        coverage: 'gap: FND-PFM-NOT-085'
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-004-association-e-mail-template.md
        verification_note: >-
          A complete proof of this combined guarantee is not established by the
          inspected scenario bindings.
      - invariant: INV-DOM-PFM-NOT-005-01
        scenarios: []
        coverage: 'gap: FND-PFM-NOT-085'
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          A complete proof of this combined guarantee is not established by the
          inspected scenario bindings.
      - invariant: INV-DOM-PFM-NOT-005-02
        scenarios:
          - ATS-PFM-NOT-017-03
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-005-03
        scenarios:
          - ATS-PFM-NOT-017-07
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-005-04
        scenarios:
          - ATS-PFM-NOT-018-02
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-005-05
        scenarios:
          - ATS-PFM-NOT-018-05
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-005-06
        scenarios: []
        coverage: 'gap: FND-PFM-NOT-085'
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          A complete proof of this combined guarantee is not established by the
          inspected scenario bindings.
      - invariant: INV-DOM-PFM-NOT-005-07
        scenarios:
          - ATS-PFM-NOT-020-05
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-005-08
        scenarios:
          - ATS-PFM-NOT-019-02
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-005-09
        scenarios:
          - ATS-PFM-NOT-017-14
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-005-10
        scenarios:
          - ATS-PFM-NOT-019-07
        coverage: specified
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          The candidate supplies the fixture outcome; individual binding limits
          remain applicable.
      - invariant: INV-DOM-PFM-NOT-005-11
        scenarios: []
        coverage: 'gap: FND-PFM-NOT-085'
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          A complete proof of this combined guarantee is not established by the
          inspected scenario bindings.
      - invariant: INV-DOM-PFM-NOT-005-12
        scenarios: []
        coverage: 'gap: FND-PFM-NOT-085'
        source: >-
          rhythm-v2-docs:specs/platform/notifications/design/objects/DOM-PFM-NOT-005-association-communication.md
        verification_note: >-
          A complete proof of this combined guarantee is not established by the
          inspected scenario bindings.
open_question_evidence:
  - question: OQ-PFM-NOT-009
    provenance: observed
    product_intent: proposed
    source: >-
      rhythm-v2-docs:specs/platform/notifications/FINDINGS.md:FND-PFM-NOT-044;
      FND-PFM-NOT-045; FND-PFM-NOT-050; FND-PFM-NOT-051; FND-PFM-NOT-052
control_gap_evidence:
  - finding: FND-PFM-NOT-053
    controls:
      - TC-DAT-003
    provenance: observed
    source: >-
      services-platform:modules/communications/db/communication-message-events.table.ts
      (header comment: partitioned by month, retention by dropping partitions);
      docs/communications/architecture.md#16.2 Differences from the design, and
      why; no registration of the table with the partition manager was found in
      the module
    related_finding: FND-PFM-NOT-024
  - finding: FND-PFM-NOT-054
    controls:
      - TC-PI-004
      - TC-AVL-004
    provenance: observed
    source: >-
      services-platform:modules/notifications/services/registration/register-service-notifications.ts:cancelRetiredRequests
    related_finding: FND-PFM-NOT-027
  - finding: FND-PFM-NOT-055
    controls:
      - TC-PI-002
    provenance: observed
    source: >-
      services-platform:modules/communications/services/persistence/messages.ts:claimMessageForSubmission;
      modules/communications/tests/integration/services/persistence/messages.integration.spec.js#claims
      it again once the ambiguity window has passed, the unknown attempt closed
    related_finding: FND-PFM-NOT-030
  - finding: FND-PFM-NOT-056
    controls:
      - TC-AZ-002
      - TC-TEN-004
      - TC-IAM-006
    provenance: observed
    source: >-
      services-platform:modules/communications/services/requests/handle-invocation.ts:run
    related_finding: FND-PFM-NOT-035
  - finding: FND-PFM-NOT-057
    controls:
      - TC-AZ-005
      - TC-TEN-002
      - TC-DAT-002
    provenance: observed
    source: >-
      services-platform:modules/notifications/services/centre/hq-notifications.ts:listDeadLetters;
      modules/notifications/services/centre/hq-notifications.ts:retryDeadDelivery;
      modules/notifications/services/centre/notification-centre.ts:toDeliveryRecord;
      modules/notifications/aws/api/notifications.routes.ts
    related_finding: FND-PFM-NOT-036
  - finding: FND-PFM-NOT-058
    controls:
      - TC-PI-005
    provenance: observed
    source: >-
      services-platform:modules/communications/db/communication-templates.table.ts
      (no actor column for draft edits or archiving);
      modules/communications/db/communication-template-versions.table.ts:published_by_id;
      modules/notifications/services/persistence/template-overrides.ts (header:
      publish and deactivation are audited)
    related_finding: FND-PFM-NOT-043
  - finding: FND-PFM-NOT-059
    controls:
      - TC-PI-004
      - TC-AVL-004
    provenance: observed
    source: >-
      services-platform:modules/notifications/services/dispatch/deliver-delivery.ts:deliverQueuedDelivery;
      modules/notifications/services/reconcile/reconcile-tenant.ts:reconcileTenant
    related_finding: FND-PFM-NOT-044
  - finding: FND-PFM-NOT-060
    controls:
      - TC-PI-002
      - TC-PI-004
      - TC-PRV-004
    provenance: observed
    source: >-
      services-platform:modules/communications/services/feedback/process-ses-event.ts:processSesEvent;
      modules/communications/services/persistence/messages.ts:recordMessageEvent
    related_finding: FND-PFM-NOT-045
  - finding: FND-PFM-NOT-061
    controls:
      - TC-PI-003
      - TC-PI-005
    provenance: observed
    source: >-
      services-platform:modules/communications/services/templates/template-publishing.ts:publishTemplate;
      services-platform:modules/communications/services/persistence/templates.ts:publishTemplateDraft;
      services-platform:modules/communications/services/persistence/templates.ts:updateTemplateDraft
    related_finding: FND-PFM-NOT-051
---

# Notification and Communication Examination Findings

## Findings

These records distinguish implementation defects, unapproved extensions and limits of the available evidence. Evidence remains in the structured source list; recommendations describe proposed product decisions.

| id | severity | statement | affects | evidence | kind |
|---|---|---|---|---|---|
| `FND-PFM-NOT-001` | medium | The approved HQ decision excludes a reserved workspace, while implementation creates a demonstration support workspace for system alerts. The handoff treats that choice as an assumption. The product should resolve whether this workspace is permitted and whether ordinary HQ lists and nightly processing should include it. | `CAP-PFM-NOT-013`, `CON-PFM-NOT-002` | See `finding_evidence` | inconsistency |
| `FND-PFM-NOT-002` | low | Several records reference a plan filename absent from the pinned tree. The humanized plan is available and supplies this corpus's milestone authority. The product should correct the stale plan references. | `MOD-PFM-NOT` | See `finding_evidence` | inconsistency |
| `FND-PFM-NOT-003` | medium | The approved combined bell is incomplete: its popover does not contain a Notifications section. The associated intended rule lacks passing implementation proof, pending the attention milestone dependency. | `CAP-PFM-NOT-009`, `BR-CAP-PFM-NOT-009-09`, `JNY-PFM-NOT-001` | See `finding_evidence` | defect |
| `FND-PFM-NOT-004` | medium | The milestone remains in progress. Its recorded fourth acceptance run passes eighteen of nineteen journeys, with the delivery-explanation defect, partial bell integration and unconfigured Slack token still limiting verification. The product should complete those proofs before treating the release as verified. | `CAP-PFM-NOT-009`, `CAP-PFM-NOT-010`, `CAP-PFM-NOT-011`, `CAP-PFM-NOT-013`, `JNY-PFM-NOT-004` | See `finding_evidence` | debt |
| `FND-PFM-NOT-005` | medium | Preference, wording, identity, digest and text-accounting persistence exists outside the approved core release. Current routes and orchestration do not expose or consult it. The product should approve a future milestone plan before activating those primitives. | `CAP-PFM-NOT-015`, `BR-CAP-PFM-NOT-015-13`, `FEAT-PFM-NOT-06` | See `finding_evidence` | inconsistency |
| `FND-PFM-NOT-006` | low | The request-outcome enumeration includes definition-disabled, but current processing never writes it because workspace enablement settings are not applied. | `CON-PFM-NOT-002`, `CAP-PFM-NOT-015` | See `finding_evidence` | debt |
| `FND-PFM-NOT-007` | low | The History delivery table omits the future milestone from unused-channel explanations. The recorded defect leaves the intended explanation rule without passing proof. | `CAP-PFM-NOT-011`, `BR-CAP-PFM-NOT-011-08`, `JNY-PFM-NOT-003` | See `finding_evidence` | defect |
| `FND-PFM-NOT-008` | low | Ending an undispatched assignment prevents its assignment announcement but still sends the ending announcement. Whether recipients should hear about an assignment they never received remains an open product decision. | `CAP-PFM-NOT-014`, `BR-CAP-PFM-NOT-014-09`, `JNY-PFM-NOT-002` | See `finding_evidence` | inconsistency |
| `FND-PFM-NOT-009` | high | The handoff reports that the notification submission role still needs adoption in the shared capability-role catalog. This examination does not inspect that external catalog. The product should obtain owning-infrastructure proof before relying on other services to publish. | `CAP-PFM-NOT-002` | See `finding_evidence` | debt |
| `FND-PFM-NOT-010` | low | The shared producer library excludes system audiences, so Platform uses a separate HQ publication path with repeated envelope validation. The recorded debt identifies the duplication that future library adoption should resolve. | `CAP-PFM-NOT-013` | See `finding_evidence` | debt |
| `FND-PFM-NOT-011` | medium | The registered scope includes notification Settings, HQ History, shared notification components and libraries. The legacy alerts route redirects to attention and is outside notification rule ownership. The module inventory preserves that boundary. | `MOD-PFM-NOT` | See `finding_evidence` | inconsistency |
| `FND-PFM-NOT-012` | medium | The examined communications records confirm the original architecture and acceptance, but provide no matching Andrew decision for later caller-rendered, Marketing-lane and version-owned extensions. Their observed implementation remains proposed. | `CAP-PFM-NOT-017`, `CAP-PFM-NOT-018`, `CAP-PFM-NOT-020` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-013` | low | The communications architecture repeats a section number for two different subjects, making numeric citations ambiguous. The product should use descriptive heading references until the record is corrected. | `MOD-PFM-NOT` | See `finding_evidence` | inconsistency |
| `FND-PFM-NOT-014` | medium | The communications acceptance excludes console delivery work. Permitted notification screens contain no communication-history or suppression interface, but this limited scope cannot establish repository-wide screen absence. | `CAP-PFM-NOT-019`, `CAP-PFM-NOT-020` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-015` | medium | Lane capacity has no implemented workspace-fairness guarantee. The product should decide how simultaneous senders share a lane before assuming campaigns receive fair service. | `CAP-PFM-NOT-018` | See `finding_evidence` | debt |
| `FND-PFM-NOT-016` | medium | Owned-template requests lack independently trusted submitting-service identity at acceptance. A service permitted to invoke the primitive can name a Marketing version. The product should establish authenticated service ownership before enforcing producer-specific contracts. | `CAP-PFM-NOT-017` | See `finding_evidence` | debt |
| `FND-PFM-NOT-017` | low | The approved audience list names five personal selection forms, while code also accepts a system audience for HQ. The product should explicitly confirm that additional audience form. | `CAP-PFM-NOT-003`, `CAP-PFM-NOT-013` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-018` | medium | The plan's scope describes an HQ bell experience, while its later decision directs HQ alerts to Slack only. The product should resolve the remaining inbox question and reconcile the scope wording. | `CAP-PFM-NOT-013` | See `finding_evidence` | inconsistency |
| `FND-PFM-NOT-019` | low | Only Rhythm Administrator currently grants the HQ notification keys. Support staff lack those powers until Andrew decides the HQ access policy. | `CAP-PFM-NOT-012` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-020` | medium | Platform does not own resource display names. The console supplies them for responsibility scope, but future external channels lack that lookup. The product should decide how resource labels enter those messages. | `CAP-PFM-NOT-004`, `CAP-PFM-NOT-014` | See `finding_evidence` | debt |
| `FND-PFM-NOT-021` | low | The plan's assumption describes an earlier console milestone number, whereas the cited decision uses the current notification milestone. The product should reconcile that historical reference. | `CAP-PFM-NOT-009` | See `finding_evidence` | inconsistency |
| `FND-PFM-NOT-022` | medium | Responsibility producer internals lie outside the registered code scope. Documentation and acceptance journeys support the integration contract, but delegation confirmation, transaction rollback and refusal compensation remain without bound owning-module proof. | `CAP-PFM-NOT-014` | See `finding_evidence` | debt |
| `FND-PFM-NOT-023` | low | Nonproduction responsibility routes support a test delay header guarded by environment. The product should decide whether that route-level seam remains appropriate before broader adoption. | `CAP-PFM-NOT-014` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-024` | low | Communication event partitions exist, but the examined as-built record reports retention and partition maintenance as unimplemented. The product should establish a retention policy and maintenance proof. | `CAP-PFM-NOT-019` | See `finding_evidence` | debt |
| `FND-PFM-NOT-025` | medium | The requested planning brief is missing from the supplied specification checkout. This review relies on the authoring contract, draft and pinned evidence and cannot verify requirements unique to the absent brief. | `MOD-PFM-NOT` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-026` | medium | Some acceptance scenarios combine checks beyond their bound assertions. Existing bindings identify inspected evidence rather than complete execution proof. The product should strengthen composite and unbound scenarios before using them as design-entry proof. | `MOD-PFM-NOT` | See `finding_evidence` | debt |
| `FND-PFM-NOT-027` | medium | Definition retirement commits before workspace cancellation attempts. A cancellation error is logged without undoing retirement, so some unsettled requests can remain. The product should define recovery for partial retirement sweeps. | `CAP-PFM-NOT-001` | See `finding_evidence` | defect |
| `FND-PFM-NOT-028` | high | Unexpected adapter exceptions are logged using their raw message. Content or credentials embedded in that message can violate the approved logging restriction despite passing normal-path log checks. The product should require redaction on the exception path. | `CAP-PFM-NOT-008` | See `finding_evidence` | defect |
| `FND-PFM-NOT-029` | medium | Collapsed-item withdrawal cannot refresh wording when declared links have been redacted or the recipient is no longer eligible. Ownership and counts change while previous content remains. The product should decide how to present that stale-content boundary. | `CAP-PFM-NOT-005` | See `finding_evidence` | debt |
| `FND-PFM-NOT-030` | medium | Communication recovery can resubmit after the ambiguity interval. A first submission that reached the provider but was not recorded can therefore duplicate delivery. The product should define its acceptable ambiguity policy before promising exactly-once sending. | `CAP-PFM-NOT-018` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-031` | high | Sender provisioning adopts existing provider identities, and purge deletes adopted identities too. The examined sources do not establish exclusive cross-workspace ownership. The product should resolve reference ownership before deleting shared identities. | `CAP-PFM-NOT-020` | See `finding_evidence` | debt |
| `FND-PFM-NOT-032` | medium | Allowed notification paths prove their own screens and behavior only. They do not establish repository-wide absence of communication interfaces or aliases, nor the internals of responsibility and provisioning producers. Those areas need their owning examination. | `CAP-PFM-NOT-014`, `CAP-PFM-NOT-019`, `CAP-PFM-NOT-020` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-033` | medium | Caller-rendered purposes, Marketing-version content and changed-message behavior have code evidence without corresponding Andrew approval in the examined records. The product should record authority for these extensions before design relies on them. | `CAP-PFM-NOT-016`, `CAP-PFM-NOT-017`, `CAP-PFM-NOT-019` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-034` | medium | Deployment defines a text-message queue but no text-message consumer. Queue and persistence checks therefore establish preparation rather than deployed text delivery. The product should plan and verify that consumer in the text milestone. | `CAP-PFM-NOT-007` | See `finding_evidence` | debt |
| `FND-PFM-NOT-035` | medium | The changed-message operation accepts a service filter from its invocation and does not independently authenticate that service name. Filtering excludes different labels without establishing caller-exclusive ownership. The product should supply trusted caller identity before relying on that restriction. | `CAP-PFM-NOT-019` | See `finding_evidence` | debt |
| `FND-PFM-NOT-053` | low | Communication-event history has no established partition-retention maintenance in the examined implementation. | `TC-DAT-003`, `CAP-PFM-NOT-019` | Structured control evidence | control-gap |
| `FND-PFM-NOT-054` | medium | Notification-definition retirement logs failed workspace cancellation after commit without an established repair for the remaining requests. | `TC-PI-004`, `TC-AVL-004`, `CAP-PFM-NOT-001` | Structured control evidence | control-gap |
| `FND-PFM-NOT-055` | medium | Communication recovery can resend a submission whose provider acceptance was not recorded, so repeated delivery can produce another message. | `TC-PI-002`, `CAP-PFM-NOT-018` | Structured control evidence | control-gap |
| `FND-PFM-NOT-056` | medium | The changed-message service filter comes from the invocation without independent binding to the caller’s machine identity. | `TC-AZ-002`, `TC-TEN-004`, `TC-IAM-006`, `CAP-PFM-NOT-019` | Structured control evidence | control-gap |
| `FND-PFM-NOT-057` | high | HQ dead-letter and retry responses expose retained channel content without the live customer-entry check required for History; the exception remains undecided. | `TC-AZ-005`, `TC-TEN-002`, `TC-DAT-002`, `CAP-PFM-NOT-012`, `BR-CAP-PFM-NOT-012-07` | Structured control evidence | control-gap |
| `FND-PFM-NOT-058` | low | Association-template draft editing and archiving record neither the changing actor nor an audit entry. | `TC-PI-005`, `CAP-PFM-NOT-016` | Structured control evidence | control-gap |
| `FND-PFM-NOT-059` | medium | Final delivery writes can precede failed notice-summary refresh, and redelivery or nightly reconciliation does not repair that final-state mismatch. | `TC-PI-004`, `TC-AVL-004`, `SVC-PFM-NOT-notifications`, `WF-PFM-NOT-005` | Structured control evidence | control-gap |
| `FND-PFM-NOT-060` | high | Recorded provider feedback can survive a failed suppression write; duplicate detection then prevents replay from applying the missing recipient protection. | `TC-PI-002`, `TC-PI-004`, `TC-PRV-004`, `WF-PFM-NOT-013`, `CAP-PFM-NOT-020` | Structured control evidence | control-gap |
| `FND-PFM-NOT-061` | medium | Template publication locks to allocate a number but does not recheck the earlier content, state and version snapshot against concurrent changes. | `TC-PI-003`, `TC-PI-005`, `CAP-PFM-NOT-016` | Structured control evidence | control-gap |

| `FND-PFM-NOT-036` | high | HQ dead-letter and retry responses include retained channel content without checking the active customer access grant required for History. Route permissions restrict entry, but the examined records do not resolve whether this operational content is exempt from customer access policy. The product should require a grant or redact operator responses before customer channels are adopted. | `CAP-PFM-NOT-012`, `BR-CAP-PFM-NOT-012-07`, `OQ-PFM-NOT-007` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-037` | medium | Retiring a definition marks its open requests cancelled and settled but does not withdraw their notices or end their unsent deliveries. The notices keep counting as unread and still apply, and a queued Slack or text delivery of such a request is still sent, because the delivery consumer checks the notice and the expiry, not the request's outcome. The withdrawal routine the persistence comment names is never called. The product should decide whether retirement withdraws notices (OQ-PFM-NOT-008); the design records the gap in the registration workflow and the request lifecycle. | `CAP-PFM-NOT-001`, `BR-CAP-PFM-NOT-001-11`, `WF-PFM-NOT-001`, `STATE-PFM-NOT-002`, `ADR-PFM-NOT-009` | See `finding_evidence` | defect |
| `FND-PFM-NOT-038` | low | The module asks no model a question, so the design has no inference directory and every contract, workflow and screen carries an empty inference list; the charter does not yet say so in the sentence the conventions require. The planning owner should add that sentence to the charter. | `MOD-PFM-NOT` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-039` | low | Rhythm HQ's read of a workspace's e-mail sender is a GET in the workspace lifecycle module that refreshes verification from the provider and writes the result, so a read changes state, and verification only refreshes when someone looks. The design should move the refresh into a communications operation (or a schedule) and keep the HQ read side-effect free. | `CAP-PFM-NOT-020`, `BR-CAP-PFM-NOT-020-14`, `WF-PFM-NOT-015`, `STATE-PFM-NOT-014`, `SVC-PFM-NOT-communications` | See `finding_evidence` | inconsistency |
| `FND-PFM-NOT-040` | low | The notice status cancelled and the delivery status deferred are declared in the closed vocabularies and excluded by queries, but no current path writes either. Deferral belongs to quiet hours and digests; cancelled notices are covered by superseded. The design should either assign them a path in the preference milestone or remove them. | `STATE-PFM-NOT-003`, `STATE-PFM-NOT-005`, `CAP-PFM-NOT-007` | See `finding_evidence` | debt |
| `FND-PFM-NOT-041` | medium | The two pipelines resolve an uncertain provider hand-off in opposite ways. A notification delivery left sending is failed as ambiguous at nightly reconciliation and never resent; a communication message left submitting is closed as unknown after fifteen minutes and may be submitted again. No record chooses either policy for both. The product should choose one policy per kind of message (recommendation: keep never-resend for staff and HQ alerts, and require the provider's send report or an operator decision before resubmitting association e-mail). | `ADR-PFM-NOT-010`, `WF-PFM-NOT-005`, `WF-PFM-NOT-011`, `CAP-PFM-NOT-008`, `CAP-PFM-NOT-018`, `FND-PFM-NOT-030` | See `finding_evidence` | inconsistency |
| `FND-PFM-NOT-042` | medium | A notification request item that fails processing on all eight receives reaches the dead-letter queue with no request record, because the queue entry was deleted on publication and the record is written only by the processing transaction. History and the request list therefore never show it, and nightly reconciliation only finds expired work among undispatched entries. Only the dead-letter alarm notices. The design should record a failed request (or expose the requests dead-letter queue to Rhythm HQ) so administrators see that a producer's announcement was lost. | `CAP-PFM-NOT-008`, `CAP-PFM-NOT-011`, `WF-PFM-NOT-002`, `WF-PFM-NOT-003`, `SVC-PFM-NOT-notifications` | See `finding_evidence` | undocumented |
| `FND-PFM-NOT-043` | low | Association template draft edits and archiving record no actor and no audit entry; only publication records who published. Notification wording overrides, by contrast, audit publication and deactivation in the security audit stream. The product should decide whether association template changes are audited the same way. | `DOM-PFM-NOT-004`, `CAP-PFM-NOT-016`, `STATE-PFM-NOT-009` | See `finding_evidence` | undocumented |

| `FND-PFM-NOT-044` | medium | Delivery results commit before their notice summary refresh. A failed refresh can leave a notice showing earlier progress; redelivery acknowledges a final delivery without repairing the summary, and nightly reconciliation does not scan final deliveries for this mismatch. | `DOM-PFM-NOT-003`, `SVC-PFM-NOT-notifications`, `STATE-PFM-NOT-003`, `WF-PFM-NOT-005` | See `finding_evidence` | defect |

| `FND-PFM-NOT-045` | high | Feedback saves the event and message summary before adding bounce or complaint suppressions. If suppression fails, the next receive recognizes the event as a duplicate and returns before trying suppression again. The address can remain deliverable despite the recorded permanent bounce or complaint. | `DOM-PFM-NOT-005`, `STATE-PFM-NOT-012`, `WF-PFM-NOT-013`, `CAP-PFM-NOT-020` | See `finding_evidence` | defect |

| `FND-PFM-NOT-046` | medium | Dormant persistence accepts identity activation without checking a phone challenge, and accepts digest delivery without checking collected count or window expiry. The draft confused proposed caller behavior with enforced guards. Future activation needs an approved orchestration path and proof of those checks. | `STATE-PFM-NOT-006`, `STATE-PFM-NOT-008`, `CAP-PFM-NOT-015` | See `finding_evidence` | undocumented |

| `FND-PFM-NOT-047` | low | The chain sheet reads the request through the workspace management route, including when opened from HQ, and expands already loaded delivery events locally. HQ list permission and its access grant do not by themselves establish authority for that separate management route. The draft incorrectly mapped expansion and retry to delivery and instance reads. | `SCR-PFM-NOT-003`, `SCR-PFM-NOT-004`, `SCR-PFM-NOT-005` | See `finding_evidence` | inconsistency |

| `FND-PFM-NOT-048` | medium | The design brief requested for this examination is absent from the supplied checkout. The authoring contract, existing design, planning layer and pinned implementation provide the available basis; requirements unique to the missing brief remain unknown. | `MOD-PFM-NOT` | See `finding_evidence` | undocumented |

| `FND-PFM-NOT-049` | medium | Responsibility and provisioning producer internals, CRM compensation, external library internals and any enabling entity registration are not established by direct reads within this module scope. Their cited records describe contracts, but do not prove producer ordering, deployment grants or custom-field registration. The design marks producer anchors unknown and retains the existing adoption and ownership findings. | `WF-PFM-NOT-006`, `WF-PFM-NOT-009`, `WF-PFM-NOT-014`, `DOM-PFM-NOT-003`, `DOM-PFM-NOT-004`, `DOM-PFM-NOT-005` | See `finding_evidence` | undocumented |

| `FND-PFM-NOT-050` | medium | Owned-template partial saves retain omitted fields from the stored draft, not a fresh published-version read. Creation, draft replacement and publication use separate transactions, so later failure can leave unpublished or edited draft content. The design now describes those boundaries; the desired recovery policy remains open. | `WF-PFM-NOT-014`, `STATE-PFM-NOT-009`, `CAP-PFM-NOT-016` | See `finding_evidence` | implementation gap |
| `FND-PFM-NOT-051` | medium | Template publication inspects active state and an optional expected version before its write transaction. It then locks the row to allocate a publication number but freezes the earlier snapshot without rechecking state or version. Concurrent archive or editing can invalidate the earlier check. Draft replacement does guard its expected version in the update; the publication race remains unresolved. | `DOM-PFM-NOT-004`, `STATE-PFM-NOT-009`, `CAP-PFM-NOT-016` | See `finding_evidence` | implementation gap |

| `FND-PFM-NOT-052` | medium | The final-receive loop still observes its invocation time budget. Messages it does not reach remain draft when the request is returned for dead-letter handling. The planning description expects untouched messages to be attempted on the final receive. The design records the implemented limit without changing that planning rule. | `WF-PFM-NOT-011`, `CAP-PFM-NOT-018` | See `finding_evidence` | implementation gap |

| `FND-PFM-NOT-062` | medium | The test specification for application notification declarations has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-001`, `STATE-PFM-NOT-001` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-063` | medium | The test specification for transactional publication has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-002` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-064` | medium | The test specification for recipient selection has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-003` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-065` | medium | The test specification for recipient-specific rendering has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-004` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-066` | medium | The test specification for repeated-event collapse has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-005` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-067` | medium | The test specification for withdrawal and expiry has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-006`, `STATE-PFM-NOT-002` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-068` | medium | The test specification for notification routing and delivery has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-007`, `STATE-PFM-NOT-003`, `STATE-PFM-NOT-005` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-069` | medium | The test specification for notification recovery and retention has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-008` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-070` | medium | The test specification for the personal inbox has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-009`, `STATE-PFM-NOT-004`, `BR-CAP-PFM-NOT-009-09` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-071` | medium | The test specification for selection and delivery explanations has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-010` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-072` | medium | The test specification for workspace activity review has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-011`, `BR-CAP-PFM-NOT-011-08` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-073` | medium | The test specification for HQ investigation and retry has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-012` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-074` | medium | The test specification for operational alerts has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-013` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-075` | medium | The test specification for responsibility announcements has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-014`, `BR-CAP-PFM-NOT-014-09` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-076` | medium | The test specification for stored delivery configuration has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-015`, `STATE-PFM-NOT-006`, `STATE-PFM-NOT-007`, `STATE-PFM-NOT-008`, `BR-CAP-PFM-NOT-015-13` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-077` | medium | The test specification for association content publication has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-016`, `STATE-PFM-NOT-009` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-078` | medium | The test specification for communication submission has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-017`, `STATE-PFM-NOT-010` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-079` | medium | The test specification for communication sending has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-018`, `STATE-PFM-NOT-011`, `STATE-PFM-NOT-015` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-080` | medium | The test specification for communication outcomes has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-019`, `STATE-PFM-NOT-012` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-081` | medium | The test specification for recipient and sender safeguards has incomplete detailed proof. Missing category cases and lifecycle rows require independent fixtures and assertions; existing composite cases supply only their named test assertions. | `ATS-PFM-NOT-020`, `STATE-PFM-NOT-013`, `STATE-PFM-NOT-014` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-082` | medium | Many retained capability scenarios combine assertions from several executable files. Suite bindings identify contributing assertions rather than complete execution of every composite precondition and step; an assertion-by-assertion qualification run remains required. | `ATS-PFM-NOT-001`, `ATS-PFM-NOT-002`, `ATS-PFM-NOT-003`, `ATS-PFM-NOT-004`, `ATS-PFM-NOT-005`, `ATS-PFM-NOT-006`, `ATS-PFM-NOT-007`, `ATS-PFM-NOT-008`, `ATS-PFM-NOT-009`, `ATS-PFM-NOT-010`, `ATS-PFM-NOT-011`, `ATS-PFM-NOT-012`, `ATS-PFM-NOT-013`, `ATS-PFM-NOT-014`, `ATS-PFM-NOT-015`, `ATS-PFM-NOT-016`, `ATS-PFM-NOT-017`, `ATS-PFM-NOT-018`, `ATS-PFM-NOT-019`, `ATS-PFM-NOT-020` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-083` | medium | Several feature-level chains have specification coverage but no executable file that performs the complete chain. Component capability tests do not supply an executable feature binding by themselves. | `FAS-PFM-NOT-01`, `FAS-PFM-NOT-02`, `FAS-PFM-NOT-03`, `FAS-PFM-NOT-04`, `FAS-PFM-NOT-05`, `FAS-PFM-NOT-06`, `FAS-PFM-NOT-07` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-084` | medium | The added related-capability chains have no inspected executable suite performing their complete sequence. They remain proposed until a cumulative workflow suite supplies the missing assertions. | `ATS-PFM-NOT-001-14`, `ATS-PFM-NOT-002-09`, `ATS-PFM-NOT-003-09`, `ATS-PFM-NOT-004-05`, `ATS-PFM-NOT-005-10`, `ATS-PFM-NOT-006-10`, `ATS-PFM-NOT-007-10`, `ATS-PFM-NOT-008-11`, `ATS-PFM-NOT-009-10`, `ATS-PFM-NOT-010-07`, `ATS-PFM-NOT-011-07`, `ATS-PFM-NOT-012-06`, `ATS-PFM-NOT-013-10`, `ATS-PFM-NOT-014-07`, `ATS-PFM-NOT-015-12`, `ATS-PFM-NOT-016-15`, `ATS-PFM-NOT-017-15`, `ATS-PFM-NOT-018-14`, `ATS-PFM-NOT-019-09`, `ATS-PFM-NOT-020-15` | See frontmatter evidence | coverage-gap |
| `FND-PFM-NOT-085` | medium | Combined domain guarantees still need complete assertion coverage for failure-path logging, publication races, historical purge guards, rollback objects, opt-out exceptions and sender selection. The invariant matrix identifies each guarantee and its scenario or remaining gap. | `INV-DOM-PFM-NOT-003-11`, `INV-DOM-PFM-NOT-004-06`, `INV-DOM-PFM-NOT-004-09`, `INV-DOM-PFM-NOT-005-01`, `INV-DOM-PFM-NOT-005-06`, `INV-DOM-PFM-NOT-005-11`, `INV-DOM-PFM-NOT-005-12` | See frontmatter evidence | coverage-gap |

## Open Questions

| id | question | reason | options | recommendation | affects |
|---|---|---|---|---|---|
| `OQ-PFM-NOT-001` | Should assignment ending be announced when the assignment notice never arrived? | The current sequence can present an ending without a preceding announcement. | Withhold the ending when assignment delivery never occurred; or preserve unconditional ending notices. | The product should withhold that ending until the assignee has received an assignment announcement. | `CAP-PFM-NOT-014`, `JNY-PFM-NOT-002` |
| `OQ-PFM-NOT-002` | Which HQ roles should read and retry notifications? | Current keys belong only to Rhythm Administrator, leaving support access undecided. | Allow support History with grants and administrator retry; or retain administrator-only access. | The product should grant support history reads with active customer access and keep retry restricted to administrators. | `CAP-PFM-NOT-012` |
| `OQ-PFM-NOT-003` | Should HQ also have a console inbox for operational alerts? | The approved scope and later Slack-only decision describe different experiences. | Retain Slack-only delivery; or add a console inbox for HQ recipients. | The product should retain Slack-only routing unless Andrew approves an additional inbox. | `CAP-PFM-NOT-013`, `FEAT-PFM-NOT-05` |
| `OQ-PFM-NOT-004` | How should external channels name a responsibility resource? | Platform lacks resource display names that the console can resolve. | Include producer-supplied display labels; resolve labels from owning modules during rendering; or omit external resource names. | The product should include the resource display label in producer data before external notification channels begin. | `CAP-PFM-NOT-004`, `CAP-PFM-NOT-014` |
| `OQ-PFM-NOT-005` | How should concurrent workspaces share a sending lane? | A large campaign can consume capacity ahead of other active senders. | Allocate equal active-workspace shares; weight shares by plan or volume; or retain arrival-order processing. | The product should allocate equal shares among active workspaces and lend unused capacity to other senders. | `CAP-PFM-NOT-018` |
| `OQ-PFM-NOT-006` | Should ending delegated cover notify the delegate? | A delegate can otherwise miss the removal of responsibilities they were covering. | Send an ending announcement; or retain the current silent ending. | The product should announce delegation ending as part of the planned producer adoption. | `CAP-PFM-NOT-014` |
| `OQ-PFM-NOT-007` | Should operator delivery responses expose customer content without an access grant? | Dead-letter and retry operations return channel content outside the History grant boundary. | Require an active workspace grant for content; redact operator responses to status and identity only; or approve global HQ content access. | The product should redact global operator lists and require an active grant for customer content. | `CAP-PFM-NOT-012` |
| `OQ-PFM-NOT-008` | Should retiring a definition withdraw its open notices as a cancel does? | Retirement today settles open requests but leaves their notices unread and applicable and lets their queued deliveries send, so people keep acting on a kind of notice the application no longer declares. | Withdraw as a cancel (unsent deliveries cancelled, notices no longer apply); leave delivered notices but cancel unsent deliveries; or keep today's behaviour and only settle the requests. | The product should treat retirement as a withdrawal of each open request, run it through the same withdrawal path, and retry or report workspaces where the sweep failed. | `CAP-PFM-NOT-001`, `CAP-PFM-NOT-006`, `WF-PFM-NOT-001`, `FND-PFM-NOT-037` |
| `OQ-PFM-NOT-009` | Which consistency and recovery gaps must close before implementation preparation? | Summary refresh, feedback protection, template publication and final-receive work have separate failure boundaries that the draft understated. | Require repairs before preparation; prepare explicit corrective work with acceptance coverage; or approve the current limits. | The product should prepare corrective work with failure and race scenarios, while treating unprotected feedback and publication races as required fixes. | `FND-PFM-NOT-044`, `FND-PFM-NOT-045`, `FND-PFM-NOT-050`, `FND-PFM-NOT-051`, `FND-PFM-NOT-052` |
