mcpField
A
aif-loop

aif-loop

github.com/lee-toエージェントワークフロー1.1k94 回インストール今日更新
リポジトリ

aif-loop について

aif-loopは、確認済みの基準に沿って成果物の作成と評価を反復するAI Factoryスキルです。ループの状態とイベント履歴を保存し、別セッションから再開できます。

主な機能

  1. 01契約で定めた6段階の実行
  2. 02定義済みチェックによる成果物の評価
  3. 03評価不合格時の成果物の改善
  4. 04状態とイベント履歴の保存
  5. 05ループの再開・停止・一覧・確認

活用シーン

  1. 01プロジェクト文書の反復的な改善
  2. 02要件に沿った生成設定の評価
  3. 03後続セッションでの成果物タスクの再開

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/lee-to/ai-factory --skill aif-loop

インストール後、Claude Code で/aif-loopを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
ACTIVE-TIME-BUDGET.md
CONTEXT-MANAGEMENT.md
CRITERIA-TEMPLATES.md
PHASE-CONTRACTS.md
RULE-SCHEMA.md
TERMINAL-REPORT.md

詳細

Loop - リフレックス反復ワークフロー

厳格なフェーズ契約、評価ルール、セッション間で保持される状態を用いて、結果重視の反復ループを実行します。

Step 0: 設定を読み込む

最初に: .ai-factory/config.yaml が存在する場合は読み込み、次の項目を解決します。

  • パス: paths.description、paths.architecture、paths.rules_file、paths.roadmap、paths.plan、paths.plans、paths.evolution
  • 言語: プロンプトには language.ui、生成コンテンツには language.artifacts

config.yaml が存在しない場合は、既定値を使用します。

  • パス:すべての成果物に .ai-factory/
  • 言語:en(英語)

用語:

  • ループ = タスクエイリアスに対する1回の完全な実行(run.json に保存され、run_id で識別されます)
  • 反復 = そのループ内の1サイクル

基本的な考え方

各反復では、可能な場合は並列実行しながら6つのフェーズを実行します。

  1. PLAN - 現在の反復の短い計画を作成します
  2. PRODUCE - 1つの artifact.md を作成します ← PREPARE と並列実行
  3. PREPARE - ルールからチェック用スクリプトとテスト定義を生成します ← PRODUCE と並列実行
  4. EVALUATE - 準備したチェックとコンテンツルールを成果物に対して実行し、結果を採点します。独立したチェックグループには並列の Task エージェントを使用します
  5. CRITIQUE - 正確な問題点と修正案を示します(失敗した場合のみ)
  6. REFINE - 批評に基づいて成果物を書き直します(失敗した場合のみ)
         PLAN
           │
    ┌──────┴──────┐
    ↓             ↓          ← parallel (Task tool)
 PRODUCE      PREPARE
 (artifact)   (checks)
    ↓             ↓
    └──────┬──────┘
           ↓
       EVALUATE              ← parallel check execution (Task tool)
       ┌───┼───┐
       ↓   ↓   ↓
      exec content aggregate
       └───┼───┘
           ↓
       CRITIQUE (if fail)
           ↓
       REFINE (if fail)

品質が十分になった場合、重大な問題が残っていない場合、ユーザーが実行を停止した場合、進捗が停滞した場合、またはリソース制限に達した場合(任意の時間予算、反復回数の上限)に停止します。優先順位の全容は Step 5 に記載されています。

永続化の契約

解決された evolution ディレクトリ内では、状態の保存に必ず3+1個のファイルを使用します(current.json はループの実行中のみ存在します)。

<resolved evolution dir>/current.json
<resolved evolution dir>/<task-alias>/run.json
<resolved evolution dir>/<task-alias>/history.jsonl
<resolved evolution dir>/<task-alias>/artifact.md

ユーザーから明示的に依頼されない限り、追加のインデックスファイルや反復ごとのフォルダ階層は作成しないでください。

