Skip to content

feat(security): UnsignedTx.secondLlmRequired scaffold for Inv #12.5 (#501) - #530

Merged
szhygulin merged 1 commit into
mainfrom
feat/501-second-llm-flag
Apr 28, 2026
Merged

feat(security): UnsignedTx.secondLlmRequired scaffold for Inv #12.5 (#501)#530
szhygulin merged 1 commit into
mainfrom
feat/501-second-llm-flag

Conversation

@szhygulin

Copy link
Copy Markdown
Collaborator

Closes #501.

Summary

Inv #12.5 (skill-side) marks a curated list of op classes where the second-LLM check is a precondition of `confirmed: true`, not opt-in. The skill rule lives in `vaultpilot-skill` v9+; this PR is the MCP-side scaffold so future hard-trigger op producers can flip a flag at build time and have the existing verification block surface a mandatory ⚠ line.

What ships

  • New `secondLlmRequired?: boolean` on `UnsignedTx`. Default absent / false.
  • `renderVerificationBlock` emits a ⚠ line below the hash when the flag is true: `⚠ SECOND-LLM CHECK REQUIRED — call get_verification_artifact(handle) and relay the pasteableBlock to the user BEFORE 'send' (Inv Auto-discover Morpho Blue positions via event-log scan #12.5 hard-trigger op).`
  • +3 tests pinning the behavior (omitted when absent/false, emitted when true, composes cleanly with recipient + `tokenClass` warnings).

What does NOT ship

No producer wires the flag yet — every hard-trigger op class is itself deferred (#481 EIP-7702, #453 Permit2 batch, #451 opaque-facet bridges, Safe enableModule / N-candidate selection not yet built). Pure dormant scaffold.

Trust note (documented inline)

The flag is a workflow signal, not a cryptographic primitive. Closing the agent-side honesty gap (rogue agent ignores or self-attests the check) requires infrastructure that doesn't exist today:

Approach Feasibility Why not today
Provider-signed responses (Anthropic / OpenAI sign verdicts with provider key) Easiest, just needs vendor buy-in No API today exposes signed responses
TEE attestation (run second LLM in SGX / SEV / PCC) Works Heavy infra; defeats vendor-diversity intent
zkML proof of NN inference Works in research Hours-to-days proving on small models
Challenge-response (MCP asks, user pastes answer back) Naive — doesn't help MCP knows the answer; rogue agent answers correctly without involving a second LLM
Out-of-band human ack (SMS / hardware confirm button) Works for "human approved" Doesn't prove an LLM verified

Coordinated release

  • Skill v9 (in `vaultpilot-skill` repo) ships the Inv Auto-discover Morpho Blue positions via event-log scan #12.5 invariant text + lifts §16 unconditional 7702 refusal.
  • MCP-side `EXPECTED_SKILL_SHA256` bump happens in that skill-coordination PR, not this one — this PR is just the dormant scaffold.

Test plan

  • +3 tests, full suite 2447/2447 passing
  • Verify CI green
  • Smoke (when first hard-trigger op producer ships): `prepare_` → receipt verification block contains the `⚠ SECOND-LLM CHECK REQUIRED` line below the hash.

🤖 Generated with Claude Code

…501)

Inv #12.5 (skill-side, issue #501) marks a curated list of op classes
where the second-LLM check is a precondition of `confirmed: true`,
not opt-in. The skill-side rule lives in vaultpilot-skill v9+; this
PR is the MCP-side scaffold so future hard-trigger op producers can
flip a flag at build time and have the existing verification block
surface a mandatory ⚠ line.

What ships:

- New `secondLlmRequired?: boolean` on `UnsignedTx`. Default absent
  / false. Documentation comment lists today's hard-trigger op
  classes (all currently deferred or not built):
    - EIP-7702 setCode (#481)
    - Permit2 batch grants (#453)
    - Opaque-facet bridges (#451)
    - Approval-management N-candidate selection (Inv #13)
    - Safe enableModule / setGuard / threshold changes
- `renderVerificationBlock` reads the flag and emits a single
  ⚠ line below the hash:
    ⚠ SECOND-LLM CHECK REQUIRED — call get_verification_artifact(handle)
    and relay the pasteableBlock to the user BEFORE 'send' (Inv #12.5
    hard-trigger op).
- 3 tests pinning the behavior: omitted when absent/false, emitted
  when true, composes cleanly with recipient + tokenClass warnings.

What does NOT ship:

- No producer wires the flag yet (every hard-trigger op class is
  itself deferred). The flag is dormant scaffold.
- No enforcement layer below the rendered ⚠. The MCP can't tell
  whether the agent actually ran the second-LLM check — same self-
  attestation gap as `userDecision: "send"`.

Trust note (in the field doc):
The flag is a workflow signal, not a cryptographic primitive.
Closing the agent-side honesty gap requires infrastructure that
doesn't exist today (provider-signed LLM responses, TEE attestation,
or zkML proofs of NN inference). Discussed in the PR thread for
this issue.

Coordinated with skill v9 release (lifts §16 unconditional 7702
refusal + adds Inv #12.5 hard-trigger language); MCP-side
`EXPECTED_SKILL_SHA256` bump happens in the skill-coordination PR,
not this one.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@szhygulin
szhygulin force-pushed the feat/501-second-llm-flag branch from b64e7e1 to 66330df Compare April 28, 2026 15:15
@szhygulin
szhygulin merged commit fa5243b into main Apr 28, 2026
4 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 28, 2026
@szhygulin
szhygulin deleted the feat/501-second-llm-flag branch May 19, 2026 04:26
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[security] Add Invariant #12.5 — hard-trigger ops list requiring mandatory second-LLM

1 participant