Transaction boundaries
The decision and its audit entry commit together. Recourse does not.
The decision row, its reasons, and the append-only ledger entry all commit inside a single database transaction, so an auditable decision without its ledger entry can never exist. But the path-to-yes search runs outside that transaction — a slow or failed recourse computation must never roll back a decision that already legally stands. The ledger append serialises per tenant behind a row lock, so concurrent decisions can't reorder the hash chain.
orchestrator/service.py:94