ファイルの役割
  • current.json:アクティブなループへのポインターのみ。ループが completed/stopped/failed になったら削除します
  • run.json:現在のループ状態の唯一の信頼できる情報源
  • history.jsonl:追記専用のイベントログ(1行につきJSONオブジェクト1つ)
  • artifact.md:成果物の内容の唯一の信頼できる情報源(PRODUCE と REFINE の各フェーズ後に書き込み、run.json には重複して保存しません)

コマンドモード

$ARGUMENTS を解析します。

  • status - current.json からアクティブなループの状態を表示して終了します
  • resume [alias] - アクティブなループ、またはエイリアスで指定したループを再開します
  • stop [reason] - 理由を指定してアクティブなループを停止します(省略時は user_stop)
  • new <task> またはモードを指定せずタスク文を入力 - 新しいループを開始します
  • list - すべてのタスクエイリアスと状態(running/stopped/completed/failed)を一覧表示します
  • history [alias] - ループのイベント履歴を表示します(既定ではアクティブなループ)
  • clean [alias|--all] - 停止済み/完了済み/失敗したループのファイルを削除します(ユーザーの確認が必要です。削除前には必ず確認してください)

タスクが指定されておらず、アクティブなループも存在しない場合は、ユーザーにタスクのプロンプトを尋ねます。

ステップ 0:コンテキストの読み込み

存在する場合は、以下のファイルを読みます。

  • 解決済みの説明パス
  • 解決済みのアーキテクチャパス
  • 解決済みの RULES.md パス

これらを使って、出力がプロジェクトの規約に沿うようにします。

.ai-factory/skill-context/aif-loop/SKILL.md を読みます — ファイルが存在する場合は必須です。

このファイルには、パッチ、コードベースの規約、技術スタックの分析から /aif-evolve が蓄積した、プロジェクト固有のルールが含まれています。これらのルールは、現在のプロジェクトに合わせて調整されています。

skill-context ルールの適用方法:

  • skill の一般的な指示に対するプロジェクトレベルの上書きとして扱います
  • skill-context のルールがこの SKILL.md に記載された一般ルールと矛盾する場合は、skill-context のルールを優先します(より具体的なコンテキストを優先するためです。入れ子になった CLAUDE.md ファイルと同じ原則です)
  • 矛盾がない場合は、SKILL.md の一般ルールと skill-context のプロジェクトルールの両方を適用します
  • skill-context のルールがこの skill の既定値と矛盾するように見えても、無視してはいけません。プロジェクトでの経験から、既定値では不十分だと判明したために存在しています
  • 重要: skill-context のルールは、この skill のすべての出力に適用されます。生成される成果物、実行状態、評価基準も対象です。skill-context のルールに「成果物には X を含めること」または「評価では Y を確認すること」とある場合は、必ず従ってください。skill-context のルールに違反するループ出力を生成するのはバグです。

遵守の確認: 成果物を生成した後、すべての skill-context ルールに照らして確認します。ルールに違反している場合は、ユーザーに提示する前に出力を修正してください。

ステップ 0.1:反復以外のコマンドを処理する

コマンドが status、stop、list、history、clean のいずれかの場合は、処理を実行して終了します。

  • status:current.json を読みます。ファイルが存在する場合は、指定された run.json を読み、alias | status | iteration | phase | current_step | last_score | updated_at を表示します。予算が設定されている場合は、completed_phase_seconds / max_completed_phase_seconds も表示します。ファイルが存在しない場合は、実行中のループがないことを報告します
  • stop [reason]:実行中のループのみ停止します。run.json.status = "stopped" と run.json.stop.reason = <reason or "user_stop"> を設定し、history.jsonl に stopped イベントを追加した後、current.json を削除して(アクティブなポインターをクリアして)終了します
  • list:解決済みの進化ディレクトリを走査し、各 run.json を読み、alias | status | iteration | last_score | updated_at の表を表示します
  • history [alias]:指定された alias(またはアクティブなループ)の history.jsonl を読み、書式付きのイベント時系列を表示します
  • clean [alias|--all]:削除対象を表示し、AskUserQuestion でユーザーに明示的な確認を求めてから、ループディレクトリを削除します。停止済み/完了/失敗したループのみを削除できます。実行中のループの削除は拒否します。必要に応じて current.json を更新します

