fix(security): second-LLM check is always optional - #832
Merged
Conversation
Deletes the Inv #12.5 hard-trigger flag `secondLlmRequired` on `UnsignedTx` and the `⚠ SECOND-LLM CHECK REQUIRED` line the verification renderer emitted for it. No op class makes the check a precondition of 'send'; docs restate Inv #12.5 as a recommendation. The check needs the user to physically paste into a second provider's session, so a rule that blocks 'send' until it happens blocks the user, not an attacker — a rogue agent self-attests the verdict either way (the `userDecision: "send"` self-attestation gap). The flag also never had a producer: no `prepare_*` path set it, so nothing on this server changes behavior. The load-bearing gate lives in the skill, filed at szhygulin/vaultpilot-security-skill#51. Co-Authored-By: Claude Opus 5 (1M context) <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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
The second-LLM cross-check is always optional. Inv #12.5 (issue #501 / #530) had carved out a set of op classes where it was a precondition of
send; that carve-out is gone.MCP side (this PR). Deletes
secondLlmRequiredonUnsignedTxand the⚠ SECOND-LLM CHECK REQUIREDlinerenderVerificationBlockemitted for it. Noprepare_*path ever set the flag, so no shipped behavior changes — the deletion removes the only mechanism by which one could.SECURITY.md/README.md/ROADMAP.mdrestate Inv #12.5 as a recommendation.Why optional. The check needs the user to physically paste into a second provider's session, so a rule that blocks
senduntil it happens blocks the user, not an attacker — a rogue agent self-attests the verdict either way (theuserDecision: "send"self-attestation gap). Users who run it still get the value: a coordinated lie across two provider sessions is harder than a single-agent compromise.Test.
test/second-llm-required-flag.test.ts(the flag's test) is replaced bytest/second-llm-always-optional.test.ts, which pins the policy instead: no renderer output attachesREQUIRED|MANDATORY|MUST|NOT YET RUNto aSECOND-LLMline, and the offer stays present and labeled optional on both sign modes. Verified red by re-adding a mandatory line torenderVerificationBlock(1 failed atsecond-llm-always-optional.test.ts:61), then restored.Out of scope — the load-bearing gate is skill-side.
SKILL.md§12.5 refuses to advance topreview_send/send_transactionuntil the user supplies a second-LLM verdict, and listsprepare_custom_callas a trigger. Filed at szhygulin/vaultpilot-security-skill#51. That issue also covers §12.5's claim of an MCP-sidesecondLlmRequired = trueauto-stamp, which was never implemented and after this PR names a field that no longer exists.test-results/SUMMARY.mdstill records "mandatory second-LLM, not opt-in" as a 2026-04-28 smoke-test recommendation; left as written — it is a dated record, not live policy.Gate:
tsc --noEmitclean;vitest run test/second-llm-always-optional.test.ts test/verification.test.ts test/send-hash-pin.test.ts→ 101 passed.Reverses the MCP half of #501 (shipped in #530). #501 is already closed; this does not reopen it.
Based on
agenthill/main@ 50f82e5; theszhygulinfork PR opened first was closed (stale downstream, 56 behind).🤖 Generated with Claude Code