orca-graph について
orca-graphは、PLAN.mdのタスクを依存グラフに変換して実行を調整するスキルです。並列ディスパッチと永続状態が必要な作業向けで、追記型イベントログを基準に依存関係の監査や検証、グラフ表示を行います。
主な機能
- 01PLAN.mdから依存グラフを構築
- 02トポロジカルな層ごとにロックと実行
- 03追記型イベントログで状態を永続化
- 04根拠付き回答の検証と監査
- 05グラフと2Dアトラスを生成
活用シーン
- 01依存タスクを含む計画の調整
- 02複数のエージェントによる同一タスクの奪い合い防止
- 03セッションをまたいだ未完了作業の再開
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rheinmir/ setup --skill orca-graphインストール後、Claude Code で/orca-graphを入力して読み込まれたか確認します。
詳細
スキル:orca-graph
orca-workflow の分岐版です。propose → gate → plan → dispatch は同じですが、依存関係はデータ(graph.json)であり、頭の中で推測するものではありません。ランタイム:harness/scripts/orca-graph.py。可視化:fdk/tools/graph-viz.py(1つのグラフ)+ fdk/tools/graph-atlas.py(2Dアトラス)。デフォルトの保存先は llmwiki/graph/ です。
エンジンは別のリポジトリにあります:https://github.com/Rheinmir/orca-graph(テスト+VT評価スイート+独自の履歴)。~/.orca-graph/repo/ にインストールします。overstack 内の上記3つのパスは、このエンジンを指すシムです。入力するコマンドは従来どおりです。シムが「エンジンが未インストールです」(rc 3)と表示したら、表示されたコマンドをそのまま実行してください:curl -fsSL https://raw.githubusercontent.com/Rheinmir/orca-graph/main/install.sh | bash。overstack がない場合は、~/.orca-graph/bin/orca-graph を直接呼び出してください。
WHAT
目的とコンテキスト
- 目的: PLAN.md の作業を依存関係グラフ(依存関係は graph.json 内のデータ)に分解し、決定論的なツールで5つの質問に答えます。トポロジカル層ごとにロック+リース+世代管理を行ってディスパッチし、追記専用で永続化された状態を維持し、ソース付きのルーブリックですべてのモデルの回答を採点します。
- 利用するタイミング:
- PLAN.md に3つ以上のタスクがあり、何を並行して実行できるか、何が何を待つのか、どこまで進んだのかを把握する必要がある場合。
- 複数のエージェントをディスパッチし、2つのエージェントが同じタスクを奪い合ったり、同じファイルに書き込んだりしないようロックが必要な場合。
- 作業が複数のセッションにまたがる場合。状態はクラッシュ後も保持されなければならず、「頭の中で覚えておく」ことはできません。
- 対象外: インシデントには使用しないでください(→
orca-issue)。PLAN がない場合も使用しないでください(→/proposeの後に/plan)。 PRD v1.1 の範囲外です(率直に明記):outbox/backpressure を備えた永続的な item pipeline、token 単位の layered fan-in、anchor registry、eval floor に基づくモデルルーティング、scale proposal、discovery 用の seen ledger — 詳しくはエンジンリポジトリのevals/vt-matrix.jsonを参照してください。28件中13件の VT シナリオが、理由付きでout_of_scopeと記録されています。 PRD の範囲外です(率直に明記しており、あるように装っていません):PostgreSQL ledger、secret gateway、予算管理、LangGraph、integration queue/candidate hash、外部 effect の補償、プロセスレベルのサンドボックス(エージェントのコマンドを専用コンテナ/VM で実行すること)。このツールは1台のマシン向けのファイルベースです。上記が必要なら、それは別のエンジンであり、orca-graph のアップグレードではありません。(ファイル書き込みの allow-list — プロセスのサンドボックスとは別 — は実装済みです。以下の「Reference — Daemon & control-room」にあるrun --strictと GH#162 を参照してください。)
メンタルモデル
PLAN.md → build → graph.json(キャッシュ)+ events.jsonl(真実のソース、追記専用)→ ask(5つの質問)→ トポロジカル層ごとの next/lock/set/run → verify(+ qc)→ audit → graph-viz / graph-atlas / control-room。
各ノードの状態遷移:
proposed → ready(すべての依存関係が完了)→ locked → dispatched → done | done_unverified | failed | unknown;blocked は HITL で人による対応待ちです。
3つの軸は分離されています:state(ライフサイクル)・verified(verify が rc 0 だったか)・fresh(完了後に上流が再実行されて stale になったか。警告のみ)。
Reprise PRD から取り入れたルール:op_key の冪等性・CAS --if-rev・古い結果を防ぐ generation・リース切れ → failed ではなく unknown・verify なしでは done にならない。
qc(GH#163、任意 — PLAN.md の**QC:**フィールド。verifyと同様にspec_hashに含まれます):verifyが rc=0 で完了した後に実行する、独立したレビューコマンドです。verify を行ったのと同じ呼び出しでは実行されません(emit()のby != "reconcile")。verify を自分で実行した人/エージェントの役割と、レビュー担当者の役割を分けます。失敗した場合、run/set doneから直接実行したときはemit()がdoneをdone_unverifiedに降格します(verify 失敗と同様)。reconcile経由の場合はreadyと判定します(reconcileは明確な結論を出し、done_unverifiedのまま保留にしません)。**QC:**を指定しない場合、これまでとまったく同じ動作です(後方互換性あり)。
入力と出力の契約
| 項目 | 必須? | 意味 | |
|---|---|---|---|
| 入力 | PLAN.md | はい | 3 件以上のタスク;**Depends:**、**Verify:**、任意の **Kind:**、**QC:**、**Resources:** の行;存在しない場合は skill plan を呼び出します |
| 入力 | 依存関係の理由 | あることが望ましい | **Depends:** Task 1 (data), Task 2 (preference) — reason ∈ data · contract · acceptance · effect_order · control(ハードな依存関係)· preference(記述順によるもののみ) |
| 入力 | リソースの申告 | 共有時 | **Resources:** db-migration(exclusive), api-x(shared), llm(capacity:2) — mode の指定がない場合は exclusive |
| 入力 | store | いいえ | デフォルトは llmwiki/graph/ |
| 入力 | --parent <gid>/<node> | いいえ | 子グラフを親グラフのノードに接続します |
| 入力 | agent + agent のコマンド | ディスパッチ時 | lock --by に指定する agent 名;run … -- に指定するコマンド |
| 出力 | <id>.graph.json + <id>.events.jsonl + .locks/ | はい | グラフ + 永続状態 |
| 出力 | build の出力 | はい | サイクル、推論された依存関係(gợi-ý)、並列実行する 2 つのノード間で同じファイルを書き込む競合 |
| 出力 | ラベルとソース付きの回答 | モデルが回答する場合 | ルーブリック 1 / 0 / 0.3 / 0.5 / 捏造 0 で採点します |
| 出力 | HTML グラフ + 2D アトラス + control-room.html | はい | 描画用 Python ファイル 2 つ + control-room ジェネレーター |
| 出力 | audit-log.jsonl | 完了時 | ソースを 1 つずつ再確認した結果;捏造 = 0 |
ルールと機能
- RULE-01 (MUST): ロックは DISPATCH を制御します;ファイル書き込みの副作用に対する allow-list はソフト制御です (GH#162) — 上記の
run --strictを参照してください。Allow-list は実際のプロセス分離の代わりにはなりません → 完全な分離が必要な場合は、タスクごとに専用の worktree を引き続き選択してください(コマンド、環境変数、ファイルシステム外の副作用を実行します)。 - RULE-02 (MUST): headless CLI では
blocked(HITL)ノードをディスパッチしないでください — 人間の代わりに推測して黙ってしまいます(250626 の教訓、約 1/5 を割り当て)。 - RULE-03 (MUST): グラフに関するモデルの回答はすべて、開いて確認できるラベルとソースを付けて
answerに通す必要があります。ソースがない場合は、捏造(0)ではなくkhông-biết(0.3)を選択してください。 - RULE-04 (MUST): 推論された
gợi-ý依存関係は、該当するレイヤーをディスパッチする前にユーザーが承認するか、**Depends:**で宣言する必要があります。 - RULE-05 (MUST):
events.jsonlを削除したり手動で編集したりしないでください。誤りがあれば、修正イベントを追加してください。graph.jsonはキャッシュにすぎません — 破損した場合はbuildを再実行し、状態は events から fold します。 - RULE-06 (MUST): 生成される HTML には、ライト/ダーク切り替え + full path + 意味の説明がある用語(fdk ルール)が必要です — 描画用ファイル 2 つで対応済みです。HTML を手書きしないでください。
- RULE-08 (MUST): リソースの競合は DAG の依存関係ではありません (PRD v1.1 §23.2)。独立した 2 つのタスクが統合ブランチ/DB スキーマ/テスト環境/API クォータを共有する場合は、
**Resources:**で申告し、実行時の順序制御はlockに任せてください。偽の**Depends:**を追加しないでください。専用の worktree を使っていても申告は必要です。 - RULE-09 (MUST):
audit-edgesは読み取り専用で、提案のみを行います。理由のない依存関係(EDGE_UNJUSTIFIED)は維持してユーザーに確認してください。「依存関係が見つからない」は「独立していることが証明された」と同じではありません。依存関係の削除はユーザーの同意を得てから行います → PLAN を編集 →buildを再実行します。 - RULE-10 (MUST): 実行中のグラフにタスクを追加するようユーザーから依頼された場合は、
add-nodeを使用してください(元の PLAN を編集して再ビルドし、plan_version + 1とします。履歴は保持されます)。graph.jsonの手動修正は禁止です。同じ goal に対して新しいグラフを作成することも禁止です。 - RULE-07 (MUST): 対応できないこと(率直に伝えてください):ファイルに表れない暗黙の結合;agent が処理途中で終了した場合の自動ロールバック;Orca の台帳との双方向同期;約 500 ノードを超えるアトラスには graphviz が必要;allow-list はファイルシステムのみを検査し、network/process/secret へのアクセスは検査しません。
- 機能:PLAN とプロジェクトファイルの読み取り;追記専用の graph store への書き込み + ファイルロック;agent プロセスの起動と監視(pid による heartbeat);verify/qc コマンドの実行;git diff の読み取りによる allow-list の検査;静的 HTML の生成。外部のオーケストレーション台帳への一方向ミラーリングは任意です。
失敗の境界
- PLAN がない → blocked。
planを呼び出します(または/proposeの後に/planを実行します)。障害の場合はorca-issueに切り替えます。 - Cycle(
check-cyclesの rc 2)または depth ≤ 6/node ≤ 20 の上限超過 → ツールが拒否し、スコープを縮小するまで blocked になります。 gợi-ýの依存関係が未確認 → そのレイヤーをディスパッチする前に、ユーザーに clarify します。- Node が
blocked(HITL) → 人の対応を待ちます。ヘッドレスでディスパッチしてはいけません。 - エージェントが lease を超えて応答しない →
unknown(failedではありません)となり、reconcileします。試行回数が 3 回を超えると failed になります。 - 生成結果が古い、または plan_version が異なる → STALE となり、公開しません。
- 回答の根拠となる情報源がない →
không-biếtラベルを付け、捏造しません。
方法
メインワークフロー
| ステップ | 種類 | 入力 | アクション | 出力/終了条件 | 失敗時/次の処理 |
|---|---|---|---|---|---|
| W01 | 決定的 | harness があるリポジトリ | ステップ 0:事前作業の sweep pull-gate-sweep.sh | sweep 完了 | harness がない場合 → スキップ |
| W02 | 判断 | PLAN | ステップ 1:PLAN があるか確認。なければ skill plan を実行し、Depends + Verify を実際の内容で記入 | PLAN.md | Depends が不足 → tool が推測し、gợi-ý ラベルを付与 |
| W03 | 決定的 | PLAN.md | ステップ 2:python3 harness/scripts/orca-graph.py build <PLAN.md> | graph.json + cycle とファイル競合の警告 | 競合 → Depends を追加するか、理由を示して受け入れる |
| W03b | 決定的 | graph.json | ステップ 2b:audit-edges <id> — 理由のないエッジ、削除可能な preference エッジ、変更前後のクリティカルパス | finding の表(読み取り専用) | EDGE_UNJUSTIFIED → 理由をユーザーに尋ね、Depends に記入 |
| W04 | 判断 | graph | ステップ 3:まず ask で 5 つの質問を行い、その後、ラベル + ソースを付けて answer でモデルが回答 | ラベル付きの回答 | ソースなし → 不明 |
| W05 | 副作用あり | graph.json | ステップ 4:graph-viz.py で描画 → HTML をユーザーに送り、承認を得る(gate-create) | HTML + gate | 未知の kind → B06 |
| W06 | 副作用あり | 承認済み graph | ステップ 5:完了が next から報告されるまで、next → lock → set dispatched → dispatch → set done のループ | node が done | lease 切れ → B05 |
| W07 | 決定的 | 完成した graph | ステップ 6:audit <id> → graph-atlas.py llmwiki/graph/ → 問題が明らかになった場合は problem-tree | audit-log + atlas | 捏造 > 0 → 報告 |
各ステップの詳細(W01–W07 の正本。ステップ 0–6 は W01–W07 に対応):
- harness がある場合は、orca-workflow と同様に事前作業の sweep(
pull-gate-sweep.sh)を行います。 - PLAN はありますか? なければ skill
planを呼び出します。/planのテンプレートには**Depends:** Task 1, Task 3と**Verify:** <終了コード 0 のコマンド>の行があります。実際の内容を記入してください。Depends が不足している場合、tool が Consumes/Produces から推測し、gợi-ýラベルを付与します。 - graph を構築:
python3 harness/scripts/orca-graph.py build <PLAN.md>→ cycle、推論された deps、並行する 2 つの node 間での同一ファイルへの書き込み競合を出力します(⚠ → Depends を追加して順次実行にするか、理由を示して受け入れます)。 - 5 つの質問に回答 — まず tool、次にモデル:
ask <id> needs·ask <id> parallel·ask <id> deps <n>·ask <id> why <n>·ask <id> related。- モデルが補足する内容(意味、既存 graph との意味的な関連、リスク)→ ラベル + ソースを付けて
answerで記録します:answer <id> <n> --q why --label chắc|gợi-ý|không-biết --score S --evidence file:path:line edge:a->b event:<op_key> absence:<lệnh> --text "..."。 - 評価基準(2026-09-12 にユーザーが確定):正解 1 · 不正解 0 · 不明 0.3 · 実際のソースがある提案 0.5 · ソースの捏造 0。確信がない場合は
gợi-ý/không-biếtとし、chắcを付けないでください。
- 描画 + gate:
python3 fdk/tools/graph-viz.py llmwiki/graph/<id>.graph.json→ HTML をユーザーに送り、承認を得ます(orca-workflow と同様にgate-create)。- グラフ上の node は task の kind に従って描画されます(PLAN.md の
**Kind:** build|test|fix|research|docs|design|review|security|infra|data|migrate|deploy|release|cleanup|integration|wiki。デフォルトはbuild)。icon + shape + 背景色は、engine リポジトリのengine/kind-glyphs.json(~/.orca-graph/repo/engine/)で参照します(既定のレジストリはすべての graph で共用されます。変更/追加はそのリポジトリへの PR を通じて行います)。node の枠線は引き続き state を表します(変更しません)。 - レジストリに存在しない未知の
kind→ tool が一時的に生成します(monogram + hash に基づく色/形状。~/.orca-graph/kind-glyphs.local.jsonに記録。マシンローカルで、engine の git clone を汚しません)。また、stderr に警告を出力します。この警告が表示されたら、/raise-issueで新しい glyph をkind-glyphs.jsonに提出するかどうか、ユーザーに尋ねてください。確認せずに既定のレジストリへ追加しないでください。
- グラフ上の node は task の kind に従って描画されます(PLAN.md の
- 実行ループ(
nextが完了を報告するまで繰り返します):
Agent が lease の間ずっと応答しない場合、next <id> # node ready = chạy song song NGAY; blocked = HITL, KHÔNG dispatch headless lock <id> <n> --by <agent> # O_EXCL + lease (mặc định 90 phút); heartbeat <id> <n> khi chờ lâu set <id> <n> dispatched --op-key <uuid> # rồi orca orchestration dispatch --task … --inject (brief NGUYÊN VĂN từ PLAN) set <id> <n> done --gen <gen> --op-key <uuid> # gen lấy từ output lệnh dispatched; gen cũ → STALE, không publishnextが node をunknownに戻します。その後、再度 lock する前にreconcile <id> <n>(verify を実行)します。attempt は最大 3 回です。 Orca のレジストリにもミラーリングする場合:sync-orca <id> --run(一方向。Orca のレジストリはランタイム全体で共有され、プロジェクトの印を付けます)。 - 終了:
audit <id>(各ソースを再度開く。捏造 = 0。audit-log.jsonlに記録)→graph-atlas.py llmwiki/graph/で atlas を再生成 → プロセス上の問題が明らかになった場合は problem-tree を更新します。
ブランチ
| ID | 種類 | 条件 | 動作 | スキップ/失敗 | 再合流 |
|---|---|---|---|---|---|
| B01 | user_optional | あるノードの下に子グラフを分ける必要がある | build <PLAN> --parent <gid>/<node>;すべての子ノードが完了すると親ノードが join します | depth 6 または 20 node を超えると → tool が拒否します | W03 |
| B02 | conditional_required | 既存の graph に対して build を再実行する | plan_version + 1、削除された node は superseded[] に追加、spec_hash が変更された完了済み node は fresh=stale になります | 古い plan_version の結果 → STALE | W06 |
| B03 | user_optional | user が一時停止/再開/キャンセルを希望する | control <id> pause、resume、cancel、status | cancelled は再開できません → 新しい build plan を作成します | W06 |
| B04 | capability_optional | 手入力の 4 コマンドを 1 つにまとめたい | run <id> <node> -- <lệnh agent> + daemon watch + control-room | node に verify がない場合 → headless を拒否します | W06 |
| B05 | recovery | agent が lease の期限を過ぎても応答しない | next が node を unknown に戻します → reconcile <id> <n> が verify を実行してから再度 lock します | 最大 3 attempt 後に failed | W06 |
| B06 | conditional_required | kind-glyphs.json にない未知の kind | tool が一時 glyph を kind-glyphs.local.json に生成し、stderr に警告を出します → 新しい glyph を /raise-issue するか user に確認します | デフォルトのレジストリには自動追加しません | W05 |
| B07 | user_optional | Orca のレジストリにもミラーしたい | sync-orca <id> --run(一方向) | — | W06 |
| B09 | user_optional | graph ができた後、user が作業の追加または「ノードを追加で描画」を依頼する | add-node <id> --title … [--depends t1:data] [--blocks t5] [--files …] [--verify …] [--kind …] [--resources …] → + tN を出力し、build を再実行して HTML を再描画し、link を user に渡します | cycle の生成/20 node 超過/不明な dep → tool が拒否し、PLAN はそのまま維持されます | W05 |
| B10 | recovery | lock が chờ RESOURCE を返す | 別の node が競合する claim を保持しています → 先に別の ready node に取り組み、ask <id> waiting で保持者を確認します;もう一方の node が完了したら再度 lock します | 別の agent の node を自動で unlock しません | W06 |
| B08 | conditional_required | node に **QC:** が記載されている | verify rc 0 の後に独立して QC を実行します;失敗 → done_unverified(run/set)または ready(reconcile) | 記載がない場合 → 従来の動作 | W06 |
検証と停止条件
必須事項:verify rc 0(および QC が記載されている場合は QC)でのみ done になります;lease/generation/op_key/CAS は tool が決定します;破損時は check-cycles と lint/build --strict が rc 2 を返します;audit は各ソースを再度開き、捏造は 0 です。人による対応が必要な事項:gate で HTML graph を承認すること、gợi-ý の deps を確認すること、blocked node に対処すること。next が完了を報告した時点で実行ループは停止します;各 node の attempt は最大 3 回です。
例
- 正常系: PLAN に 5 task があり、t2 と t3 が同じ Depends t1 を参照 →
buildが cycle なし、file の競合なしと報告 →ask t2 parallelが t3 を返す →nextが t1 を割り当て、完了後に t2 と t3 を並列で割り当て、それぞれにlock --by、set done --genを実行 →auditの捏造は 0 → atlas regen。 - 境界条件/失敗: t2 と t3 が並列で同じ
src/api.tsに書き込む →buildが同じ file への書き込み競合を ⚠ で出力 → t3 に**Depends:** Task 2を追加して順次実行にし、build を再実行;agent t3 が lease の期限を過ぎても応答しない →unknown→reconcileが再度 lock する前に verify を実行します。 - 境界条件: model が「release のロックを解除するために t4 が存在する」と説明しようとしたものの、開けるソースがない →
answer … --label không-biết(0.3)を使い、chắcは付けません。
参考 — 親 graph → 子 graph の階層(PRD Reprise Graph Engine §4)
build <PLAN> --parent <gid>/<node>→ 子 graph を親 graph の 1 つの node に結び付けます(包含ツリーであり、依存関係 DAG とは異なります)。親 node はchild_graphを持ち、すべての子 node が完了した場合にのみ自動的に join してdone_unverifiedになります(invariant 4);子にblockednode がある場合、親もblockedになります。- ハードリミット:depth ≤ 6、≤ 20 node/graph。超過した場合 → tool が拒否します。さらに深く掘り下げず、scope を縮小してください。
- graph をまたぐ deps:
**Depends:** other-graph/t3— 他の graph でその node が完了すると満たされます。check-cycles [dir]はすべての graph を統合し、具体的な cycle の経路(a/t2 → b/t3 → a/t2)を出力します。rc 2(PRD §5.3)。 lint <id>— leaf が十分な契約を満たしているか確認します(PRD §4.4):title · files · produces · verify · 明確な deps。verify/files が不足している場合、build --strictは rc 2 を返します。
参照 — 根拠のあるトポロジーと所有者が明確なリソース(PRD v1.1 §23)
- Depends の解析は厳格です: 解決できないトークン(
—の後に挿入された注記、Task 1 và Task 2、存在しないタスク、形式が誤ったグラフをまたぐ依存関係<gid>/<tid>)はbuildエラーになります。黙って無視されることはありません。エッジが消えて気付かないままノードが早期に ready になる事態を防ぎます。区切りには,または;を使い、注記は別の行に記載してください。 - エッジの理由:
**Depends:** Task 1 (data), other-graph/t3 (control)。必須の5つのクラス(data · contract · acceptance · effect_order · control)は、アーティファクトを渡さない場合でも省略できません。ペイロードを運ばない承認ゲートも、実際のエッジです。preferenceは記述順によるものに限られます。理由はspec_hashに含まれません。実行中のグラフに理由を付けても、完了済みノードが stale になることはありません。 audit-edges <id> [--json] [--strict]— dry-run です。検出コード:EDGE_UNJUSTIFIED(理由のない Depends の宣言 → 維持)·EDGE_INFERRED(推論された依存関係)·PREFERENCE_REMOVABLE(削除を提案)·PREFERENCE_HAS_HIDDEN_CONSTRAINT(preference と記載されていても、下流の Consumes/Verify/QC が上流の Task、ファイル、または出力に言及している、あるいは2つのノードが同じファイルを書き込む場合 → 維持。文字列を比較するため、文字列に現れない結合は検出できません)。critical path では、ノード数(unit-weight、所要時間ではありません)、クラス数、直前・直後に実行可能なノードの集合を数えます。--strictはEDGE_UNJUSTIFIEDが残っている場合に rc 2 を返します。- リソース要求: キーはツールが正規化するため(lowercase + normpath)、表記上の別名でも同じリソースとして扱われます。
lockは要求をすべて取得するか、何も取得しません(Aを保持してBを待つことはありません)。同じ store 内のすべてのグラフを確認し、単一の admission mutex の下で実行します。exclusiveは同じキーに対するすべての要求をブロックします。capacity:Nはキーの POOL サイズです。そのキーを保持している各ノード(sharedも含む)が1スロットを占有し、ノードごとに異なる N を指定した場合は最小の N が適用されます(lock の順序には依存せず、sharedでも上限を回避できません)。sharedのみの場合、ブロックされるのは exclusive がある場合またはプールが満杯の場合だけです。別のグラフで期限切れになった lease も、lock/nextの実行時に reaper が処理します(要求がグラフをまたいで停滞することはありません)。実行中のノードを手動でunlockするとunknownに戻るため、再度 lock する前に reconcile してください。並列実行されるノードの組み合わせについて、buildはℹ … cùng claimと出力します。これは情報であり、エラーではありません。 ask <id> waiting— 未実行の各ノードに理由を1つ表示します:data(上流を待機)·gate(HITL、control/acceptance ゲート、verify がまだ成功していない、または reconcile 待ちの unknown)·resource(要求が保持されている。保持者を表示)·queue(max_parallel が上限に達している)·control(pause/cancel)·retry(3 attempt を使い切った)·none。nextは、ready だが lock を取得できていないノードについても行を追加して表示します。ready と admitted は同じではありません。- トポロジーのクラス(
ask parallel)は、説明のための投影であり、制約ではありません。依存関係を満たしたノードは、同じクラスにある上流ノードが未完了でも、すぐに ready になります。
参照 — 識別、dry streak、呼び出し予算(PRD v1.1 §24–27)
reconcile-items --expected A,B,C --verdicts rows.jsonl [--universe N]— verdict(supported|refuted|inconclusive)を行の位置ではなくitem_idで照合します。{A,A,B}の3行がそろっていても C が不足しているため rc 2 を返します。verdict: nullの行、またはstatus≠ ok の行は、ID付きの outcome 不足(errored_ids)として扱われ、除外されず、refuted にも数えられません。同じ item に verdict とエラー行の両方がある場合はCONFLICTING_OUTCOMEです。manifest が空の場合は--allow-emptyが必要です。verdict ファイルがない場合はエラーであり、「0行」とは扱いません。coverageでは、完了数/選択済みと選択済み/全体の2つの分母を分けます。不明な場合はunknownとなり、100% と報告されません。アイテムの一括 fan-out(例:/tc-run)後に結果を集約する場合に使います。dry-streak --prev N --complete 0|1 --new N— discovery が dry だったラウンドとして数えるのは、ラウンドが完了し、新しい候補がなかった場合だけです。ラウンドが失敗した場合は0にリセットされます。dry は停止のヒューリスティックであり、すべてを確認し尽くした証明ではありません。cost-envelope <id> [--reviewers N] [--max-attempts N]— dispatch 前にモデルの呼び出し回数を数えます: planner 1 + worker/node afk + QC があるノード数 × reviewer + synthesis 1。max_callsは最大 retry 数を掛けた値です。実測値がない場合、expectedは unknown と記録されます。shell による Verify はトークンを0消費しますが、CPU は消費するため、別途報告します。総 call 数の代わりに「N agent」と言わないでください。
リファレンス — 履歴を壊さない再計画(PRD §10)
- 既存のグラフに対する再度の
buildはplan_version + 1になります。削除されたノードは最終状態を保持したままsuperseded[]に入ります。契約(spec_hash= title/files/deps/verify/produces)が変更された完了済みノードはfresh=staleになります(警告のみで、state は巻き戻しません)。 - 古い結果:
set done --plan-version Nの N が現在の値と異なる場合は STALE となり、publish されません(invariant 2)。 runは dispatch 時のplan_versionを記録します。エージェントの実行中に replan が発生した場合、結果は STALE となり、ノードは新しい spec に従って再実行できるようreadyに戻ります(rc ≠ 0)。add-nodeは一ノードの replan です。admission mutex 下で実行されるため、並行する 2 つのコマンドが互いを上書きすることはありません。parser と同じように PLAN を読み取ります(code fence は無視します)。すべての field は必ず 1 行に収めてください。--blocksはlocked|dispatchedのノードを拒否します。PLAN は graph と一致している必要があります(手動で編集した場合は先にbuildしてください)。新しい id に、削除済みノードの id は再利用できません。--blocks t5は新しいノードを t5 の前に挿入します(t5 の Depends 行に接続し、行がない場合は追加します)。--parentを忘れて子 graph を再度 build しても、親とのリンクは維持されます。
リファレンス — Control(PRD §8.3、invariant 11)
control <id> pause|resume|cancel|status。「要求」されたことと「停止済み」であることは異なります。pause_requestedがpausedになるのは、locked|dispatchedのノードがなくなってからです。activeでない場合、next/lockは新しいノードを割り当てません。cancelledは resume できません。新しい plan version を build してください。build --max-parallel N(デフォルトは 4):実行中のノード数が上限に達している場合、lockは拒否されます(PRD §12.1)。
リファレンス — Daemon と control-room(PRD §8.4:lease 60 s・heartbeat 15 s・reaper 15 s)
run <id> <node> [--hb 15] [--lease-sec 60] [--strict] -- <lệnh agent>— 手入力で実行していた 4 つのコマンドを置き換えます。短時間の lock → dispatched → コマンドを spawn → pid に従って heartbeat → exit 0 ならdone(verify は自動実行)、それ以外ならfailedとなります。verifyのないノードは headless で拒否されます(強制するには--allow-unverified)。ディレクトリを自動的に~/.orca-graph/registry.jsonの registry に記録し、daemon がなければ自動的に spawn します(無効にするにはORCA_GRAPH_NO_DAEMON=1、ホームディレクトリの変更にはORCA_GRAPH_HOME)。- 書き込み allow-list(GH#162): git repo 内では、
runは実際に変更されたファイルの diff(tracked の変更と新規 untracked、spawn 直前との比較)をノードで宣言されたfilesと照合します。範囲外の変更はデフォルトでは警告のみです(doneevent のnoteに記録)。--strictを指定した場合にのみ、強制的に元に戻します(新規 untracked は削除、tracked の変更はgit checkoutで HEAD に戻します)。git repo でない場合(例:store が repo の外にある場合)は自動的にスキップされ、エラーにはなりません。orca-graph 自身の bookkeeping(.graph.json/.events.jsonl/.locks/)は常に diff から除外され、「agent による書き込み」とはみなされません。 watch [--once] [--interval 5] [--idle-sec 600]— マシン全体で daemon は 1 つだけです。pid に基づきdaemon.lockでロックします。各回で、実行中のノードがある registry 内の dir だけを読み取ります(コストは実行中のノード数に比例し、開いているプロジェクト数には比例しません。Python の起動を含めても 1 回あたり 84 ms と計測)。lease の期限切れを検出した reaper はunknownにし、verify があればすぐ reconcile します。生存/停止状態の表を表示します。registry が idle-sec より長く空のままなら自動終了し、graph が変更された場合は control-room を再生成します。fdk/tools/build-control-room.py→llmwiki/html/control-room.html— 最初に開くページです。data-first で、registry、graph.json、problem-tree、tokens.jsonl、audit-log のみを読み取ります。マシン全体で何が実行中かとその上限、各 graph の進捗と停滞中のノード、未解決の負債、今日のコスト、自動評価と audit の差を表示します。5 秒ごとに自動更新されます。daemon は各回とrunの開始/終了時に再生成するため、ページを LIVE に保つのにサーバーは不要です。レベル 2(サーバー+pause/cancel ボタン)とレベル 3(Orca の組み込み)は未実装です。レベル 1 が日常的に使われ、不足が明らかになった場合にのみ実装してください。- 生存/停止状態 ≠ 正否:daemon が把握するのは process が動いているか停止しているかだけです。
doneと再実行の判断はverifyが行います。process が動いたままハングしていても heartbeat は正常を示します。ノードごとに冪等な**Verify:**と時間上限を設定してください。
参照 — 振り返り
/orca-graph = PLAN → deps を含む graph.json → ask が確定的な5つの質問に回答 → ロック/リース/世代番号を使ったレイヤー単位のディスパッチ → append-only の永続状態 → answer/audit がルーブリック 1/0/0.3/0.5/捏造=0 でモデルを採点 → 1つのグラフと2Dアトラスを含むHTML。
意外なユースケース:完了済みの古い PLAN に対して build を実行し、当時、同じファイルに書き込む2つのタスクが並列で実行されていなかったか検証し直すこと。または related を使い、新しい PLAN に着手する前に、古い PLAN のどのファイルに触れるかを確認すること。