ステップ 1:ループの初期化または再開

1.1 ディレクトリの確認
mkdir -p <resolved evolution dir>
1.2 エイリアスと ID(新規ループ)

以下を生成します。

  • task_alias:小文字のハイフン区切りスラッグ(3~64 文字)
  • run_id:<task_alias>-<yyyyMMdd-HHmmss>
1.3 current.json の書き込み
{
  "active_run_id": "courses-api-ddd-20260218-120000",
  "task_alias": "courses-api-ddd",
  "status": "running",
  "updated_at": "2026-02-18T12:00:00Z"
}
1.4 初期 run.json の書き込み
{
  "run_id": "courses-api-ddd-20260218-120000",
  "task_alias": "courses-api-ddd",
  "status": "running",
  "iteration": 1,
  "max_iterations": 4,
  "max_completed_phase_seconds": null,
  "completed_phase_seconds": 0,
  "phase_started_epoch_seconds": null,
  "phase": "A",
  "current_step": "PLAN",
  "task": {
    "prompt": "OpenAPI 3.1 spec + DDD notes + JSON examples",
    "ideal_result": "..."
  },
  "criteria": {
    "name": "loop_default_v1",
    "version": 1,
    "phase": {
      "A": { "threshold": 0.8, "active_levels": ["A"] },
      "B": { "threshold": 0.9, "active_levels": ["A", "B"] }
    },
    "rules": []
  },
  "plan": [],
  "prepared_checks": null,
  "evaluation": null,
  "critique": null,
  "stop": { "passed": false, "reason": "" },
  "last_score": 0,
  "stagnation_count": 0,
  "created_at": "2026-02-18T12:00:00Z",
  "updated_at": "2026-02-18T12:00:00Z"
}
1.5 再開ロジック

ループを再開する場合:

  1. run.json を読み、current_step と iteration を取得します
  2. history.jsonl の最後のイベントを読み、一貫性を確認します
  3. run.json.current_step がフェーズの中断を示している場合:
    • そのフェーズから再実行します(スキップしません)
    • PRODUCE_PREPARE の場合は、PRODUCE と PREPARE の両方を必ず再実行します(冪等です。成果物は上書きされ、チェックは再生成されます)
  4. run.json.status が stopped、completed、または failed の場合は、ユーザーに知らせて new を提案します(failed の実行では、問題の内容がわかるように、history.jsonl の最後の phase_error イベントも表示します)
  5. 古い phase_started_epoch_seconds は破棄します。中断されたフェーズを実際に再開するときに、現在の date +%s を設定します。中断された試行は予算に加算されません。完了したセグメントからすでに累積された completed_phase_seconds のみが引き継がれます(references/ACTIVE-TIME-BUDGET.md を参照してください)。

ステップ 2:対話型セットアップ(新しいループ)

クイックモード(デフォルト、確認優先)

