Replays and deliveries

One local effect per event key, snapshots that never post, and deliveries that retry only when the receiver cannot apply an event twice.

Request with "decision": "replay" and one of these operations: apply, deliver.

Clauses applied

  • replay.key: Same EventKey and digest returns the existing effect, while conflicting digest is rejected.
  • replay.snapshot: Repeated stock snapshot plus adjustment event can never each be treated as a fresh physical increase.
  • replay.delivery: WarehouseDeliveries retries only transport; event-mode consumers post each signed delta once, snapshots replace nonposting positions at a monotonic revision, and receivers without deduplication require reconciliation before retry.

Evidence questions

destination_outcome@1

This is what a receiving system returned for one warehouse event delivered to it. Did the receiving system apply the event?

AnswerMeaning
appliedYes. It recorded the event, or reports that it already holds this event.
not_appliedNo. It rejected the event or never processed it, and recorded nothing.
not_establishedUnknown. The reply does not settle it, such as a timeout, a dropped connection, a queued acknowledgement or an ambiguous error.

Examples

Finance replies that the journal already exists

{
  "decision": "replay",
  "proposal": {
    "operation": "deliver",
    "key": "adj-2026-10-02-0091",
    "digest": "9be1d2"
  },
  "destination": {
    "name": "NetSuite",
    "mode": "event",
    "dedupe": "none"
  },
  "attempts": [
    {
      "transport": "sent",
      "at": "2026-10-02T16:01:09Z",
      "evidence": "httpx.ReadTimeout: The read operation timed out"
    },
    {
      "transport": "response_received",
      "http_status": 400,
      "at": "2026-10-02T16:03:40Z",
      "evidence": "{\"o:errorDetails\":[{\"detail\":\"A record with external ID adj-2026-10-02-0091 already exists (Journal Entry JE-118204).\",\"o:errorCode\":\"DUP_RCRD\"}]}"
    }
  ]
}

Response from the rules with no model loaded, so every question abstains.

{
  "verdict": "reconcile",
  "next": {
    "action": "query_destination",
    "text": "It is not established whether NetSuite applied event adj-2026-10-02-0091, and it does not deduplicate. Query it before any retry.",
    "role": "Inventory Controller"
  },
  "questions": [
    {
      "ask": "attempts/0",
      "question": "destination_outcome@1",
      "status": "model_unavailable",
      "evidence": [
        "/attempts/0/evidence"
      ]
    },
    {
      "ask": "attempts/1",
      "question": "destination_outcome@1",
      "status": "model_unavailable",
      "evidence": [
        "/attempts/1/evidence"
      ]
    }
  ]
}

Download the request

The same event key arrives with different content

{
  "decision": "replay",
  "proposal": {
    "operation": "apply",
    "key": "rcp-55120",
    "digest": "a71e",
    "kind": "event",
    "delta": "25"
  },
  "events": [
    {
      "key": "open",
      "digest": "o1",
      "kind": "opening",
      "delta": "100"
    },
    {
      "key": "rcp-55120",
      "digest": "f02c",
      "kind": "event",
      "delta": "20"
    }
  ]
}

Response from the rules with no model loaded, so every question abstains.

{
  "verdict": "reject",
  "next": {
    "action": "resolve_conflict",
    "text": "Event key rcp-55120 was applied with different content. A changed digest under the same key is a conflict.",
    "role": "Inventory Controller"
  },
  "questions": []
}

Download the request

Request schema

{
  "type": "object",
  "required": [
    "decision",
    "proposal"
  ],
  "additionalProperties": false,
  "properties": {
    "decision": {
      "const": "replay"
    },
    "proposal": {
      "type": "object",
      "required": [
        "operation",
        "key",
        "digest"
      ],
      "additionalProperties": false,
      "properties": {
        "operation": {
          "type": "string",
          "enum": [
            "apply",
            "deliver"
          ]
        },
        "key": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "digest": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "kind": {
          "type": "string",
          "enum": [
            "event",
            "snapshot"
          ]
        },
        "delta": {
          "type": "string",
          "format": "signed-decimal"
        }
      }
    },
    "events": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "key",
          "digest",
          "kind",
          "delta"
        ],
        "additionalProperties": false,
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "digest": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "kind": {
            "type": "string",
            "enum": [
              "opening",
              "event",
              "snapshot"
            ]
          },
          "delta": {
            "type": "string",
            "format": "signed-decimal"
          }
        }
      },
      "maxItems": 10000
    },
    "destination": {
      "type": "object",
      "required": [
        "name",
        "mode",
        "dedupe"
      ],
      "additionalProperties": false,
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "mode": {
          "type": "string",
          "enum": [
            "event",
            "snapshot"
          ]
        },
        "dedupe": {
          "type": "string",
          "enum": [
            "verified",
            "none"
          ]
        }
      }
    },
    "attempts": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "transport"
        ],
        "additionalProperties": false,
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "transport": {
            "type": "string",
            "enum": [
              "not_sent",
              "sent",
              "response_received"
            ]
          },
          "http_status": {
            "type": "integer",
            "minimum": 100,
            "maximum": 599
          },
          "evidence": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000
          }
        }
      },
      "maxItems": 50
    }
  }
}