---
id: SVC-PFM-NOT-communications
title: Communications Service Module
product_area: platform
module: notifications
repository: services-platform
source_module: modules/communications
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owns:
- DOM-PFM-NOT-004
- DOM-PFM-NOT-005
does_not_own:
- Notifications owns staff inbox records and any future staff e-mail request it submits here.
- Business modules own purpose source records and their custom fields; CRM owns contact opt-out facts.
- Marketing owns campaigns and subscription decisions; Accounting owns invoice wording and attachments.
- Workspace lifecycle owns provisioning and the HQ sender read, while Communications implements sender
  identity behavior.
- The examined console scope has no template, communication-history or suppression administration screen.
operations:
- operation_id: getCommunicationsHealth
  intent: Expose communications API health and deployed build for operations.
  access: public
  permission: 'none: public route'
  realises: []
  published_to_submissions: 'not published: service health is an operational read without a submission
    binding.'
- operation_id: listCommunicationPurposes
  intent: Describe editable purposes, source fields, sample values and starter content.
  access: console
  permission: platform.communication-templates.read
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: purpose metadata supports staff content authoring.'
- operation_id: listCommunicationTemplates
  intent: Inspect workspace templates with optional purpose and archived inclusion, excluding Marketing-owned
    content.
  access: console
  permission: platform.communication-templates.read
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: the operation inspects association content and publication
    history.'
- operation_id: createCommunicationTemplate
  intent: Start editable content for a purpose that uses association templates.
  access: console
  permission: platform.communication-templates.create
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: staff manage reusable communication content through the authoring
    API.'
- operation_id: getCommunicationTemplate
  intent: Inspect a template’s editable content, validation and current publication.
  access: console
  permission: platform.communication-templates.read
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: the operation inspects association content and publication
    history.'
- operation_id: updateCommunicationTemplate
  intent: Save replacement draft content only when the editor’s version is current.
  access: console
  permission: platform.communication-templates.update
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: staff manage reusable communication content through the authoring
    API.'
- operation_id: archiveCommunicationTemplate
  intent: Remove a template from active use while retaining its publications.
  access: console
  permission: platform.communication-templates.delete
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: staff manage reusable communication content through the authoring
    API.'
- operation_id: validateCommunicationTemplate
  intent: Save the draft’s validation results without creating a publication.
  access: console
  permission: platform.communication-templates.update
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: staff manage reusable communication content through the authoring
    API.'
- operation_id: previewCommunicationTemplate
  intent: Render selected draft or published content with sample or supplied values without sending it.
  access: console
  permission: platform.communication-templates.read
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: preview and test operations support content review before
    delivery.'
- operation_id: testSendCommunicationTemplate
  intent: Send a marked draft or publication test to the requester, a test mailbox or an allowed address.
  access: console
  permission: platform.communication-templates.test-send
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: preview and test operations support content review before
    delivery.'
- operation_id: publishCommunicationTemplate
  intent: Create the next immutable snapshot after validating the draft.
  access: console
  permission: platform.communication-templates.publish
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: staff manage reusable communication content through the authoring
    API.'
- operation_id: listCommunicationTemplateVersions
  intent: Inspect the publication history of one template.
  access: console
  permission: platform.communication-templates.read
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: the operation inspects association content and publication
    history.'
- operation_id: getCommunicationTemplateVersion
  intent: Retrieve the frozen content of a selected publication.
  access: console
  permission: platform.communication-templates.read
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: the operation inspects association content and publication
    history.'
- operation_id: getCommunicationReadiness
  intent: Check one template or owner for send readiness and explain configuration blockers.
  access: console
  permission: platform.communication-templates.read
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: readiness diagnoses the owner’s communication configuration.'
- operation_id: listCommunicationMessages
  intent: Inspect workspace messages by recipient, request, source, purpose or delivery progress.
  access: console
  permission: platform.communication-messages.read
  realises:
  - CAP-PFM-NOT-019
  published_to_submissions: 'not published: the operation reads stored communication outcomes.'
- operation_id: getCommunicationMessage
  intent: Inspect a message with its attempts, referenced content and bounded provider-event history.
  access: console
  permission: platform.communication-messages.read
  realises:
  - CAP-PFM-NOT-019
  published_to_submissions: 'not published: the operation reads stored communication outcomes.'
- operation_id: getCommunicationMessageContent
  intent: Retrieve retained rendered content under the separate content-read permission.
  access: console
  permission: platform.communication-messages.read-content
  realises:
  - CAP-PFM-NOT-019
  published_to_submissions: 'not published: the operation reads stored communication outcomes.'
- operation_id: cancelCommunicationMessage
  intent: Stop a recipient message while it remains a draft.
  access: console
  permission: platform.communication-messages.update
  realises:
  - CAP-PFM-NOT-018
  published_to_submissions: 'not published: staff can cancel existing draft sending work.'
- operation_id: listCommunicationRequests
  intent: Inspect up to fifty newest requests associated with a specified source record.
  access: console
  permission: platform.communication-messages.read
  realises:
  - CAP-PFM-NOT-019
  published_to_submissions: 'not published: the operation reads stored communication outcomes.'