タスクのプロンプトに、タスクの種類と理想的な結果を推測するのに十分な情報が含まれている場合:

  1. プロンプトからタスクの種類を自動検出します(API 仕様、コード、ドキュメント、設定)
  2. references/CRITERIA-TEMPLATES.md から該当するテンプレートを読み込みます
  3. 推測したルール、フェーズのしきい値(フォールバック:A=0.8、B=0.9)、最大イテレーション数(デフォルト:4)、完了フェーズの時間予算(デフォルト:none。references/ACTIVE-TIME-BUDGET.md のセットアップルールに従う場合に限り推測します)を作成します
  4. 最大イテレーション数の横に正規化した予算を添えて、推測した設定をドラフトの要約として表示します
  5. タスクのテキストに成功基準がすでに記載されている場合でも、AskUserQuestion を使って成功基準(ルール/しきい値)の明示的な確認を必ず求めます
  6. タスクのテキストにイテレーション数がすでに記載されている場合でも、AskUserQuestion を使って最大イテレーション数の明示的な確認を必ず求めます
  7. ドラフトした値が null でない場合は、時間予算について明示的な確認を求めます。その際、必ず none も選択肢として提示します
  8. ユーザーが基準、最大イテレーション数、または予算を変更した場合は、ドラフトを更新し、3 項目すべてについて再確認を求めます
  9. 明示的な確認が完了してから、イテレーション 1 を開始します
  10. タスクの種類を自動検出できない場合(曖昧、または複数の種類が混在するプロンプト)は、ただちにフルセットアップに進みます
フルセットアップ

重要なガードレール:

  • タスクのプロンプトに成功基準と最大イテレーション数の両方がすでに記載されていても、必ず再度質問し、明示的に確認を得てください。

最初のイテレーションを開始する前に、簡潔なセットアップの質問をします:

  1. タスクの種類 - どの種類の成果物ですか?(API 仕様、コード、ドキュメント、設定、その他)- references/CRITERIA-TEMPLATES.md からテンプレートを読み込む際に使用します
  2. 理想的な結果の定義
  3. 必須チェック(テスト、スキーマ/コントラクト、具体的な要件)
  4. 品質しきい値(A/B フェーズ)
  5. 最大イテレーション数(デフォルト:4)
  6. 完了フェーズの時間予算(秒単位、デフォルト:none)— none を明示的に選択肢として提示します。ドメインレベルのタイムアウトはループの予算ではありません
  7. 重大な問題とみなす条件
  8. 明示的な確認:「この成功基準でよろしいですか?」
  9. 明示的な確認:「最大イテレーション数 = N でよろしいですか?」
  10. 予算が none でない場合は、予算について明示的に確認します:「時間予算 = N 秒でよろしいですか?」

回答から評価ルールを生成します:

  • references/CRITERIA-TEMPLATES.md から該当するテンプレートを読み込み、出発点として使用します
  • 理想的な結果と必須チェックに基づいて、タスク固有のルールを追加します
  • 開始前に、ユーザーがルールを確認し、調整できるようにします

回答と生成されたルールは、再現性を確保するためのスナップショットとして run.json.criteria に保存します。

タスクのテキストから解析した基準、イテレーション数の上限、または時間予算は、ユーザーが明示的に確認するまで確定したものとして扱ってはいけません。

保存前の正規化ルール:

  • イテレーション数の上限に関する唯一の信頼できる情報源は run.json.max_iterations です
  • 時間予算に関する唯一の信頼できる情報源は run.json.max_completed_phase_seconds です。この項目は省略可能です。ユーザーが時間予算を求め、確認した場合を除き、null(制限なし)を保存します。このフィールドがない実行ファイルは null として扱います。受け付けられる値は null または秒単位の正の整数です。文字列、0、負の数、小数の場合は検証エラー(phase_error)となり、値を強制的に変換してはいけません。詳細は references/ACTIVE-TIME-BUDGET.md を参照してください
  • すべてのルールを完全な RULE-SCHEMA 形式(id、description、severity、weight、phase、check)に展開します
  • テンプレートの簡略形式で weight が省略されている場合は、重大度から導出します(fail=2、warn=1、info=0)

ステップ 3:フェーズコントラクト

フェーズを実行する前に、以下を読み込みます:

  • references/PHASE-CONTRACTS.md - 各フェーズの厳格な入出力コントラクト
  • references/RULE-SCHEMA.md - ルールの形式とスコアの計算
