Why hash-chaining
Each step’s entry hash is SHA-256 over the previous step’s hash plus a canonical (key-sorted) JSON serialization of the step’s contents — sequence, status, provider, action type, idempotency key, request hash, external id, detail, and timestamp. Editing, deleting, or reordering any row changes a hash and breaks every link after it. Row-level security already forbids updates and deletes; the chain goes further — even a privileged operator with raw SQL access cannot rewrite history silently.