承認フロー
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 です。
判断のしかた
Section titled “判断のしかた”spendctl pendingspendctl 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)の管理トークンが必要です。