3.1 フェーズ
  • PLAN - 反復計画を生成します(逐次実行)
  • PRODUCE - 成果物を生成します(PREPARE と並列実行)
  • PREPARE - ルールとタスクプロンプトからチェック用スクリプト/定義を生成します(PRODUCE と並列実行)
  • EVALUATE - 準備済みのチェックとコンテンツルールを実行し、スコアを集計します(Task 経由でチェックグループを並列実行)
  • CRITIQUE - 修正指示とともに問題点を特定します(逐次実行、不合格の場合のみ)
  • REFINE - 成果物に修正を適用します(逐次実行、不合格の場合のみ)
3.2 並列実行モデル

Task ツールを介して、2 つのレベルで並列処理を行います。

  1. フェーズ間:PLAN の完了後、PRODUCE と PREPARE を並列の Task エージェントとして実行します。どちらも PLAN の出力のみを依存関係とします。
  2. フェーズ内:EVALUATE は、独立したチェックグループごとに並列の Task エージェントを起動します(Bash を使う実行可能なチェック、Read/Grep を使うコンテンツルール)。結果を集計して最終スコアを算出します。
3.3 フェーズの出力形式

各フェーズは、定義された出力を生成します(PHASE-CONTRACTS.md を参照)。ラッパーによる包含はありません。ルーターの出力もありません。

Step 4: 反復の実行

各反復では、次の手順を実行します。

  1. run.json.current_step = "PLAN" を設定し、PLAN フェーズを実行します。
  2. run.json.current_step = "PRODUCE_PREPARE" を設定し、両方を並列の Task エージェントとして起動します。
    • Task A(PRODUCE):成果物を生成し、artifact.md に書き込みます
    • Task B(PREPARE):ルールと計画からチェック用スクリプト/定義を生成します
    • 両方の完了を待ちます
  3. run.json.current_step = "EVALUATE" を設定し、EVALUATE フェーズを実行します。
    • 独立したチェックグループごとに並列の Task エージェントを起動します。
      • 実行可能なチェック(コンパイル、リンティング、テスト)→ Bash を使う Task
      • コンテンツルール(構造、完全性、スタイル)→ Read/Grep を使う Task
    • 結果をスコアに集計します
  4. passed=false の場合:
    • まず、Step 5 の停止条件を優先順位に従って評価します。 いずれかの条件に該当する場合は、処理を続けず、その理由で停止します。Step 5 の確認は反復を進める前に行い、進めた後には行いません
    • 該当しない場合:run.json.current_step = "CRITIQUE" を設定し、CRITIQUE フェーズを実行します
    • run.json.current_step = "REFINE" を設定し、REFINE フェーズを実行します
    • 更新した成果物を artifact.md に書き込みます
    • 反復回数を増やして続行します
  5. phase=A かつ passed=true の場合:
    • phase=B に切り替え、B レベルのルールを有効にします
    • run.json.current_step = "PREPARE" を設定し、phase=B で PREPARE を再実行して、B レベルのチェックを実体化します(成果物はすでに A に合格しているため、PLAN/PRODUCE は実行しません)
    • run.json.current_step = "EVALUATE" を設定し、準備済みの B レベルのチェックを使って同じ成果物を対象に EVALUATE フェーズを実行します
    • B の評価にも合格した場合は、成功として停止します(threshold_reached)
    • B の評価に不合格の場合は、CRITIQUE → REFINE と進み、その後、反復回数を増やします
  6. phase=B かつ passed=true の場合:
    • 成功として停止します(threshold_reached)
逐次実行へのフォールバック

Task ツールを利用できない場合、またはエラーを返した場合は、逐次実行に切り替えます。実行順は PLAN → PRODUCE → PREPARE → EVALUATE → CRITIQUE → REFINE です。並列処理なしでもループが機能する必要があります。

このフォールバックでは、PRODUCE_PREPARE は引き続き 1 つの論理ステップとして扱います。current_step を分割せず、PRODUCE と PREPARE の間に予算による停止を設けず、並列実行の試行失敗と逐次再試行を同じ計測セグメントとして扱います。