- operation_id: getCommunicationRequest
  intent: Inspect request acceptance, blocking reasons and recipient-message progress counts.
  access: console
  permission: platform.communication-messages.read
  realises:
  - CAP-PFM-NOT-019
  published_to_submissions: 'not published: the operation reads stored communication outcomes.'
- operation_id: requestCommunication
  intent: Accept a system request, persist its object and committed pointer, and return a receipt.
  access: system
  permission: platform.communications.request
  realises:
  - CAP-PFM-NOT-017
  published_to_submissions: 'not published: domain services select and submit communication requests.'
- operation_id: listCommunicationSuppressions
  intent: Inspect active address suppressions, optionally including released history.
  access: console
  permission: platform.communication-suppressions.read
  realises:
  - CAP-PFM-NOT-020
  published_to_submissions: 'not published: address protection is administered by authorized staff.'
- operation_id: createCommunicationSuppression
  intent: Add a manual address suppression with an optional staff explanation.
  access: console
  permission: platform.communication-suppressions.create
  realises:
  - CAP-PFM-NOT-020
  published_to_submissions: 'not published: address protection is administered by authorized staff.'
- operation_id: releaseCommunicationSuppression
  intent: End an active suppression while retaining the staff actor and reason.
  access: console
  permission: platform.communication-suppressions.update
  realises:
  - CAP-PFM-NOT-020
  published_to_submissions: 'not published: address protection is administered by authorized staff.'
- operation_id: request (IAM operation of platform_communications_request)
  intent: Accept a service request when the caller has no existing business transaction.
  access: internal
  permission: the platform-communications-request-invoke managed policy
  realises:
  - CAP-PFM-NOT-017
  published_to_submissions: 'not published: business services submit recipient mail directly.'
