feat: vigil-revoke skill — closes detection→revoke loop via Bankr#354
Conversation
VIGIL PR #323 explicitly split the Approval Revoker into a future skill ('Bankr-gated, state-changing — separate PR.'). wallet-risk-weekly (PR #340) surfaces HIGH-bucket approvals weekly but had no autonomous remedy path. This skill closes that loop. workflow_dispatch only — var is a wallet:spender:token triplet (matches tuples vigil_scan_approvals / approval-audit return). Strict allowlist on the input. Bankr-bound wallet check before any state-changing call. Pre-revoke allowance read short-circuits to NOOP when already zero — no gas spent on a redundant submission. Post-revoke receipt poll plus a final allowance read so the notification only claims success on a chain-confirmed revoke. 7-state exit taxonomy. No auto-retry, no bulk revoke per run, no trusted-spender auto-skip — the operator triplet is the decision boundary. Registered disabled in aeon.yml at the end of the Hound onchain investigation section. skills.json regenerated (193 → 194), category onchain-security. capabilities: external_api, writes_external_host, onchain_writes, sends_notifications.
Review findings — holding merge until these are fixedDeep review against the agreed VIGIL enable-time posture. The config layer is genuinely compliant: dormant ( Blockers1. Nothing verifies what Bankr actually signed 2. Validate-after-interpolate on Nits for the same pass
Follow-up worth filing as an issue (pre-existing, not this PR)The runner injects |
|
Fresh-eyes pass, post-existing-review. The current comment thread already lands the two highest-leverage items (calldata verification on 1. Post-allowance read has no failure path — asymmetric with the pre-check
The pre-allowance read at Suggest symmetric handling: if the post-read is empty / non-hex after the same retry+WebFetch ladder, emit a third verdict ( 2. Poll loop falls through silently on unknown Bankr statuses — composes with no idempotency on
|
distribute-tokens bans the Agent API for transfers; document that Bankr exposes no structured raw-contract-call path for an arbitrary approve, so /agent/prompt is the only route here, and the blast radius is bounded to zeroing an allowance (never a fund move). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Targeted edit of the vigil-revoke entry only — a full regenerate on this branch would reflow every entry's sha and conflict with main. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
New
skills/vigil-revoke/SKILL.md—workflow_dispatch-only skill that revokes a single live ERC-20 approval on Base via Bankr.varis awallet:spender:tokentriplet (the tuple shapevigil_scan_approvalsandapproval-auditalready emit). Confirms the approval is still live viaeth_callonallowance(owner,spender)before spending any gas, submitsapprove(spender, 0)via Bankr's/agent/promptpath, polls/agent/job/{id}for up to 90s, then re-readsallowanceto verify the on-chain state. Notification only claims SUCCESS on receipt status0x1+ post-allowance0x000…000.Why
VIGIL's five-round review (PR #323) explicitly split the Approval Revoker into a future skill — "Bankr-gated, state-changing — separate PR."
wallet-risk-weekly(PR #340, 2026-06-04) now runs the weekly audit and surfaces HIGH-bucket approvals worth revoking. The detection → revoke loop has been half-open since: the agent identifies an UNLIMITED approval to a non-trusted spender but has no autonomous path to act. This skill closes the loop — the operator copies the triplet from the wallet-risk-weekly notification (or runsapproval-auditon-demand) and dispatches once.Five other HoundFlow onchain skills still have no scheduled consumer; this isn't an attempt to schedule any of them. It's the deliberate write-side companion to the read-only inventory: operator-initiated only, no cron.
Changes
skills/vigil-revoke/SKILL.md— new skill. Strict input allowlist on the triplet (^0x[hex40]:0x[hex40]:0x[hex40]$, case-insensitive then lower-normalised — mirrors VIGIL's round-4 input hardening). Bankr ownership pre-check (/wallet/me≟ triplet wallet) refuses cross-wallet submissions. Pre-revoke allowance read short-circuits to NOOP when already zero. Post-revoke: receipt poll + final allowance read so SUCCESS is chain-confirmed, not Bankr-reported. 7-state exit taxonomy (OK / NOOP / FAILED / BAD_VAR / WALLET_MISMATCH / ERROR / STATE_CORRUPT). State filememory/topics/vigil-revoke-log.jsonis append-only with a 500-entry cap.aeon.yml— register disabled at end of the Hound onchain investigation section.generate-skills-json— extend theonchain-securitycategory line to includevigil-revokealongsidevigilandwallet-risk-weekly.skills.json— entry inserted alphabetically betweenvigilandvuln-scanner. Total 193 → 194.Design decisions
workflow_dispatchis the retry.vigil-revoke-batchskill, deliberately out of scope here to keep blast radius bounded and the audit trail clean.wallet-risk-weekly's severity bucketing, not here. If the operator names a triplet, the skill revokes (or NOOPs on already-zero)./agent/prompt. The body only interpolates validated 40-hex addresses — never operator-typed text or fetched contract metadata.external_api,writes_external_host,onchain_writes,sends_notifications. Matches the locked taxonomy indocs/CAPABILITIES.md.Sandbox note
Bankr API calls require
X-API-Keyenv-var expansion in the curl header — sandbox-blocked env expansion would 403 the call. The skill detects that path and exits with a clear error rather than falling back to WebFetch (which would either leak the key into a URL or omit auth entirely). Base RPC calls (allowance check + receipt poll) use the public endpoint and fall back to WebFetch on curl failure perCLAUDE.mdpattern 1.Built autonomously by Aeon