# Workflow orchestration — boundaries

## Orchestration scope

Orchestration **may**:

- Invoke **domain application services** in a defined order.
- Maintain **workflow control data**: current step, attempt count, terminal status (`completed`, `failed`, `compensating`), correlation id, saga idempotency key.
- **Translate** domain failures into workflow-level decisions (retry, compensate, escalate).

Orchestration **must not**:

- **Own** procurement, inventory, or payroll **ledger truth** (no duplicate receipt or stock rows “for the workflow”).
- **Bypass** domain validation (e.g. skip receipt integrity checks).
- **Hide** partial completion without a persisted workflow state (no “only in memory” multi-step business processes).

---

## Sync boundaries

Use **synchronous** orchestration when:

- All steps hit the **same** database and the business defines **one** user-visible outcome (“receive and stock in one click”).
- **Strong atomicity** is required across domains in that deployment (see `docs/architecture/cross-domain-transactions.md`).

The orchestrator runs **inside or wraps** a single transaction boundary **owned** by the outermost documented service.

---

## Async boundaries

Use **async** orchestration when:

- External IO, partner APIs, or **separate** runtime processes are involved.
- **Eventual consistency** is explicitly accepted and **reconciliation** is owned (see `docs/architecture/cross-domain-reconciliation.md`).

Async steps **start after commit** of durable workflow state and domain facts that must precede them (`docs/architecture/cross-domain-events.md`).

---

## Orchestration stop points

A **stop point** is a state where:

- No further automatic step runs without **new** input or **policy** (e.g. `awaiting_approval`, `awaiting_carrier`).
- Retries **do not** re-enter completed steps unless idempotency guarantees no duplicate side effects.

Document stop points per workflow in the product spec; the orchestrator **must** persist them.

---

## What orchestration may NOT own (summary)

| Forbidden ownership | Why |
|---------------------|-----|
| Canonical stock quantity | Inventory ledger + projection rebuild own this. |
| Receipt line participation / quarantine | Procurement integrity layer owns this. |
| Payroll computed totals | Payroll engine owns snapshots. |

---

## Critical stance

**Orchestration boundaries beat implicit coupling.** If a step needs a field, the **domain** exposes it via a query or result DTO—do not read foreign tables from orchestrator repositories.