- operation_id: submitCommunicationRequest (shared library, in the caller's transaction)
  intent: Store the communication object and insert its pointer within the caller’s transaction.
  access: internal
  permission: the request-store policy and the rhythm_communications_submitter capability role
  realises:
  - CAP-PFM-NOT-017
  published_to_submissions: 'not published: the business owner publishes work inside its own transaction.'
- operation_id: readiness, testSend and renderPreview (IAM operations)
  intent: Provide service callers with readiness, test delivery and content preview.
  access: internal
  permission: the platform-communications-request-invoke managed policy
  realises:
  - CAP-PFM-NOT-016
  - CAP-PFM-NOT-017
  published_to_submissions: 'not published: service callers inspect and test their communication content.'
- operation_id: saveOwnedTemplate, clearOwnedTemplate and getOwnedTemplates (IAM operations)
  intent: Compose, remove or retrieve the template owned by a business record.
  access: internal
  permission: the platform-communications-request-invoke managed policy
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: the owning record composes its content through its own save
    contract.'
- operation_id: changedMessages (IAM operation)
  intent: Return messages changed since a cursor, filtered by the supplied submitting-service label rather
    than authenticated service identity.
  access: internal
  permission: the platform-communications-request-invoke managed policy; service filter not authenticated
    (FND-PFM-NOT-035)
  realises:
  - CAP-PFM-NOT-019
  published_to_submissions: 'not published: the change feed synchronizes existing communication outcomes.'
- operation_id: storeMessageVersionTemplate (IAM function platform_communications_message_templates)
  intent: Publish immutable content owned by a Marketing message version, returning the existing publication
    for an identical repeat.
  access: internal
  permission: the platform-communications-message-templates-invoke managed policy, given only to Marketing
  realises:
  - CAP-PFM-NOT-016
  published_to_submissions: 'not published: Marketing publishes content owned by its message version.'
- operation_id: nudgeCommunicationsDispatcher (IAM invoke of platform_communications_dispatcher)
  intent: Wake communication dispatch after the caller commits its pointer.
  access: internal
  permission: the platform-communications-dispatcher-invoke managed policy
  realises:
  - CAP-PFM-NOT-018
  published_to_submissions: 'not published: the invocation wakes internal dispatch after commit.'
events:
- name: SES configuration-set events (send, delivery, delivery delay, bounce, complaint, reject, open,
    click)
  direction: consumed
  when: SES reports a configured message event through EventBridge and the feedback queue.
  payload_summary: Provider message identity, workspace and message tags, event type, report time and
    recipient diagnostics correlate feedback.
jobs:
- Communication dispatch runs each minute or after a nudge and publishes claimed workspace pointers to
  their purpose lane.
- Transactional and Marketing consumers each process one queued request and send its remaining eligible
  messages.
- The quota guard reads account capacity each minute, updates lane budgets and controls the Marketing
  consumer mapping.
- The feedback consumer processes batches of ten provider reports with at most three concurrent mappings.
- Sender and communication lifecycle participants support provisioning checks and workspace removal.
integrations:
- system: Amazon SES
  direction: outbound and inbound
  contract: SES receives lane-classified e-mail with correlation tags and Marketing unsubscribe headers,
    supplies quota and identity reads, and returns configuration-set reports.
- system: Amazon S3 (platform-communications bucket)
  direction: outbound
  contract: The communication bucket retains producer request objects for thirty days and rendered message
    objects until workspace removal.
- system: Amazon SQS
  direction: outbound and inbound
  contract: Both sending lanes use eight receives and twenty-minute visibility; provider feedback uses
    five receives before dead-lettering.
consistency:
- rule: A caller’s business transaction commits or removes its dispatch pointer.
  kind: transactional
  compensation: An object written before rollback can remain unsent until thirty-day expiry.
- rule: Acceptance commits the request and recipient messages after storing rendered bodies.
  kind: transactional
  compensation: A retry can overwrite deterministic body objects left by a failed database transaction.
- rule: An in-flight message cannot be claimed again within the ambiguity interval.
  kind: eventual
  compensation: An older unrecorded attempt can be closed unknown and resubmitted, creating duplicate-provider
    risk.
- rule: Provider summaries and recipient suppression are updated asynchronously.
  kind: eventual
  compensation: Event commitment precedes suppression; duplicate feedback can skip a suppression that
    previously failed.
- rule: Transactional capacity reserves a share ahead of Marketing.
  kind: eventual
  compensation: Budget waits publish fresh delayed work rather than consume retries; Marketing pauses
    near quota exhaustion.
evidence:
- 'services-platform at ad3f6a65: modules/communications/aws/api/communications.routes.ts (24 routes including
  health); services/requests/handle-invocation.ts (eight IAM operations); aws/logic/communications-functions.lambda.ts
  (eight functions); aws/resources/*.ts; aws/platform.service.ts (communication permission groups).'
- 'services-platform at ad3f6a65: docs/communications/architecture.md §5.5, §18, §20 to §22; docs/queued-work.md
  §5 and §8.'
controls: [TC-AVL-001, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, 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-DAT-006, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-MON-001, 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-SEC-001, TC-SEC-002, TC-SEC-003, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---
# Communications Service Module

## What This Service Is For

Communications sends association e-mail requested by business workflows and retains its history. It owns reusable publications, processed requests, recipient messages, protection, sender identity and account-wide lane capacity.

## Boundary

Notifications owns staff inbox records and any future staff e-mail request it submits here. Business modules own purpose source records and their custom fields; CRM owns contact opt-out facts. Marketing owns campaigns and subscription decisions; Accounting owns invoice wording and attachments. Workspace lifecycle owns provisioning and the HQ sender read, while Communications implements sender identity behavior. The examined console scope has no template, communication-history or suppression administration screen.

## Operations in Words

Expose communications API health and deployed build for operations.

Describe editable purposes, source fields, sample values and starter content. Inspect workspace templates with optional purpose and archived inclusion, excluding Marketing-owned content. Start editable content for a purpose that uses association templates. Inspect a template’s editable content, validation and current publication. Save replacement draft content only when the editor’s version is current. Remove a template from active use while retaining its publications. Save the draft’s validation results without creating a publication. Render selected draft or published content with sample or supplied values without sending it. Send a marked draft or publication test to the requester, a test mailbox or an allowed address. Create the next immutable snapshot after validating the draft. Inspect the publication history of one template. Retrieve the frozen content of a selected publication. Check one template or owner for send readiness and explain configuration blockers. Inspect workspace messages by recipient, request, source, purpose or delivery progress. Inspect a message with its attempts, referenced content and bounded provider-event history. Retrieve retained rendered content under the separate content-read permission. Stop a recipient message while it remains a draft. Inspect up to fifty newest requests associated with a specified source record. Inspect request acceptance, blocking reasons and recipient-message progress counts. Inspect active address suppressions, optionally including released history. Add a manual address suppression with an optional staff explanation. End an active suppression while retaining the staff actor and reason.

Accept a system request, persist its object and committed pointer, and return a receipt.

Accept a service request when the caller has no existing business transaction. Store the communication object and insert its pointer within the caller’s transaction. Provide service callers with readiness, test delivery and content preview. Compose, remove or retrieve the template owned by a business record. Return messages changed since a cursor, filtered by the supplied submitting-service label rather than authenticated service identity. Publish immutable content owned by a Marketing message version, returning the existing publication for an identical repeat. Wake communication dispatch after the caller commits its pointer.

## Events and Jobs

Two sending lanes share acceptance and dispatch behavior. The dispatcher and quota guard run each minute, while feedback arrives through a separate queue. Sender lifecycle work creates or adopts provider identities, checks their presence and removes them during purge. Marketing content has a separate invocation capability; the external grant and its default-off adoption are not verified here.

## Consistency Guarantees

An object written before rollback can remain unsent until thirty-day expiry. A retry can overwrite deterministic body objects left by a failed database transaction. An older unrecorded attempt can be closed unknown and resubmitted, creating duplicate-provider risk. Event commitment precedes suppression; duplicate feedback can skip a suppression that previously failed. Budget waits publish fresh delayed work rather than consume retries; Marketing pauses near quota exhaustion.
