資金移動の確認
お金を動かすすべてのツールは、プレビュー後に実行するゲートを通ります。その理由、対象範囲、および唯一の例外について説明します。
「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_positionminara_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_start は MANUAL_ONLY、sub_stop は ALWAYS_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.sh、stop.sh、reconfig.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 ファイル。
.zshrcにexport 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 の代行ではありません。