---
id: CAP-PFM-NOT-005
title: Combine repeated events into one notice
feature: FEAT-PFM-NOT-02
product_area: platform
module: notifications
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes:
  - NT-ACC-0205
  - PLAT-M23-S11
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#2. Scope'
  - >-
    services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#PLAT-M23-S11
purpose: >-
  Recipients see one useful item for a burst of related events while the
  underlying contributions remain traceable.
outcomes:
  - Matching event bursts share one recipient notice.
  - Withdrawal updates folded content when rerendering remains possible.
concepts:
  - CON-PFM-NOT-003
actors:
  - ACT-PFM-031
surfaces:
  - job
preconditions: []
postconditions: []
permissions: []
rules:
  - id: BR-CAP-PFM-NOT-005-01
    statement: >-
      Within the configured collapse interval, requests for the same definition,
      recipient and subject record can share a notice; the default interval is
      two minutes; zero disables collapse; Different records or recipients
      remain separate.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/orchestration/cancel-and-supersede.integration.spec.js#folds
      five requests into one notification carrying the latest data and the count
    origin: none
  - id: BR-CAP-PFM-NOT-005-02
    statement: >-
      Only applicable, unread and unarchived notices accept another
      contribution; Otherwise processing creates a fresh unread notice.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/orchestration/cancel-and-supersede.integration.spec.js#makes
      a new, unread notification when the one it would fold into was read
    origin: none
  - id: BR-CAP-PFM-NOT-005-03
    statement: >-
      When both contributions specify a scope, collapse requires equal scopes; a
      contribution without a scope can match a scoped notice.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/orchestration/cancel-and-supersede.integration.spec.js#folds
      requests of the same scope and keeps requests of another scope apart
    origin: none
  - id: BR-CAP-PFM-NOT-005-04
    statement: >-
      Collapse adopts the latest contribution's data and wording, increases the
      contribution count and retains the latest fifty request references.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/unit/collapsing.spec.js#keeps
      the newest fifty and drops the oldest
    origin: none
  - id: BR-CAP-PFM-NOT-005-05
    statement: >-
      A transaction lock serializes matching recipient, definition, record and
      scope identities; work with a different lock identity proceeds
      independently.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/orchestration/cancel-and-supersede.integration.spec.js#folds
      ten requests dispatched at the same moment into one notification of
      collapsed count nine
    origin: none
    note: >-
      A hash-based advisory lock does not prove that a different identity never
      waits.
  - id: BR-CAP-PFM-NOT-005-06
    statement: >-
      Removing a contribution reduces the count and can move ownership to the
      oldest remaining open request; Removing the latest contribution refreshes
      wording when renderable; removing the final contribution supersedes the
      notice.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/orchestration/cancel-and-supersede.integration.spec.js#keeps
      the notification when the first of its requests ends, handing it to the
      next and dropping the count
    origin: none
  - id: BR-CAP-PFM-NOT-005-07
    statement: >-
      An occurrence produces at most one notice for each recipient even when
      repeated requests cross monthly boundaries.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/orchestration/orchestrate-request.integration.spec.js#makes
      one instance for one occurrence however many requests name it
    origin: none
  - id: BR-CAP-PFM-NOT-005-08
    statement: >-
      When link data has been redacted or the recipient is no longer eligible, a
      collapsed notice retains its earlier wording rather than re-rendering
      after withdrawal.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-platform:modules/notifications/services/orchestration/orchestrate-request.ts:rerenderMessage
    origin: none
scenarios:
  - id: SC-CAP-PFM-NOT-005-01
    given: >-
      Jane receives five Batch posting assignment events within two minutes with
      different ending dates.
    when: All matching events pass through processing.
    then: >-
      One unread item presents the latest details and four additional collapsed
      contributions.
    provenance: test
    source: >-
      react-console:acceptance/notifications/playwright/journeys/pipeline/NT-ACC-0205.spec.ts#NT-ACC-0205
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-NOT-003
related:
  - CAP-PFM-NOT-006
  - CAP-PFM-NOT-009
journeys:
  - JNY-PFM-NOT-005
open_questions: []
evidence:
  - >-
    Pinned evidence inventory 1:
    services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md;
    services-platform:modules/notifications/tests/unit/collapsing.spec.js;
    services-platform:modules/notifications/services/orchestration/orchestrate-request.ts
  - >-
    Pinned evidence inventory 2:
    services-platform:modules/notifications/tests/integration/services/orchestration/cancel-and-supersede.integration.spec.js;
    services-platform:modules/notifications/tests/integration/services/orchestration/orchestrate-request.integration.spec.js;
    react-console:acceptance/notifications/playwright/journeys/pipeline/NT-ACC-0205.spec.ts
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-PI-001, TC-PI-003, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Combine repeated events into one notice

## Purpose

Recipients see one useful item for a burst of related events while the underlying contributions remain traceable.

## How It Works

Platform looks for a matching applicable notice before creating another item. The match considers recipient, definition, subject record, timing and scope. Read or archived items do not absorb later requests. Matching work shares a transaction lock. A successful collapse updates the notice and retains contribution references. Withdrawal removes one contribution and can transfer ownership or supersede the item. Rendering after withdrawal is conditional on remaining data and recipient eligibility. Those conditions can leave earlier wording visible even after the newest contribution disappears.

The rule rows define this outcome; the acceptance set identifies existing proof and proposed checks. Implementation evidence alone does not approve the observed details.

## Relationships

Recipient selection supplies the eligible people and their audience explanations.
