Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e747-8f27-7242-8df8-8bc44f88c929
5.2 KiB
Transaction-linked native operation outcomes
HUB-WP-0012 source candidate, 2026-09-28. Live sender admission, database rollout and owner acceptance remain open.
Coverage and transaction boundary
The durable native registry, message, progress-event and interaction-event writes
already append to runtime_audit_ledger in their business transaction. Enforced
requests now bind those ledger rows to the verified issuer/subject, actor/target
tenant, principal type, policy decision/version/caller, request digest and
server-generated authorization correlation ID. This context comes from the
access boundary, never command payloads or caller-supplied correlation headers.
It is scoped to handler execution and reset in finally.
The same transaction inserts one immutable hub.operation.committed envelope
into runtime_outcome_outbox, keyed by its ledger ID. Failure to insert either
record rolls back the business mutation. A rolled-back transaction has no
committed outcome; the earlier authorization receipt remains an authorization
attempt. Registry duplicate acknowledgements have registry.duplicate operation
records and do not pretend a new registration was created.
The envelope contains business object references and a payload hash, not message bodies, event payloads, credentials or tokens. Business correlation IDs are retained separately from verified authorization correlation IDs. That verified ID and decision ID join the outcome to the pre-execution signed decision already held by Audit Core. The outcome does not duplicate the signed envelope.
This slice covers the native durable mutation ledger. It does not claim outcome coverage for compatibility/embedded-host mutations, background projection refresh, external services, or in-memory development stores. Non-enforced maintenance writes retain their existing local ledger behavior without fabricating an actor or emitting an attributed remote outcome.
Delivery, recovery and readiness
When a durable store and outcome-capable audit sink are composed, the runtime
starts a dispatcher and cancels it before closing clients or stores. It selects
up to 25 eligible rows per batch, one database transaction per row, and waits
one second between batches. PostgreSQL uses FOR UPDATE SKIP LOCKED so workers
can select different rows. Each receiver call is bounded to three seconds.
AuditCoreSink.append_outcome reuses the operational-custody probe, rotating
sender credential and exact accepted/duplicate receipt checks. All retries use
the same event ID, occurrence timestamp and body; the ID is also the idempotency
key. Only an accepted receipt marks the row delivered. Failed attempts retain
the row with persisted exponential retry delay (one second up to sixty seconds).
Exceptions are not stored as diagnostic text. Cancellation or a crash before the
local delivery acknowledgement leaves the row eligible for replay. Delivery is
at least once; receiver deduplication resolves a lost receipt or duplicate send.
It does not change business mutation idempotency or make a client retry safe.
The authorization audit still requires synchronous remote custody before the handler. Queuing a committed outcome does not weaken that check. An outcome outage after authorization cannot undo an already committed operation.
Protected readiness adds outcome_delivery: missing delivery composition is
unavailable, a pending row older than sixty seconds is stale, and a young or
empty backlog is ok. Database readiness checks that the new table is accessible.
Pending rows are never silently discarded. Delivered rows remain for inspection;
retention/pruning needs a separately admitted operational policy.
Schema and rollout
Migration 0006_outcome_outbox adds the table, ledger foreign key and pending-row
index. Apply it through the existing owner migration lane before deploying this
candidate and admit runtime SELECT/INSERT/UPDATE privileges. Automatic downgrade
requires an online check and refuses a nonempty pending queue. Drain pending
outcomes and preserve required custody records before schema rollback.
The Audit Core sender must admit hub.operation.committed for source hub-core
and tenant tenant:platform, in addition to existing authorization record classes.
This document neither issues that grant nor claims production delivery.
Local evidence
Tests use SQLite-backed durable stores to prove atomic rollback, handler rejection, all native mutation families, actor/decision attribution, concurrent request isolation, persisted retry delay, reopen/replay, cancellation, stale-backlog readiness, dispatcher drain/shutdown and migration shape/downgrade refusal. The real Audit Core receiver/storage source accepts the eight-field envelope and returns a duplicate receipt on replay. Its operational-readiness classification is explicitly a test fixture; this is not live custody evidence.
PostgreSQL multiworker lock scheduling, production grants, retention and deployed failure-detection/receiver acceptance still require integration receipts.
Validation on 2026-09-28: 366 tests pass with the opt-in owner-source suite enabled; inventory drift, package build and isolated installed-wheel checks pass. The wheel includes the current migration, authority-context and durable-store code.