MINARA
セキュリティ

資金移動の確認

お金を動かすすべてのツールは、プレビュー後に実行するゲートを通ります。その理由、対象範囲、および唯一の例外について説明します。

「100 USDC を ETH にスワップして」と Agent に伝えても、Agent はすぐには実行しません。まず取引内容を示す確認カードが表示されます。

Sell: 100 USDC (Ethereum)
Buy:  ~0.0286 ETH (estimated, 0.5% slippage)
Route: Uniswap V3
Gas estimate: ~$1.20

内容を確認し、意図した操作と合っていれば承認します。その時点で初めて、Agent がトランザクションをブロードキャストします。

なぜ Agent はすぐに実行しないのか? LLM は誤読することがあるからです。「100 USDC」が「1000 USDC」になることもあり、入力したアドレスが 1 文字ずれる場合もあり、チェーンが Ethereum から Base にいつの間にか変わることもあります。一度ブロードキャストしてしまうと、これらはいずれも取り消せません。そのため、すべての資金移動ツールは構造的に二段階です。プレビューが先で、実行は後です。

コントラクト

お金を動かすすべてのツールは ToolEntry に controlPolicy.confirm を宣言します。制御ポリシーゲートはツール呼び出しの拒否点でプレビューを実行し、同意を集め、その後に実行専用ハンドラーへ渡します。これはハーネスが強制するものであり、プロンプトでもハンドラー内部でもありません。

プロンプトによる案内ではなくハード制約にする理由は? LLM はプロンプトインジェクション、悪意あるスキルによる攪乱、または LLM が命令として解釈してしまう悪意あるツール結果によって、プロンプトレベルのルールを「忘れる」ことがあります。モデルは操作パラメータでツールを一度呼び出します。確認証拠がなければ、ゲートはプレビュー封筒を返し、トランザクションは生成されません。クライアントがカードを描画します。モデルはプレビューを見ず、二度目のツール呼び出しもありません。

ポリシーは tool-control-policy.ts にあります。解釈するフックは tier-gate.ts にあります。新しい資金移動ツールはすべて controlPolicy.confirm を宣言する必要があり、未対応の PR はレビューで差し戻されます。確認パスのない資金移動エントリは fail-closed になります。

対象ツール

ツールはツールレジストリで isFundMoving: true とマークされます。目的別にまとめた一覧は以下のとおりです。

トークン取引

  • swap_tokens:チェーンをまたぐ DEX スワップ
  • buy_token / sell_token:明示的な買い / 売りサイド
  • transfer_token:ウォレットからアドレスへの送金

永続先物

  • open_perps_position / close_perps_position
  • minara_perps_wallet_sweep:サブアカウント間の残高移動
  • minara_perps_wallet_transfer:永続先物残高の振り替え
  • minara_wallet_fund_perp:現物から永続先物アカウントへの資金供給(USDC 入金)

Autopilot(自律取引のオン / オフ)

  • minara_autopilot_enable / minara_autopilot_disable

Autopilot のトグルが資金移動扱いなのは、オンにすること自体がオペレーターによる自律取引の承認を意味するからです。有効化後、個々の Autopilot 取引はその承認を引き継ぎ、取引ごとに再確認を求めません。

ワークフロー

  • workflow_activate / workflow_deactivate

同じ考え方です。ワークフローをアクティベーションすることが、「このオートメーションを単独で実行することを承認する」という意思表示になります。

Strategy Studio(自分のストラテジー)

  • strategy-codegen スキルの deploy.sh

デプロイは一回限りの承認です。詳細は後述のストラテジーデプロイは一回限りの承認を参照してください。

他のクリエーターのストラテジーをライブで実行する

  • minara_top_strategies_apply_start:Top Strategies のストラテジーを実行

これらはユーザーの資金を使って自律取引を開始または停止するものであり、作者がデプロイ時に承認する仕組みがないため、Autopilot と同じ確認ゲートを通ります(apply_start / sub_startMANUAL_ONLYsub_stopALWAYS_CONFIRM)。

取引所への直接注文

  • hyperliquid_* のすべての発注 / キャンセル / 出金エンドポイント

新しい資金移動ツールを追加する場合は isFundMoving: true をマークし、controlPolicy.confirm を宣言してください。対応していない PR はコードレビューでブロックされます。

実際のフロー

Agent の呼び出しから承認までの流れです。

LLM: swap_tokens({
  sell_token: "USDC",
  sell_amount: 100,
  buy_token: "ETH",
  chain: "ethereum"
})

→ ゲート: 確認証拠なし
→ 宣言された preview(シミュレーション)を実行し、minara-confirm 封筒でブロック
→ クライアントがプレビューカードを描画。モデルは見ない

カードで承認する

→ 同じ呼び出しが実行専用ハンドラーへ進む
→ ハンドラーが署名してブロードキャスト
→ {tx_hash: "0x...", executed: true} を返す

呼び出し元が渡す confirm: true は、対話的な同意証拠として今も有効です。チェックは寛容です(true"true"1"yes""on")。一部のツール呼び出しプロトコルが真偽値を文字列化するためです。UI パスはモデルがそのフラグを渡すことに依存しません。

ストラテジーデプロイは一回限りの承認

