yoi/tickets/scope-lock.md
2026-04-18 19:25:03 +09:00

4.0 KiB
Raw Blame History

Scope lock file: write 排他とスコープ分譲の記録基盤

レビュー状態

初回レビュー実施済み。scope-lock.review.md を参照。 指摘1件ファイルパーミッション 0600 の明示設定)の修正を条件に受け入れ可。

背景

Pod オーケストレーションでは scope の分譲spawner が自身の scope を spawned Pod に譲渡)が発生する。また、人間が独立に複数の Pod を起動した場合にも同一パスへの write 衝突を検出する必要がある。

これらを解決するため、マシン上の全 Pod の scope 割り当てを単一の lock fileで一元管理する。

仕様

lock file

置き場: $XDG_RUNTIME_DIR/insomnia/scope.lock

内容:

{
  "allocations": [
    {
      "name": "abc123",
      "pid": 12345,
      "socket": "/run/insomnia/.../pod-a.sock",
      "scope_allow": ["/project/src:write:recursive"],
      "delegated_from": null
    },
    {
      "name": "def456",
      "pid": 12346,
      "socket": "/run/insomnia/.../pod-b.sock",
      "scope_allow": ["/project/src/core:write:recursive"],
      "delegated_from": "abc123"
    }
  ]
}

アクセスは flock(2) による advisory lock で排他制御する。

操作

タイミング 動作
Pod 起動 lock → stale 検出PID 死活)→ 自動回収 → write 衝突チェック → 自分の scope を登録 → unlock
scope 分譲 lock → spawner の allocation に deny 追記 → 新 Pod の allocation を追加(delegated_from に spawner→ unlock
Pod 正常終了 lock → 自分の allocation を削除 → delegated_from が自分の子が残っていなければ親の deny を解除 → unlock
stale 検出 kill(pid, 0) で生存確認。死んでいたら allocation を削除し scope を delegated_from の親に返却

stale の自動回収

Pod がクラッシュした場合、lock file にエントリが残る。次に lock file を開いた Pod が stale を検出し自動回収する:

  • 死亡 Pod の scope のうち、生存中の子 Pod が持つ分を除外
  • 残りを delegated_from の親に返却
  • 死亡 Pod のエントリを削除
  • 子 Pod の delegated_from を親に付け替え

effective scope の導出

effective_scope = 自分の allocation - Σ(delegated_from が自分を指す子の allocation)

セキュリティとアクセス

  • ファイルパーミッション 0600owner only、ディレクトリは 0700。他ユーザーからの読み取りを防ぐ
  • ownerPod を動かしているユーザーは当然読める。JSON なので直接確認も可能
  • Pod による lock file 探索は排他制御の目的に限定する。Pod 発見のための lock file スキャンは行わないPod の発見は spawn 記録 + 明示的な紹介のみ)
  • 衝突で Pod 起動が拒否されたとき、競合相手の name をエラーメッセージに含める

実装

  • 新規モジュール crates/pod/src/scope_lock.rs(または crates/scope-lock/
  • Pod 起動時(Pod::from_manifest / Pod::from_manifest_toml)に lock 取得
  • Pod 終了時(Drop または明示的 releaseに lock 解放
  • Controller 層でのエラー伝搬

完了条件

  • Pod 起動時に scope lock file に allocation が記録される
  • 同一パスへの write 衝突が検出され、Pod 起動が拒否される(競合相手の name がエラーに含まれる)
  • Pod 正常終了時に allocation が削除される
  • stale エントリPID 死亡が自動回収され、scope が親に戻る
  • 分譲チェーンA→B→Dの部分回収が正しく動作する
  • 単体テストで衝突検出・stale 回収・分譲/返却が検証される

範囲外

  • SpawnPod ツール自体の実装(tickets/spawn-pod-tool.md
  • scope の分譲粒度permission レベルでの分譲等)は当面パス単位のみ