# Issue #7: フィールドベース依存関係設計（改訂版）

## 背景

現在の DAG ワークフローでは、ノード間のデータ依存が暗黙的であり、
YAML の遷移グラフを変更しても整合性が検証されない問題がある。

**目標:**
> 遷移グラフ（YAML）を変更して sync すれば、ノードのコードを変更せずにワークフローを変更できる

## 設計原則

### 関心の分離

| 役割 | 責務 | 知る必要があること |
|------|------|------------------|
| **ノード実装者** | `@node` で依存を宣言 | ノードが必要とするフィールド |
| **YAML 記述者** | 遷移を定義 | **ノード名と Outcome のみ** |
| **フレームワーク** | 依存の自動検証 | 両方を読み取って検証 |

### ノード実装者の責務

```python
@node(
    requires=["incident_id"],           # 必須フィールド
    optional=["hostname"],              # オプションフィールド
    provides=["escalated", "notified"], # 追加するフィールド
)
def escalate(ctx: WorkflowContext) -> tuple[WorkflowContext, Outcome]:
    if ctx.hostname:  # optional なので存在チェック
        notify_with_host(ctx.hostname)
    return ctx.model_copy(update={"escalated": True}), Outcome.success("done")
```

### YAML 記述者の責務

```yaml
# YAML には依存関係を書かない！
# ノード名と遷移のみを記述

nodes:
  check_severity:
    description: "重要度をチェック"
  check_host:
    description: "ホスト情報を取得"
  escalate:
    description: "エスカレーション"

start: check_severity

transitions:
  check_severity:
    success::critical: check_host
    success::normal: escalate      # ← フレームワークが自動検証
  check_host:
    success::found: escalate
```

### フレームワークの責務

`railway sync transition` 実行時:

1. **ノードコードを読み込み**: 各ノードの `_field_dependency` を取得
2. **遷移グラフを解析**: 開始ノードから終端ノードまでの全経路を探索
3. **依存関係を検証**: 各遷移で `requires` が満たされるか確認
4. **エラー報告**: 不整合があれば分かりやすく報告

```
$ railway sync transition --entry alert_workflow

❌ 依存関係エラー: 遷移 'check_severity → escalate' が無効です

  escalate が必要とするフィールド:
    requires: [incident_id]  ✅ 利用可能
    optional: [hostname]     ⚠️ 利用不可（check_host をスキップしたため）

  提案:
    - escalate の optional から hostname を使用する処理を確認してください
    - または check_host を経由する遷移に変更してください
```

## Issue 一覧

| # | タイトル | 概要 |
|---|----------|------|
| 50 | ADR-006: フィールドベース依存関係 | 設計決定を文書化 |
| 51 | FieldDependency 型システム | requires/provides/optional の基盤 |
| 52 | Node 依存宣言拡張 | `@node` デコレータの依存宣言サポート |
| 53 | 依存情報の自動抽出 | ノードコードから依存情報を読み取る + **初期フィールド自動導出** |
| 54 | 遷移グラフ依存バリデータ | 全経路の依存関係を検証 + **Contract 整合性チェック** |
| 55 | Codegen 依存対応 | コード生成の更新 |
| 56 | Runner 依存チェック | 実行時の依存検証（オプション） + **provides 違反警告** |
| 57 | ドキュメント更新 | ARCHITECTURE.md, TUTORIAL.md, readme.md |
| 58 | マイグレーションツール | `railway update` による自動変換 |

**レビュー 3 での追加:**
- Issue #53: 開始ノードの Contract から初期フィールドを自動導出
- Issue #54: requires と Contract フィールドの整合性チェック
- Issue #56: provides 宣言したのに設定しない場合の警告オプション

## 実装順序

```
50 (ADR)
   ↓
51 (FieldDependency 型システム)
   ↓
52 (Node 依存宣言)
   ↓
53 (依存情報の自動抽出)
   ↓
54 (遷移グラフ依存バリデータ) ← 最重要
   ↓
55 (Codegen) → 56 (Runner)
   ↓
57 (ドキュメント)
   ↓
58 (マイグレーション)
```

## ワークフロー変更の例

### 例1: ノード削除（YAML のみ変更）

**Before:**
```yaml
transitions:
  check_severity:
    success::critical: check_host
  check_host:
    success::found: escalate
```

**After（check_host 削除）:**
```yaml
transitions:
  check_severity:
    success::critical: escalate
```

**フレームワークの検証:**
- `escalate.requires = [incident_id]` → ✅ 開始時に存在
- `escalate.optional = [hostname]` → ⚠️ 利用不可（警告のみ）
- **結果: sync 成功**（optional なので問題なし）

### 例2: ノード順序変更（YAML のみ変更）

**Before:**
```yaml
transitions:
  start:
    success::next: process_a
  process_a:
    success::next: process_b
```

**After（順序入れ替え）:**
```yaml
transitions:
  start:
    success::next: process_b
  process_b:
    success::next: process_a
```

**フレームワークの検証:**
- `process_b.requires` が開始時点で満たされるか確認
- `process_a.requires` が `process_b.provides` + 開始時点で満たされるか確認
- **結果: 依存が満たされれば sync 成功**

### 例3: 依存エラー（sync で検出）

```yaml
transitions:
  start:
    success::next: send_notification  # hostname が必要だが、まだ存在しない
```

```
$ railway sync transition --entry workflow

❌ 依存関係エラー: 遷移 'start → send_notification' が無効です

  send_notification が必要とするフィールド:
    requires: [hostname]  ❌ 利用不可

  この時点で利用可能なフィールド:
    [incident_id, severity]

  提案:
    - check_host を先に実行する遷移に変更してください
    - または send_notification の requires から hostname を削除してください
```

## 設計原則

1. **関心の分離**: YAML 記述者はノードの実装詳細を知る必要がない
2. **TDD**: すべての変更はテストファーストで実装
3. **関数型パラダイム**: 純粋関数、イミュータブル、副作用の分離
4. **後方互換なし**: 理想の実装を優先（マイグレーションツールで対応）

## 完了条件

- [ ] すべての Issue が完了
- [ ] 全テスト通過
- [ ] **YAML 記述者がノードの依存を知らなくてもワークフロー変更可能**
- [ ] sync 時に依存エラーが分かりやすく報告される
- [ ] ドキュメント更新完了
- [ ] `railway update` でレガシープロジェクトが自動変換される
