Transport repetition is not a new business event. Preserve stable source identity, distinguish exact replay from conflicting content, and keep later observations out of earlier evidence.
A retry must retain its identity
When a sender cannot tell whether a request succeeded, it may retry. The receiver needs a stable way to recognize the observation. Generating identity from row position, campaign name or a newly assigned receipt timestamp can turn that transport repetition into another acquisition or another monetary amount.
R2 constructs event identity from the tenant, source instance, source role and source event ID. The source instance distinguishes two provider accounts that happen to use the same event number. Tenant scope prevents unrelated workspaces from sharing a persistence key. Receipt time does not create a new business identity.
A duplicate and a conflict need different outcomes
If the identity and normalized payload match an accepted observation, delivery is a duplicate. The original remains authoritative for that identity and the caller receives an explicit duplicate result. That behavior lets a sender retry without adding another economic event.
If the identity matches but the payload changes, the result is a conflict. The receiver must not silently replace the original event or count both versions as two acquisitions. In the current bounded ingress, conflicting content is rejected while the accepted record is preserved. A complete operational quarantine and remediation policy is a separate integration concern; an HTTP response alone does not supply that workflow.
same scoped identity + same payload → duplicate
same scoped identity + changed payload → conflict
new scoped identity + valid payload → acceptedCorrelation is not a causal explanation
An explicit parent reference tells the comparison which acquisition a partner callback claims to confirm. That reference still needs to agree with the tenant, operator and partner relationship. A callback pointing to an unrelated subject cannot repair the missing confirmation simply because its timestamp is close.
The resulting lineage shows where the observed sequence diverges from the configured expectation. It does not prove whether the cause was a receiver outage, a sender retry policy, an identifier transformation or a commercial rejection. Those are hypotheses to investigate with additional evidence.
Replay the evidence available then
Suppose a callback occurred before the deadline but was received after the investigation cutoff. The later snapshot can include it; the earlier one should not. Otherwise, a historical report changes meaning whenever a delayed event arrives.
Replay needs both source occurrence time and receipt time, plus the completeness declarations available at the chosen cutoff. A deterministic evidence hash lets you identify the exact resulting content. It does not attest that the upstream source was truthful or that every expected record was delivered.
Test delivery behavior as part of onboarding
These checks are practical acceptance criteria for an adapter. They do not replace live provider validation for authentication, pagination, rate limits or source completeness. Keep adapter status explicit until those operational boundaries are exercised.
- Send the same event twice and inspect the duplicate result.
- Change an amount or subject under the same identity and require a conflict.
- Reuse a source event ID in another account and another tenant.
- Send a callback with the wrong originating-event reference.
- Compare snapshots before and after a delayed receipt.
- Exercise partial batches and inspect every per-event result before retrying.
Inspect the implementation
These notes describe the R2 model and its current boundaries. They do not certify a provider connection.
Canonical event schema ↗Ingress and replay documentation ↗