ストラテジーデプロイは動作が異なります。strategy-codegen スキルの deploy.sh は、デプロイ時に一度だけ二段階確認を実行します。--confirm なしで実行するとデプロイ内容のプレビュー(シンボル、足の間隔、レバレッジ、サブアカウント、ドローダウン上限)だけを表示します。それを確認して一回だけ判断し、同じコマンドに --confirm を付けて再実行します。

その後、ストラテジーのライフサイクルスクリプト(start.shstop.shreconfig.sh)も、それぞれ同じ「プレビュー → --confirm」の二段階を実行します。stop はデフォルトで未決済ポジションを成行でクローズします。これらはすでに承認済みのストラテジーに対するスケジューリング操作であり、新たな資金移動ではありません。

他のクリエーターのストラテジーを実行する場合は異なります。作者による事前承認の仕組みがないため、Top Strategies の minara_top_strategies_apply_start は Autopilot の有効化と同様に確認ゲートを通ります。

なぜこの例外があるのか? アルゴリズムによる取引ごとに人間の確認が必要であれば、ストラテジーは単なる手動取引スクリプトと変わりません。Strategy Studio の目的は、事前に設定した制約の範囲内で権限を委任することです。デプロイがその権限を承認する瞬間であり、以後のストラテジーはドローダウン上限、資産配分制限、デプロイ設定に組み込まれたシンボルのアローリストによって制御されます。取引ごとのプロンプトではありません。

この例外は Strategy Studio にのみ適用されます。他のツールでこのパターンを模倣しようとしないでください。その他のツール群は統一確認ゲートを使います。

MINARA_SKIP_FUND_CONFIRM(オペレーターレベルのバイパス)

非インタラクティブなコンテキスト向けに、一つのエスケープハッチがあります。環境変数 MINARA_SKIP_FUND_CONFIRM=1(または設定 safety.skipFundConfirm)を入れると、確認ゲートはその呼び出しをすでに証拠付きとして扱います。使用が適切な場合と、決して使ってはいけない場合を以下に示します。

合理的な使用例(正当なケースはわずかです):

  • バックテスト。 呼び出し元は Python ハーネスであり、プレビューを読む人間はいません。また、実行は過去のデータに対してサンドボックス化されています。
  • ワークフローエンジンの実行。 ワークフローはアクティベーション時にすでに承認されています。実行ループは承認済みワークフローをディスパッチしており、各ステップをユーザーに再確認させるものではありません。
  • CI スモークテスト。 資金移動パスを通してワイヤー呼び出しを検証することが目的です。

使ってはいけない場合:

  • インタラクティブな REPL セッション。 これはあなたを守る最後の防御ラインをバイパスします。
  • 「毎回確認するのが面倒」という理由での本番環境での使用。 セーフティをオフにしているだけです。
  • シェルの rc ファイル。 .zshrcexport MINARA_SKIP_FUND_CONFIRM=1 を書いて忘れないでください。次に Agent を起動したとき、ガードなしで動作します。

環境変数の完全なリファレンスは 環境変数 → MINARA_SKIP_FUND_CONFIRM にあります。

レイヤー 3 とレイヤー 4(それぞれが何を検出するか)

最もよくある疑問は、ゲートがレイヤー 3(このページ)なのかレイヤー 4(スクリプトリスクゲート)なのか、という点です。クイックリファレンスは以下のとおりです。

Agent へのリクエスト検出する仕組み
「100 USDC を ETH にスワップして」(直接の取引リクエスト)レイヤー 3:制御ポリシーゲートがプレビューし、確認する
subprocess.run(["minara","swap",…]) を含む Python スクリプトの実行レイヤー 4:スクリプトリスクゲートが資金移動 CLI を検出し、YELLOW を表示
terminal から cast send 0x… 1ether を実行レイヤー 4:ゲートがシェルコマンドを検査し、YELLOW を表示
ファイルを編集して minara swap が含まれる内容にするレイヤー 4:ゲートが適用後の内容をスキャンし、YELLOW を表示
codegen スキルの deploy.sh でストラテジーをデプロイスクリプトレベルの二段階確認。--confirm なしはプレビューのみ、付けると実行。バックエンドのリスクレイヤーが後ろ盾

簡単にまとめると、レイヤー 3 は Agent からの直接的な資金移動ツール呼び出しを検出し、レイヤー 4 は Agent が実行するスクリプトやコマンド内の資金移動コードを検出します。 両者は同じ脅威の異なる部分をカバーし、並行して機能します。

オペレーター向けチェックリスト

  • ✅ プレビューが表示されたら、実際に内容を確認してください。送金先、チェーン、金額、スリッページが意図したものと一致しているか確認します。二段階フローは自分自身のミスを発見するためでもあります。
  • ✅ ストラテジーをデプロイする際は、デプロイ設定を慎重に確認してください。確認を求められるのはその一回だけです。
  • ✅ ワークフローをアクティベーションする際は、「はい」をクリックする前にワークフロー定義を最初から最後まで読んでください。以後の実行では再確認を求めません。
  • ❌ インタラクティブな REPL セッションで MINARA_SKIP_FUND_CONFIRM=1 を設定しないでください。.zshrc.envrc にも記述しないでください。
  • ❌ 読んでいないプレビューを承認しないでください。確認はあなた自身の判断であり、Agent の代行ではありません。

目次