Skip to content

fix: safely resume failed claims and preserve recovery evidence - #8

Merged
iamalwaysuncomfortable merged 1 commit into
masterfrom
fix/claim-recovery
Oct 15, 2026
Merged

iamalwaysuncomfortable merged 1 commit into
masterfrom
fix/claim-recovery

Conversation

@esren0x

@esren0x esren0x commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

A claim that failed during local preparation was previously marked uncertain, even when nothing had been submitted. Reconciliation could not clear that state without finding a successful claim, so an ordinary preparation failure could block subsequent wallet operations indefinitely. This PR distinguishes proven pre-submission failures and confirmed rejections from unknown outcomes, allowing an explicit, safe resume of the original claim operation.

What changed and why

  • Track the claim submission boundary. Persist preparing before calling the SDK and submitting before entering its proving/submission adapter. If checkpoint persistence fails, the adapter is not invoked. This provides evidence for safe recovery instead of inferring failure from an error message or missing transaction ID.
  • Resume the original claim operation. Preparation failures return pending with lastFailure.code: not_submitted; confirmed claim rejections return pending with transaction_rejected. An explicit resume_operation rechecks current permissions and claimability, retains the operation ID, and skips already completed batch items.
  • Preserve safe transaction evidence. Keep allowlisted transaction IDs from SDK confirmation timeouts, fee transaction IDs from confirmed rejections, and the claim ID returned by the adapter before later SDK bookkeeping. Arbitrary SDK error messages, causes, credentials, and claim material are not exposed.
  • Resolve confirmed swap rejections without repeating deposits. Reconciliation checks known IDs through the SDK's public confirmed-transaction API. A confirmed swap rejection is terminal failure; recovery never resubmits the swap.
  • Keep genuinely unknown outcomes blocked. A timeout ID alone is not proof of acceptance. Not-found responses, RPC failures, and accepted transactions without sufficient claim-history evidence do not authorize another claim. Older ambiguous checkpoints remain conservative.
  • Document and test the recovery contract. Add regression coverage and a reusable installed-package smoke test that exercises the production CLI, runtime, and encrypted store over MCP across process restarts, with simulated SDK outcomes.

Validation

  • Pinned 0.12.0 dependencies: 93 MCP tests passed, including pre-submission failures, failed checkpoint writes, lost responses, confirmed rejections, partial batches, restart recovery, legacy ambiguity, permission revocation, and duplicate-submission prevention.
  • 25 root context tests passed; type checking, build, and git diff --check passed.
  • An independently installed tarball passed the standard smoke test: SDK key import, encrypted persistence, profile reuse, all 20 MCP tools, readiness, bridge-route discovery, and two process restarts.
  • The new installed recovery smoke passed preparation-failure, partial-batch, and timeout-to-confirmed-rejection scenarios across three process restarts, including blocked duplicate writes and explicit resume.
  • Rechecked compatibility in an isolated copy using published 0.12.1 Provable/Veil packages: all 93 MCP tests, type checking, build, and both installed-package smoke tests passed. The relevant claim/submission/confirmation source paths were also checked against Veil a15b5ab and Provable SDK 85606f89.

All transaction outcomes used for these checks were simulated. No live trades, funding, or production-provider authentication were performed. The recovery smoke requires Node 22.15+ for module hooks.

Scope and remaining limits

This PR implements recovery correctness only. Dependency pins remain at 0.12.0. Cumulative trading budgets, expanded market-data tools, spendable-record settlement receipts, operator diagnostics, agent evaluations, and executable CI integration remain separate workstreams.

A crash after possible broadcast but before the SDK returns a transaction ID can still leave an unresolved operation. Without conclusive evidence, it remains blocked rather than being retried. Confirmed rejections may have consumed fees; retained fee IDs support inspection but do not imply reimbursement.

@iamalwaysuncomfortable
iamalwaysuncomfortable merged commit a80dd2f into master Oct 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants