Skip to content

ADR-0010: Writeback — model the intent, stub the dispatch

ADR-0010: Writeback — model the intent, stub the dispatch

Status

Accepted

Date

2026-06-24

Context

The first proof loop includes “create writeback intent to GIS/ERP/OSS,” and the pack models it with WritebackIntent, sagas, compensation, dead-letter, and Temporal. But bidirectional writeback to external systems you don’t control is the swamp that consumes integration teams — idempotency against foreign APIs, partial failures, compensation, reconciling external drift. For a 2–3 person team, a real production connector inside the proof would consume the whole budget and depend on external access we may not have.

The separable insight: the kernel part of writeback — the intent lifecycle, saga semantics, compensation, dead-letter, idempotency — is exactly what we should prove, and it is independent of any specific foreign connector.

Decision

Model the intent fully; stub the dispatch. integration.RequestGISWriteback creates a WritebackIntent with a full state machine (pending → dispatched → confirmed / failed → compensated), emits events, and runs the saga (idempotency keys, compensation, dead-letter) against a mock/sandbox target — or against the legacy SmartInventory itself (which ADR-0009 already makes “just a connector”).

Real customer GIS/ERP/OSS connectors are deferred post-proof.

Alternatives Considered

One real connector end-to-end

  • Rejected for the proof: highest fidelity, biggest time sink, depends on external system access.

Fire-and-forget (emit event to a queue, no saga)

  • Rejected: skips exactly the hard part (compensation, dead-letter, idempotency) that makes writeback worth modeling as a first-class intent.

Defer writeback entirely from the proof

  • Rejected: drops the “close the loop to systems of record” differentiator, which is core to the value story.

Consequences

  • The kernel’s writeback semantics are proven without paying the foreign-integration tax.
  • Targeting legacy SmartInventory as the stub makes the stub real-ish for free and exercises ADR-0009’s connector boundary.
  • Building real connectors later is additive: they implement the dispatch behind an interface the intent/saga already drives.
  • Depends on the saga/workflow engine choice (Temporal or equivalent), which is itself an implementation detail to confirm during the proof.