CR-NEXUS-023: Multi-Runner / 同時 Resume / 競合整合性契約定義

(Concurrency / Locking / Consistency Contract)

SRS Traceability

Related SRS: docs/srs/NEXUSCORE_SRS.md

This CR satisfies: FR-1; FR-8; NFR-1; NFR-9

1. 概要(Overview)

本 CR は、NexusCore が 複数 Runner(Multi-Runner)環境で動作する場合における、

  • 同一 run_id に対する 同時 Resume
  • RunState の 競合更新
  • ロック・排他制御の 責務と正本

を 契約(Contract)として定義する。

目的:

  • 「どの Runner が正しいか」で揉めない設計にする
  • 同じ Run を 2台の Runner が同時に再開する事故を制度的に防ぐ
  • 分散・並列化を 安全に可能にする前提条件を固定する

本 CR は 設計契約のみであり、

  • ロック実装方式(FS / DB / Redis 等)
  • 分散アルゴリズム
  • 性能最適化

は要求しない。

2. 背景(Background)

CR-NEXUS-017〜022 により、以下はすでに確立している。

  • RunState は Resume の唯一の SOT(CR-017)
  • RunState の完全性は Runner が検証(CR-022)
  • 状態遷移の正本は Runner(CR-019)
  • 外部 I/O はイベントのみ(CR-021)

しかし、Runner が1つとは限らない状況では次の問題が発生する。

  • 同じ run_id を 2つの Runner が同時に Resume
  • 状態更新の競合(上書き・ロスト)
  • どちらが「正しく再開したか」不明

これを防ぐため、競合時に何が正しいかを“コードではなく契約”で固定する。

3. 基本原則(Concurrency Principles)

  • 同一 run_id は 同時に1つの Runner のみが実行可能
  • 競合解決の正本は Runner
  • Orchestrator は並行性・競合を一切扱わない
  • ロックは Resume / 状態遷移の境界でのみ必要

4. 競合シナリオの定義

本 CR が対象とする競合は以下。

4.1 同時 Resume

Runner A と Runner B が同一 run_id に対して Resume を要求

4.2 状態更新競合

RUNNING / RESUMING 中に別 Runner が状態を書き換えようとする

4.3 再試行競合

Resume 失敗後、複数 Runner が再試行を行う

5. 排他(Lock)契約モデル

5.1 排他の抽象モデル

本 CR は、以下の 抽象契約のみを定義する。

  • Resume 開始前に 排他権の取得を試行する
  • 排他権を取得できなかった Runner は 実行を開始してはならない
  • 排他権は run_id 単位で管理される

※ 実装方式は未確定。

5.2 排他の有効期間

  • 排他権は RUNNING / RESUMING の間のみ有効
  • 状態が Terminal(SUCCEEDED / FAILED / ABORTED / EXPIRED)に遷移した時点で解放される
  • 異常終了時の解放方法は実装・運用に委ねる(本 CR 外)

6. 競合発生時の正規挙動

6.1 Resume 競合時

  • 先に排他権を取得した Runner のみが Resume を継続
  • 他 Runner は以下のいずれかを行うことが望ましい:
    • Resume を中断
    • 状態を再読込して待機
    • 利用者に「既に実行中」である旨を通知

6.2 状態更新競合時

  • Runner は 自身が排他権保持者である場合のみ RunState を更新してよい
  • 排他権を持たない Runner による更新は 不正更新とみなす

7. Status / Explainability との整合

競合により Resume できなかった場合:

  • status を FAILED にする必要はない
  • Explainability 上は「競合による再開不可」と説明可能
  • 競合は エラーではなく設計上の事象として扱う

8. Trust Boundary との関係(CR-022)

  • 排他権の有無は Runner 内でのみ信頼される
  • 外部(API / Web)からの「自分が実行者だ」という主張は信頼しない
  • 排他情報の改ざん検知は CR-022 の完全性モデルに従う

9. 禁止事項(Hard Constraints)

  • 同一 run_id を複数 Runner が同時に RUNNING にすること
  • Orchestrator にロック・排他責務を持たせること
  • 排他権なしで RunState を更新すること
  • 外部入力で排他状態を指定すること

10. 非目標(Explicit Non-Goals)

本 CR は以下を目的としない。

  • ロック実装方式の決定
  • 分散ロックの可用性設計
  • フェイルオーバー戦略
  • パフォーマンス保証

11. 非機能要件(NFR)

  • 競合が発生しても RunState が破壊されない
  • 同時 Resume により 二重実行が起きない
  • core/orchestrator.py 無変更を前提とする

12. リスク・制約

  • 排他が導入されない実装では並行 Resume は防げない
  • ただし 契約があることで破壊的実装を防止できる

13. 完了条件(Done Definition)

  • 同時 Resume / Multi-Runner 競合が契約として定義されている
  • 排他権の責務主体(Runner)が固定されている
  • 競合時の正規挙動が明文化されている
  • CR-NEXUS-016〜022 と矛盾しない

14. 備考(Contract Layer の完成)

本 CR により、NexusCore の Contract Layer は以下を満たす。

  • 単一実行でも安全
  • 複数 Runner でも破綻しない
  • 分散・並行化に進める

これで Contract Layer は論理的に完全に閉じる。


Cursor に対する指示書(CR-NEXUS-023 用)

以下を そのまま Cursor に貼り付けて使用してください。

#project: NexusCore

Task: docs/spec/CR-NEXUS-023_Multi_Runner_Concurrency_Contract.md を新規追加する(docs-only)。

Scope:

  • Multi-Runner / 同時 Resume / 競合整合性の契約定義のみ
  • 実装コードには一切触れない

Rules:

  • docs/spec/ 配下に配置
  • CR タイトル・章立て・番号は変更しない
  • 冒頭に以下の SRS Traceability を必ず含める

SRS Traceability:

  • Related SRS: docs/srs/NEXUSCORE_SRS.md
  • This CR satisfies: FR-1; FR-8; NFR-1; NFR-9

Constraints:

  • 排他・競合の正本は Runner と明記する
  • Orchestrator に競合責務を持たせない
  • ロック方式は未確定とする
  • RunState は CR-NEXUS-020 を前提とする
  • Explainability は CR-NEXUS-018 と整合させる
  • TODO や実装提案を追加しない
  • core/orchestrator.py 無変更前提

Acceptance:

  • 同時 Resume の競合モデルが明文化されている
  • 排他権の概念と有効期間が定義されている
  • CR-NEXUS-016〜022 と整合している

This site uses Just the Docs, a documentation theme for Jekyll.