feat: opt-in attested execution receipts (devnet)#219
Merged
Conversation
Adds a ReceiptService that hashes a completed execution record and anchors only the SHA-256 on-chain via an SPL Memo, behind a settings toggle that is off by default. On-chain payload is the content hash plus a "DAEMON-RECEIPT v1" marker — never file contents, keys, prompts, or PII. - receiptBuilder: pure canonical JSON + deterministic content hash - receiptChain: memo emitter signed by a dedicated receipt key (never the trading vault); no signer provisioned = no-op - ReceiptService: enabled + devnet-only + signer gate; fire-and-forget so a receipt failure can never block or reverse the action that produced it - receipts ledger table (schema V58) for the "receipts emitted" surface - hooks after a successful ARIA write/sensitive tool and a landed autopilot buy - IPC to read/set the toggle and read the ledger Mainnet emission is deliberately gated off and left as a follow-up; this slice scopes real emission to devnet. Chain layer is injectable so tests never make a live call. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
anchorMemo trusted a caller-supplied cluster to pick the RPC endpoint, so a future or mistaken caller could have landed a receipt tx on mainnet if the orchestrator gate were bypassed. Hard-assert the cluster is devnet before loading a signer or opening a connection, and derive the endpoint from a devnet-locked constant rather than caller input. Off-devnet emission is now impossible at this layer regardless of shouldEmit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The receipts table only grew — every emission inserted and nothing pruned. Since the ledger just feeds a count and a recent list, keep the newest 1000 rows and prune older ones opportunistically on insert. Adds a real-SQLite test asserting the keep-newest bound. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
emitReceiptSafe did a synchronous SQLite settings SELECT inline before returning, so a receipt check could delay the ARIA tool call or autopilot tick that triggered it. Defer everything — settings read, gate, build, hash, anchor, ledger — to a setImmediate tick so the hook returns to the caller at once. Still fully exception-proof: nothing can flip the underlying action to error. Tests assert no settings/DB access happens on the synchronous path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Turns the proven registry-receipt spike into a real, off-by-default feature: DAEMON can emit a verifiable hash of an execution record on-chain, so an agent's track record is checkable instead of claimed.
Suite 1063 to 1142 (+79 across the slice, none skipped). Typecheck, build, lint:styles green. Independent review: one blocker (ungated emit boundary) + two findings, all fixed and re-verified. No live tx (devnet faucet dry); the memo path builds and signs against a live devnet blockhash.