Step 5: 停止条件

優先順位の契約

同じフェーズ境界で複数の条件が成立することがあります。この番号順は優先順位を決めるための順序であり、独立したチェックの一覧ではありません。上から順に評価し、最初に一致したものを stop.reason として報告します。完了条件はリソース条件より先に評価されるため、正常に完了した実行が、同時にリソースを使い切ったという理由で stopped に変更されることはありません。

  1. threshold_reached — phase=B かつ passed=true
  2. no_major_issues — phase=B かつ現在の評価で fail レベルのルールが失敗していない場合:warn/info のみが残り、より厳しいフェーズが残っていない状態です。phase=A では発生しません。A の評価に問題がなければ、phase=B に進む(Step 4.5)か、改善を続けるため、B レベルのルールがスキップされることはありません
  3. user_stop — ユーザーによる明示的な停止
  4. stagnation — stagnation_count >= 2(以下の「停滞ルール」を参照)
  5. budget_exceeded — max_completed_phase_seconds が設定されており、completed_phase_seconds >= max_completed_phase_seconds
  6. iteration_limit — iteration >= run.max_iterations

budget_exceeded が iteration_limit より優先されるのは意図的です。時間は取り戻せない外部リソースであるため、両方の条件に達した場合は、予算を理由として示すほうが有用です。重要なのは、どこでも順序が同じであることです。この一覧は docs/loop.md と subagents/claude/agents/loop-orchestrator.md にもそのまま記載されており、3 か所すべてで同期を保つ必要があります。

完了フェーズの時間予算

run.json.max_completed_phase_seconds は、完了したフェーズ区間に費やす時間の任意の上限です。null または未設定の場合、上限はありません。この上限はソフト上限です。フェーズ境界でのみ確認し、フェーズ(またはそのリトライ)の途中で中断することはありません。そのため、実行時間は進行中のフェーズの所要時間分まで超過することがあります。カウントされるのは完了した区間だけです。中断されたフェーズは、偶然ではなく定義上、時間に加算されません。型と不変条件、境界での計測、単一の区間として扱う PRODUCE_PREPARE とリトライ、クロックの巻き戻り、診断、セットアップルールを含む契約全体は、references/ACTIVE-TIME-BUDGET.md を参照してください。

停滞ルール

スコアの進捗を追跡します。

  • delta = score - last_score
  • delta < 0.02 で、重大度が fail のブロッカーがない場合は、stagnation_count を増やします
  • stagnation_count >= 2 の場合は、stagnation で停止します

Step 6: 永続化への書き込み(各ステップ)

各フェーズの出力後に、次の処理を行います。

  1. run.json を更新します(current_step を含む)
  2. イベントを history.jsonl に追記します
  3. current.json.updated_at を更新します
  4. PRODUCE フェーズと REFINE フェーズの後に、artifact.md をディスクに書き込みます
  5. REFINE で artifact.md を上書きする前に、以前のアーティファクトの SHA-256 ハッシュを "previous_artifact_hash" として refinement_done イベントのペイロードに保存します(履歴を肥大化させずに整合性を検証できます)
  6. max_completed_phase_seconds が設定されている場合は、references/ACTIVE-TIME-BUDGET.md に従い、フェーズ境界ごとに completed_phase_seconds/phase_started_epoch_seconds を同じ run.json の書き込みで更新します。タイマーを別に書き込むことはありません

イベント名:

  • run_started
  • plan_created
  • artifact_created
  • checks_prepared
  • evaluation_done
  • critique_done
  • refinement_done
  • phase_switched
  • iteration_advanced
  • phase_error
  • stopped
  • failed

history.jsonl の行の例:

{"ts":"2026-02-18T12:01:10Z","run_id":"courses-api-ddd-20260218-120000","iteration":1,"phase":"A","step":"EVALUATE","event":"evaluation_done","status":"ok","payload":{"score":0.72,"passed":false}}

