アーキテクチャ / Decision DAG

Decision DAG

タスクではなく「意思決定」をルーティングする。各ノードは所有権・証拠要件・承認ゲートを持つ。

ノードは「意思決定」

軍師OSは、業務を有向非巡回グラフ(DAG)として表します。ただしノードは単なるタスクではなく、所有権・必要証拠・承認ゲートを持つ意思決定です。各ノードは次の状態を取ります:

PENDING → RUNNING → DONE (ゲートを満たした場合)
PENDING → BLOCKED (ゲートを満たさない場合)

ゲート述語(既定は拒否)

ノード v が実行に進めるのは、次がすべて真のときだけです。ひとつでも欠ければ BLOCKED に落ちます。

allow(v) ⇔ deps_done(v) ∧ ( required_evidence(v) ⊆ provided(v) ) ∧ approver_ok(v)

approver_ok は、ノードのリスク階層が要求する承認者(R1–R5)が揃っているか。R1 は自動、R3 以上は人間承認が必須です。

LTL 安全性質(最後の砦)

ゲートとは独立に、線形時相論理(LTL)の不変条件を実装の assertion として持ちます。これは「高リスクの意思決定は、人間承認なしに完了状態へ到達してはならない」を意味します:

□ ( risk(v) ≥ R3 → ¬ ( DONE(v) ∧ ¬ HumanApproved(v) ) )

万一ゲートのロジックが緩く改変されても、この不変条件が SafetyViolation を送出して実行を止めます(defense in depth)。

実装(抜粋)

# dag.py — ゲート述語 def _gate(self, n): if not all(self.state[d] == "DONE" for d in n.deps): return False, "deps_incomplete" if not n.required_evidence <= self.evidence[n.id]: return False, "evidence_missing" tier = tier_for(n.risk) if tier.approver != "auto" and tier.approver not in self.approvals[n.id]: return False, f"needs_{tier.approver}_approval" return True, "ok"

カスケード停止

実行はトポロジカル順(O(V+E))。上流ノードが BLOCKED なら、それに依存する下流は deps_done を満たせず連鎖的に止まります。「上流が未承認なら下流は走らない」が構造として保証されます。

この挙動は 実証ページ の試行A/Bで実際に確認できます(証拠・承認なし→close_deal が BLOCKED、付与後→全ノード DONE)。