---
id: STATE-PFM-INT-009
title: Received provider message processing
object: DOM-PFM-INT-004
product_area: platform
module: integrations
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
states:
  - name: queued
    meaning: 'Ingress retained the message and its processing work, with verification still pending.'
  - name: processing
    meaning: A numbered processing attempt is verifying and interpreting the message.
  - name: processed
    meaning: Verified interpretation committed events and their routing work.
  - name: ignored
    meaning: Signature refusal or deduplication prevented event creation.
  - name: failed
    meaning: A transient processing failure has another attempt scheduled.
  - name: dead
    meaning: Processing stopped after exhaustion or a permanent failure.
transitions:
  - from: queued
    to: processing
    trigger: Claim a message-processing attempt
    guard: The numbered queued attempt is current and can be claimed
    side_effects:
      - Lease endpoint secrets and supply a short-lived raw-body address.
    who: Webhook worker
    provenance: observed
    source: 'services-platform:modules/integrations/services/webhooks/webhook-worker.ts:processWebhookEvent'
  - from: processing
    to: processed
    trigger: Accept verified interpretation
    guard: Signature and deduplication checks pass
    side_effects:
      - Commit interpreted events and routing work
      - Save emitted event identities.
    who: Webhook worker
    provenance: observed
    source: 'services-platform:modules/integrations/services/webhooks/webhook-worker.ts'
  - from: processing
    to: ignored
    trigger: Discard rejected or repeated input
    guard: Signature fails or processed event identity or digest matches
    side_effects:
      - Save no new events and update rejection telemetry.
    who: Webhook worker
    provenance: observed
    source: 'services-platform:modules/integrations/services/webhooks/webhook-worker.ts'
  - from: processing
    to: failed
    trigger: Schedule recovery from transient processing failure
    guard: Backoff permits another attempt below the processing ceiling
    side_effects:
      - Retain failed status with future dispatch work.
    who: Webhook worker
    provenance: observed
    source: 'services-platform:modules/integrations/services/webhooks/webhook-worker.ts'
  - from: failed
    to: processing
    trigger: Claim the next processing attempt
    guard: The deferred attempt is due and still current
    side_effects:
      - Repeat secret leasing and adapter verification.
    who: Webhook worker
    provenance: observed
    source: 'services-platform:modules/integrations/services/webhooks/webhook-worker.ts:processWebhookEvent'
  - from: processing
    to: dead
    trigger: Exhaust processing retries
    guard: The sixth numbered attempt fails
    side_effects:
      - Save dead status and emit dead-message telemetry.
    who: Webhook worker
    provenance: observed
    source: 'services-platform:modules/integrations/services/webhooks/webhook-worker.ts'
  - from: processing
    to: dead
    trigger: Encounter permanent processing failure
    guard: The failure class does not permit retry
    side_effects:
      - Save dead status and emit dead-message telemetry.
    who: Webhook worker
    provenance: observed
    source: 'services-platform:modules/integrations/services/webhooks/webhook-worker.ts'
invalid:
  - from: processed
    to: processing
    why: Settled message records are not processed again in place; replay creates another message.
  - from: dead
    to: processed
    why: A dead record remains historical; its retained body can supply a new replay record.
concurrency: >-
  Ingress stores bodies before committing message and dispatch records. Worker attempts are claimed by their
  number and terminal repeats are skipped. Replay bypasses input deduplication and can create another
  interpreted event after the original processing.
invariants:
  - INV-DOM-PFM-INT-004-01
  - INV-DOM-PFM-INT-004-02
evidence:
  - >-
    services-platform at ad3f6a65: modules/integrations/db/integration-webhook-events.table.ts;
    services/webhooks/ingress.ts, webhook-worker.ts; services/events/event-operations.ts (replays);
    services-platform:docs/milestones/INTG-M3-webhooks-events-deliveries.md (status Proposed)
---

# Received provider message processing

## The Lifecycle

```mermaid
stateDiagram-v2
  state "queued" as s0
  state "processing" as s1
  state "processed" as s2
  state "ignored" as s3
  state "failed" as s4
  state "dead" as s5
  s0 --> s1: Claim a message-processing attempt
  s1 --> s2: Accept verified interpretation
  s1 --> s3: Discard rejected or repeated input
  s1 --> s4: Schedule recovery from transient processing failure
  s4 --> s1: Claim the next processing attempt
  s1 --> s5: Exhaust processing retries
  s1 --> s5: Encounter permanent processing failure
```

## Transitions Explained

Ingress creates queued message records, and workers claim numbered attempts before verification. Verified interpretation commits events; rejected signatures and duplicates create no events. Replay is a separate creation flow using the retained body, not an outgoing transition of the original record.

## What Cannot Happen

Settled message records are not processed again in place; replay creates another message. A dead record remains historical; its retained body can supply a new replay record.

## Concurrency and Timing

Ingress stores bodies before committing message and dispatch records. Worker attempts are claimed by their number and terminal repeats are skipped. Replay bypasses input deduplication and can create another interpreted event after the original processing.