Step 7: ループ後

アーティファクトの状態(数値を報告する前に確認)

停止はどのフェーズ境界でも発生するため、アーティファクトが存在しない(not_created)、未評価(unevaluated)、保存済みの評価より新しい(stale。evaluation.artifact_hash で検出)、または評価済み(evaluated)の場合があります。数値の final_score または成功までの距離ブロックを報告できるのは、evaluated の場合のみです。それ以外の3つの状態では、理由と、以前に評価済みのスコアがあれば last_evaluated_score を添えて、final_score: unavailable と出力します。契約全体、出力形式、状態ごとのルールについては、references/TERMINAL-REPORT.md を参照してください。

ループ停止後(理由を問わず):

  1. 最終状態の概要を表示します(iteration、max_iterations、phase、artifact_status、上記のルールに従った final score、stop reason)。
  2. stop reason が iteration_limit または budget_exceeded で、artifact_status が evaluated、かつ評価の passed=false の場合は、必須の成功までの距離の詳細を含めます。
    • アクティブフェーズのしきい値と最終スコア
    • しきい値までの数値上の差(threshold - score。0を下限とします)
    • 残っている fail 重大度ルールの数と、ブロックしているルール ID
    • ルールの進捗(passed_rules / total_rules)
  3. stop reason が budget_exceeded の場合は、予算診断(completed_phase_seconds、max_completed_phase_seconds、overshoot_seconds、last_completed_step)も含め、stopped イベントのペイロードにも記載します(references/ACTIVE-TIME-BUDGET.md)。
  4. 最終アーティファクトの保存先をユーザーに尋ねます(デフォルト:<resolved evolution dir>/<alias>/artifact.md に保存)。artifact_status が not_created の場合は、ステップ4~5を完全に省略し、存在しないファイルを提示する代わりに、その旨を伝えます。
  5. アーティファクトをユーザー指定のパスにコピーすることを提案します。
  6. アーティファクトの種類に応じて、次のスキルを提案します。
    • API 仕様 → 実装には /aif-plan
    • コード → 確認には /aif-verify
    • ドキュメント → 取り込みには /aif-docs
  7. 停止理由に基づいて run.json.status を更新し、current.json がこのループを指している場合は、current.json を削除します(アクティブなループは残りません)。
停止理由ステータス
threshold_reachedcompleted
no_major_issuescompleted
user_stopstopped
iteration_limitstopped
stagnationstopped
budget_exceededstopped
phase_errorfailed

この対応付けは、ステップ5の優先順位に関する契約に従って選択された理由に適用されるため、完了ガードと同じ境界でリソースガードが作動しても、完了した実行が stopped に格下げされることはありません。

ステップ8:ユーザーへの応答形式

各イテレーションの後に、簡潔な概要を表示します。会話に run.json や artifact.md の内容全体を出力してはいけません。アーティファクトはすでにディスク上にあり、重複して出力するとコンテキストを無駄にします。

イテレーション概要の形式
── Iteration {N}/{max} | Phase {A|B} | Score: {score} | {PASS|FAIL} ──
Plan: {1-line summary of plan focus}
Hash: {first 8 chars of artifact SHA-256}
Changed: {list of added/modified sections, or "initial generation"}
Failed: {comma-separated rule IDs, or "none"}
Warnings: {comma-separated rule IDs, or "none"}
Artifact: <resolved evolution dir>/<alias>/artifact.md
  • Hash — アーティファクト全体を読まずに、どのバージョンを見ているのか確認できます。
  • Changed — イテレーション間で実際に変更された内容を示すため、概要だけで回帰を確認できます。

passed=false の場合は、簡潔な批評の概要(問題ごとにルール ID と1行の修正指示)を追記します。アーティファクト全体や評価オブジェクト全体を繰り返し出力してはいけません。

