---
id: WF-PFM-NOT-002
title: Publish a staff notification with its business change
trigger: A business change or authorized system caller publishes or cancels staff notification work.
product_area: platform
module: notifications
revision: 1
status: draft
design_intent: confirmed
origin: PLAT-M23 plan approved 2026-10-21 18:05 ET (publishNotification called in the producer's own transaction;
  queue row, dispatcher and orchestrator), services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#2.
  Scope; queued-work standard, Andrew 2026-10-10, services-platform:docs/queued-work.md#2. A dispatcher
  only moves rows
implementation_evidence: observed
inference: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
- CAP-PFM-NOT-002
- CAP-PFM-NOT-008
- CAP-PFM-NOT-009
moves:
- STATE-PFM-NOT-002
crosses:
- SVC-PFM-NOT-notifications
hops:
- n: 1
  actor_or_service: Notification producer (inside its business transaction)
  action: Validate publication or cancellation and insert its derived queue entry through the producer
    capability.
  anchor: '@rhythmsoftware/macroservice-notifications:publishNotification (library 0.2.0)'
  seam: sync
  on_failure: Reject malformed input before writing; a responsibility producer may log the refusal and
    retain its business change.
  left_inconsistent: Written queue work shares the business transaction outcome.
  observer: Producer logs.
  provenance: test
  source: services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#leaves
    nothing to claim when the producer’s transaction rolled back, and one row when it committed
- n: 2
  actor_or_service: Notification producer
  action: After transaction commit, invoke the workspace dispatcher asynchronously.
  anchor: '@rhythmsoftware/macroservice-notifications:nudgeNotificationsDispatcher'
  seam: event
  on_failure: Allow scheduled dispatch to recover a failed nudge.
  left_inconsistent: Dispatch can wait for the next minute run.
  observer: Dispatcher heartbeat and silence monitoring.
  provenance: observed
  source: services-platform:modules/notifications/services/dispatch/dispatch-notifications.ts:dispatchNotifications
- n: 3
  actor_or_service: Notifications dispatcher
  action: Claim entries briefly, publish batches of ten outside a transaction, and remove acknowledged
    entries.
  anchor: services-platform:modules/notifications/services/dispatch/dispatch-notifications.ts:dispatchNotifications
  seam: schedule
  on_failure: Keep refused entries for dispatch after their claims expire.
  left_inconsistent: Publication before deletion can produce repeated queue items, which processing deduplicates.
  observer: Dispatch outcome counters and silence alarm.
  provenance: test
  source: services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#leaves
    work for the next run when a run died between the publish and the delete, and the repeat makes nothing
    twice
- n: 4
  actor_or_service: Request consumer
  action: Pass each received item to request orchestration.
  anchor: services-platform:modules/notifications/aws/lambda/ORCHESTRATE.handler.ts
  seam: queue
  on_failure: Use queue redelivery up to eight receives before dead-letter handling.
  left_inconsistent: Dead-lettered work may have no request outcome in History.
  observer: Production queue-age and dead-letter alarms.
  provenance: documented
  source: services-platform:docs/notifications.md#6. The pipeline
idempotency: Workspace, producer, key and kind identify one queue entry; processing recognizes an existing
  outcome.
concurrency: Exclusive dispatcher claims and reserved concurrency serialize dispatch while producers write
  independent work.
branches:
- System HTTP and IAM doors use their own short transactions and reject console callers.
- The personal test operation publishes for the authenticated person.
- HQ alerts use the reserved system workspace.
waits:
- A lost nudge can add a minute before scheduled dispatch.
evidence:
- 'services-platform at ad3f6a65: modules/notifications/services/requests/submit-notification-request.ts;
  services/dispatch/{dispatch-notifications,notification-queues}.ts; aws/lambda/{DISPATCHER,ORCHESTRATE,REQUEST}.handler.ts;
  docs/notifications.md §2, §6, §9.'
controls: [TC-AVL-001, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CHG-005, TC-CHG-006, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-MON-002, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-PRV-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---
# Publish a staff notification with its business change

## What It Does

A business change or authorized system caller publishes or cancels staff notification work.

## The Flow

```mermaid
flowchart TD
    h0["Validate publication or cancellation and insert its derived queue entry through the producer capability"]
    h1["After transaction commit, invoke the workspace dispatcher asynchronously"]
    h0 --> h1
    h2["Claim entries briefly, publish batches of ten outside a transaction, and remove acknowledged entries"]
    h1 --> h2
    h3["Pass each received item to request orchestration"]
    h2 --> h3
```

## When Something Fails

The hop rows identify each retry boundary, any state left behind and the available observer. Workspace, producer, key and kind identify one queue entry; processing recognizes an existing outcome. Exclusive dispatcher claims and reserved concurrency serialize dispatch while producers write independent work.

## Open Design Questions

System HTTP and IAM doors use their own short transactions and reject console callers. The personal test operation publishes for the authenticated person. HQ alerts use the reserved system workspace. A lost nudge can add a minute before scheduled dispatch.
