コンテンツにスキップ

承認フロー

requireApprovalAbove を超えたとき、onBudgetExceeded: approve で予算を超えたとき、新しい受取先への高額な初回支払い、価格の急変のいずれかで、人間の確認が必要になります。

保留モード(既定):誰かが判断するか approvals.timeout を過ぎる(その場合は拒否)まで、エージェントのリクエストを開いたまま待ちます。CLI やスクリプトに向いています。ただし通信上の保留は最長 holdMax(既定 4 分。Node の fetch が諦める 5 分より短く)までで、それを過ぎると再送モードと同じ応答を返し、承認依頼は開いたまま残ります。保留中にエージェントが切断した場合は、あとで人間が承認しても支払いは行いません。その承認は再送で使えます。

再送モード(hold: false):spendctl はすぐに 402 を返し、本文に "error": "spendctl_approval_required" と approval ID を入れます。承認後、エージェントは X-Spendctl-Approval: <id> を付けて再送します。1つの承認で払えるのは1回の再送だけです。

台帳では、こうして差し戻されたリクエストは held になります。承認 ID を付けた再送が行われると superseded(再送は別の行で、settled などになります)、承認が否認されると denied、承認が期限切れになると expired に変わります。通信上で待っている最中のリクエストは pending_approval です。

ターミナルウィンドウ
spendctl pending
spendctl approve apr_… # --latest / --all も使える
spendctl deny apr_… --note "キャッシュの結果を使って"
  • ダッシュボード:spendctl dashboard --open
  • Webhook:format: json | slack | discord。理由、CLI コマンド、確認リンクが入ります。secretEnv を設定すると本文に署名します(X-Spendctl-Signature: sha256=…)。
  • 確認リンク:管理トークンで HMAC 束縛されています。開く(GET)だけでは内容を表示するだけで、承認・拒否のボタンは POST で動きます(チャットアプリはリンクを先読みするため)。

エージェントは承認できません。どの判断にも .spendctl/admin.token(パーミッション 0600)の管理トークンが必要です。