ループが reason=iteration_limit または reason=budget_exceeded で終了し、artifact_status が evaluated、かつ passed=false の場合は、最終応答に簡潔な distance_to_success ブロックを追記します。それ以外の artifact_status では、代わりにステップ7の final_score: unavailable ブロックを出力します。現在のアーティファクトに該当しない評価を使って、差を算出してはいけません。

出力全体を表示する例外

次の場合に限り、成果物の内容全体(要約だけでなく)を表示します。

  1. ループの終了 — 最終イテレーションで成果物全体を出力します。ただし、artifact_status が not_created の場合は、成果物が作成されなかったことと、ループが停止した理由を報告します
  2. フェーズ A → B の移行 — 移行の境界で、フェーズ A の合格基準を満たした成果物全体を一度表示し、内容を確認できるようにします(ステップ 4 に従い、B レベルの評価も直ちに実行します)
  3. ユーザーからの明示的な依頼 — ユーザーがループの途中で成果物全体の表示を求めた場合

ステップ 9:コンテキスト管理

ループでは、イテレーションごとに多くのコンテキスト(サブエージェントの結果、評価データ、批評)が生成されます。ループの状態はすべてディスクに保存されるため、コンテキストをクリアしても何も失われず、resume によってファイルから状態を完全に再構築できます。

イテレーション 2 の後、フェーズ A → B の移行時、および iteration >= 3 となるイテレーションの後には、コンテキストのクリアを推奨します。決して強制または自動でクリアせず、ユーザーが判断します。

正確な文言と理由については、references/CONTEXT-MANAGEMENT.md を参照してください。

エラーからの復旧

フェーズ出力が無効な場合

フェーズが契約に適合しない出力を生成した場合:

  1. history.jsonl に、イベント phase_error としてエラーを記録します
  2. 同じ入力を使用してフェーズを一度だけ再試行します
  3. 再試行も失敗した場合は、reason=phase_error としてループを停止し、エラーを表示します
run.json が破損している場合

run.json が存在しない、または解析できない場合:

  1. history.jsonl を読み取り、最後に確認された状態を復元します
  2. 最新のイベント(最後のイテレーション、フェーズ、スコアなど)から run.json を再構築します
  3. history.jsonl も存在しない、または空の場合は、ユーザーに知らせ、新しいループの開始を提案します

重要なルール

  1. 現在の状態の唯一の正しい情報源は run.json です(成果物の内容は保存しません)
  2. 成果物の内容の唯一の正しい情報源はディスク上の artifact.md です。run.json に重複して記載してはいけません
  3. history.jsonl は追記専用です。過去のイベントを編集してはいけません
  4. ループは高速に保ちます。計画は短く、批評は的を絞り、書き直しは最小限にします
  5. 3+1 個の永続化ファイル以外に、追加のファイルを作成してはいけません
  6. 評価者は厳格かつ非創造的でなければなりません
  7. リファイナーは、不合格となったルールを満たすために必要な箇所だけを変更します
  8. まずはシンプルに始め、指標から必要性が示された場合にのみ複雑さを加えます
  9. 失敗したフェーズは、停止する前に一度だけ再試行します
  10. デフォルトでは簡潔なイテレーション要約を使用します(ステップ 8)。成果物全体の出力はステップ 8 の例外に限り許可されます。会話に run.json 全体をそのまま出力してはいけません
  11. 戦略上重要なタイミング(ステップ 9)、つまりイテレーション 2 の後、フェーズ移行時、または iteration >= 3 の場合に、コンテキストのクリアを推奨します

例

/aif-loop new OpenAPI 3.1 spec + DDD notes + JSON examples
/aif-loop resume
/aif-loop resume courses-api-ddd
/aif-loop status
/aif-loop stop
/aif-loop list
/aif-loop history
/aif-loop history courses-api-ddd
/aif-loop clean courses-api-ddd
/aif-loop clean --all

コメント