# Consistency and reliable delivery Business consistency starts with identifying what must be true together. Pharos protects an aggregate transition in one owner transaction. Work involving other aggregates proceeds through explicit pending states and durable hand-offs. ## Transactions and optimistic concurrency Commit the aggregate state, version, receipt, recorded outcome and selected outgoing event/realtime intents together. An expected-version check prevents a decision based on stale state from silently replacing a concurrent change. Aggregate children participate through their root. Project checks its acquired revision before applying an external observation. Provider I/O happens outside the aggregate transaction. Review the [application command](../../../services/beto/contexts/project/application/commands/observe_external_project.go) and [persistence boundary](../../../services/beto/contexts/project/adaptors/persistence/README.md). ## The dual-write problem and outbox Saving state and then publishing creates a failure window between the two actions. Publishing first exposes a fact that might later roll back. A transactional outbox records publication intent in the same transaction as the state change. A relay publishes committed intent and records delivery progress afterwards. ```mermaid sequenceDiagram participant Command participant OwnerDB as Owner database participant Relay participant Broker participant Consumer participant ConsumerDB as Consumer database Command->>OwnerDB: Commit root, receipt, outcome and intent Relay->>OwnerDB: Claim committed intent Relay->>Broker: Publish with stable identity Broker-->>Relay: Confirm acceptance Broker->>Consumer: Deliver Consumer->>ConsumerDB: Commit owned progress and receipt Consumer-->>Broker: ACK ``` The broker is outside each database transaction. A lost confirmation can cause redelivery. The receiving receipt commits with the work it protects. ## Identities and recovery | Concern | Evidence | | --- | --- | | Duplicate delivery | Consumer receipt for the message identity | | Duplicate business registration | Unique exact issuer/subject ownership in Party persistence | | Command replay | Same command identity and material input, with recorded outcome | | Workflow correlation | Identifier connecting related work across boundaries | | Stale update | Expected version or the owner's explicit ordering rule | A command identity cannot be reused with changed material input. A provider effect needs its own stable idempotency or recovery mechanism; a local receipt alone cannot determine whether a remote request succeeded. A lost commit response leaves an uncertain outcome. Retry with the same identity and input to recover it. Once a consumer commits acceptance and pending dispatch, that persisted work owns the next recovery step. Record pending states and the operator actions that resolve them. Exercise: stop the sequence after each arrow. Identify the durable evidence, possible duplicate and safe next action. Compare with [the delivery rules](../../../ARCHITECTURE.md). Next: [Event sourcing](event-sourcing.md). Adapted from the [architecture reference](attribution.md), with Pharos examples.