Repository navigation
Record unreconciled authorization outcomes and audit events atomically - #895
Open
rudycelekli wants to merge 1 commit into
Open
rudycelekli wants to merge 1 commit into
rudycelekli wants to merge 1 commit into
Conversation
rudycelekli
requested review from
MikeRyanDev,
davidmckayv,
dustywusty,
guidovizoso,
mxmzb,
samjulien and
tylerslaton
as code owners
October 30, 2026 06:43
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
When a vendor authorization answer cannot be reconciled, the attempt currently settles as
unreconciledwithout a persisted audit event. Operators can inspect the attempt row, but the authorization audit trail cannot explain that ending.Record
mcp.authorization_unreconciledatomically with the winning terminal transition. The event correlates actor, server/app, action, holder and attempt creation time; it excludes the live authorization ID, consent URL and vendor account identifier. An audit insert failure rolls back the outcome and completion timestamp. A late or concurrent losing terminal callback emits no event.This addresses the shared unreconciled transition prioritized in #876. It is a partial implementation: the other lifecycle audit gaps remain open. Successful completion and cancellation events keep their current behavior.
Where it runs
OpenBot is deployed as several server processes behind a load balancer, serving a whole company.
Consecutive requests from the same person reach different processes, and the process that answered a
WebSocket upgrade is rarely the one that answers the next call on that conversation.
State that outlives a single request therefore has to be shared, or the change works on one machine
and stops working the moment there are two, without saying so. That failure is worse than not
shipping the feature: it passes review, passes CI, passes a local demo, and only surfaces as a Bot
that forgets, a question nobody can answer, or a boundary that never fires.
Answer these even when the answer is "none":
completed_at IS NULLconditional UPDATE retain first-terminal-wins under Postgres row locking. The winning update and audit insert share one transaction; this is not a check-then-write.Postgres is already there and is the default answer to all of the above: a table, a unique index, a
conditional update,
LISTEN/NOTIFYfor fan-out.Boundary and audit
Changelog
CHANGELOG.mdunderUnreleaseddescribes the audit event and rollback behavior.Proof
Native before/after proof uses Bun 1.4.3 and disposable PostgreSQL 17 with the real plugin store and persisted audit table:
bun run test:cifinished 11,017 passed, 214 skipped, and 0 failed across 886 files. Skipped live-vendor/deployment tests do not establish live acceptance.bun run lint,typecheck,typecheck:tests, desktop/chart version checks, Drizzle consistency/drift checks, Linux startup control andbun run buildpassed. Finalbun run format:checkpassed. Linux test/build evidence; final formatting check. The full-run tree differs only in formatter layout; both edited TypeScript files emit identical normalized JavaScript. Final source tree:8cc20c84bd4bedf25eddd03ad9cceb25750bcaff. Platform/container matrices and upstream PR-head CI remain separate checks.The change has no new visual surface. Native DB tests prove this terminal transition; they do not claim live vendor acceptance or resolution of every item in #876.
AI assistance: implementation, test drafting and independent patch review used AI coding assistants. The persisted behavior assertions and CI results above are executable evidence; this disclosure does not claim human-only authorship or a human review that has not occurred.