Add deadline-aware x402 settlement for upto sessions#125
Closed
adambalogh wants to merge 1 commit into
Closed
Conversation
A shared-wallet run of many sequential requests rode a single upto session whose Permit2 deadline was signed on the first request with the default 300s lifetime. The session only settled after going idle, by which point the permit had expired and settlement could never land — and the facilitator's 202 (job enqueued) was treated as settled, so the session was deleted before the on-chain result was known. Whole runs settled to nothing. New tee_gateway/x402_settlement.py (monkey-patches og-x402's Flask middleware, same pattern __main__ already uses, so the pinned dependency and uv.lock are untouched): - DeadlineAwareSessionStore tracks each session's permit deadline, hides it from the serving paths SERVE_MARGIN_SECONDS before expiry (client signs a fresh permit) and saturates the spend cap instead of serving unbillable requests once the cap is hit. - Reaper settles sessions approaching their deadline (not just idle/exhausted), polls GET /settle/<jobId> to a terminal state before marking a session settled, re-drives settlement on a failed job while the permit still allows it, and abandons loudly (CRITICAL) only when the deadline has truly passed. __main__/definitions: set an explicit X402_SESSION_MAX_TIMEOUT_SECONDS (3600) on all upto routes — the old implicit 300s was shorter than the serve margin — and wire in the new store + settlement install. Adds test_x402_settlement.py (13 tests). Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01CbDr9d3YxeSjdwJQUzjuEC
adambalogh
marked this pull request as ready for review
July 9, 2026 00:00
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.
Summary
Implements deadline-aware settlement for x402 upto sessions to fix three silent failure modes in og-x402's stock middleware that cause revenue loss:
Key Changes
New module
x402_settlement.py: Provides deadline-aware session management and settlement lifecycleDeadlineAwareSessionStore: Extends og-x402'sSessionStoreto:install_deadline_aware_settlement(): Monkey-patchesPaymentMiddlewareto:Updated
__main__.py:SessionStorewithDeadlineAwareSessionStoreinstall_deadline_aware_settlement()during middleware initializationX402_SESSION_MAX_TIMEOUT_SECONDSto session creationUpdated
definitions.py:X402_SESSION_MAX_TIMEOUT_SECONDSconstant (permit lifetime in seconds)SERVE_MARGIN_SECONDSandSETTLE_MARGIN_SECONDSNew test module
test_x402_settlement.py:Implementation Details
SERVE_MARGIN_SECONDS=420s,SETTLE_MARGIN_SECONDS=120s) to provide buffer for reaper cadence, facilitator queue latency, and on-chain confirmationJOB_POLL_BUDGET_SECONDS=30s) to avoid blocking the reaper; resumes next cycle if budget exhaustedDEADLINE_HOPELESS_SECONDS=30s) to surface revenue loss__main__.pyto avoid forking og-x402 (pinned dependency)SessionStore._lockhttps://claude.ai/code/session_01CbDr9d3YxeSjdwJQUzjuEC