/moai goal
完了条件を宣言すると、セッションがその条件を満たすまで自ら働く 条件宣言型の自律ループ コマンドです。/moai goal "<条件>" で完了条件を arm すると、毎ターン終了時に stop-goal Stop フックが条件充足の可否を評価し、満たされるまで次のターンを自動的に開始します。
情報一行要約:/moai goalは「終わりの状態を宣言する汎用ループ」です。/moai loopが「診断ツールが見つけた問題を全部なくすまで」という条件があらかじめ決まっているプリセットだとすれば、/moai goalは完了条件を 直接宣言する 汎用エンジンです。
情報プログラマティックコマンド: ネイティブの Claude Code/goalはユーザーだけが入力できる (HUMAN-ONLY) TUI コマンドです。/moai goalは同じ意味を パイプラインからプログラマティックに 実装した MoAI 所有コマンドで、moaiスキルルーティングとmoai goalCLI を通じて進入します。
エージェントに「この条件が満たされるまで任せて働き続けて」と指示したいときに使います。条件は 2 種類を混ぜて使えます。
- 機械的条件 (mechanical): シェルコマンドで検証される条件。例:
go test ./... exits 0。コマンドを実行して終了コードを観察します。 - モデル評価条件 (model-evaluated): トランスクリプトに対する判断で検証される条件。例:
すべての AC 行が PASS として記録される。セッションがこれまでに残した内容を根拠に評価します。
このループが v3 の 2 つ目の柱、エージェンティックループエンジニアリング の汎用エンジンです。goal 状態は .moai/state/goal/<session-id>.json にセッションごとに保存され (共有ファイルではない)、ターン上限 (デフォルト 30) がループを有界にします。上限に達すると評価器は 5 セクション判定 (Claim / Evidence / Baseline-attribution / Gaps / Residual-risk) を出し、ブロッキングを止めます。--max-turns 0 を指定すると、コンパクション境界を越えて持続する無限 goal が回り、ターン数の代わりに --max-duration (実時間) と停滞ガードが実際の上限になる。実上限なしに --max-turns 0 を arm すると arm 時に拒否される (fail-closed)。
条件テキストを登録し、アクティブセッションに goal を arm します。条件は conditions[] 配列としてパースされ、純粋なシェルコマンド文字列は機械的条件、トランスクリプトを参照する主張はモデル条件となります。arm すると .moai/state/goal/<session-id>.json がアトミックに (temp+rename) 記録され、stop-goal Stop フックが次のターン終了時にこれを拾って評価を開始します。
> /moai goal "go test ./... exits 0; すべての AC が PASS として記録、または 30 ターン後に中断"アクティブセッションの goal (または --all ですべてのセッションの goal) を出力します。条件テキスト、conditions 配列、使用したターン数と上限、進行ログ、ライフサイクル状態 (armed / satisfied / ceiling-exit / cleared) を表示します。
アクティブセッションの goal を解除します (状態ファイル削除)。Stop フックは arm された goal がないことを見てブロッキングを止めます。オーケストレーターがモデル条件を充足と判定した後にループを終える方法です。
情報resume動詞は提供されません。 かつて議論されていたresume(解除された goal をアーカイブから復元する) 動詞は現在の CLI にはありません。moai goal --helpはarm/status/clearのみを列挙します。clearが状態ファイルを 削除 するため (アーカイブに tombstone しない)、復元する原本が残りません。
オーケストレーターが実装着手承認 (plan→run 境界の AskUserQuestion) を実行するとき、承認/拒否の決定と 区別される別の軸 として 自律 vs 半自律 の進行モードを選択させます。選択したモードは goal 状態の progression_mode フィールドに保存されます (ユーザーが選ばなければデフォルト autonomous)。
| モード | 動作 |
|---|---|
| 自律 (autonomous, デフォルト) | 評価器が条件充足または上限到達まで毎ターンブロッキングし、ターンごとにユーザーに尋ねません。既存の Stop フック動作そのままです。 |
| 半自律 (semi-autonomous) | stop-goal フックが毎ターン境界で チェックポイント信号 ブロック JSON を出力し、オーケストレーターがこれを読んで AskUserQuestion 確認ラウンド (続行 / goal 解除 / 自律へ切替) を回します。フック自体は決して AskUserQuestion を呼び出しません (フック・サブエージェント境界 — 構造化 JSON のみ放出)。 |
注意承認は両モードとも必須です。 進行モードの軸はゲートが通過された 後 に何をするかだけを選択するものであり、ゲートの迂回でもなければ実装着手承認の緩和でもありません。arm された goal はどのモードでも run-phase 進入を承認したり、PR を作ったり、破壊的な作業を行ったりしません。
- 実装着手承認は両モードとも必須 — 進行モードは承認後の進行選択であってゲート緩和ではなく、スコアと無関係に維持されます。
- arm された goal はゲートを迂回しない — PR を自動生成せず、破壊的な作業を行いません。評価器はターンを続けるかだけを決定し、取り消せない作業を事前承認しません。
stop-goalフックはAskUserQuestionを呼び出さない — 構造化 JSON のみ放出します (フック・サブエージェント境界)。- 停滞ガード (stagnation guard) — N 回連続で無進展の反復が検出されるとループを止め、E1/E3 エスカレーションノートを含む 5 セクション判定を出します。
評価器は毎ターン終了時に実行されます。スイート全体より go test -run <pattern> を、時間のかかるコマンドより決定論的なコマンドを選んでください。stop-goal の Stop フックタイムアウトは 120 秒ですが、速いコマンドがターンループを緻密に保ちます。
/moai loop は goal エンジンの上のプリセット です。/moai goal がユーザーが完了条件を直接宣言する汎用ループだとすれば、/moai loop は「診断ツールが見つけた課題キューを全部空にするまで」という条件をあらかじめ埋めておいたプリセットです。
| エンジン | 目標 | 完了条件 |
|---|---|---|
/moai goal | 条件宣言型の汎用ループ | ユーザー定義の条件式充足 |
/moai loop | 診断修正ループ (プリセット) | 課題キュー空 + 診断クリーン (0 エラー / テスト通過 / カバレッジ) |
終わりの状態を条件式で表現できるなら /moai goal、「ツールが見つける問題を全部なくして」なら /moai loop が適しています。