# Issue #17: py.typed マーカー追加

## 優先度: 高

## 概要

Railway Frameworkは「型安全なパイプライン」をうたっているが、`py.typed`マーカーファイルが存在しないため、mypyによる静的型チェックが機能しない。これは型安全をコア価値とするフレームワークとして致命的な欠陥である。

## 現状の問題

### 症状
```bash
$ mypy src/
error: Skipping analyzing "railway": module is installed, but missing library stubs or py.typed marker
```

### 影響
- チュートリアル Step 7「安全なリファクタリング」でmypyを使用する指示があるが、実際には動作しない
- IDE（VSCode/PyCharm）での型チェック機能が制限される
- ユーザーがrailwayの型情報を利用できない

## 期待する動作

```bash
$ mypy src/
Success: no issues found
```

railwayパッケージをインポートした際、全ての型情報が正しく解決される。

## 実装計画

### 1. py.typed マーカー追加

**作成ファイル**: `railway/py.typed`

```
# Marker file for PEP 561
# This package supports type checking
```

### 2. pyproject.toml 確認

現在の設定（hatchling使用）:
```toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["railway"]
```

**注意**: hatchlingはデフォルトでpackages内の全ファイルを含めるため、`py.typed`をrailway/に配置するだけでOK。追加設定は不要。

また、pyproject.tomlには既に`"Typing :: Typed"`classifierがあるが、**実際のpy.typedファイルが存在しない**ことが問題。

### 3. 型アノテーション確認

以下のモジュールで型アノテーションが適切か確認:

- `railway/__init__.py` - エクスポートの型定義
- `railway/core/contract.py` - Contract, Params, Tagged
- `railway/core/node.py` - @node デコレータ
- `railway/core/resolver.py` - typed_pipeline, DependencyResolver
- `railway/core/pipeline.py` - pipeline, async_pipeline

### 4. テスト追加

```python
# tests/unit/test_typing.py
import subprocess
import sys
import tempfile
from pathlib import Path

def test_railway_is_typed_package():
    """Verify py.typed marker exists."""
    import railway
    package_dir = Path(railway.__file__).parent
    assert (package_dir / "py.typed").exists(), "py.typed marker not found"

def test_mypy_can_import_railway():
    """Verify mypy can type-check code importing railway."""
    with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as f:
        f.write("from railway import Contract, node, typed_pipeline\n")
        f.write("class MyResult(Contract):\n")
        f.write("    value: int\n")
        f.flush()

        result = subprocess.run(
            [sys.executable, "-m", "mypy", f.name],
            capture_output=True,
            text=True,
        )
        assert result.returncode == 0, f"mypy errors:\n{result.stdout}"
```

**注意**: `--strict`は初期段階では使用せず、基本的な型解決のみ確認。strictモードは将来的な改善目標。

## 受け入れ条件

- [ ] `railway/py.typed` ファイルが存在する
- [ ] `pip install railway-framework` 後、`py.typed` がインストールされる
- [ ] `mypy` でrailwayをインポートしたコードを型チェック可能
- [ ] チュートリアル Step 7 が実際に動作する
- [ ] CI/CDでmypyチェックが通過する

## 関連

- PEP 561: Distributing and Packaging Type Information
- チュートリアル Step 7: 安全なリファクタリング
- レビュー3（2026-01-19）スコア: 型安全性 6/10

## 参考資料

- https://peps.python.org/pep-0561/
- https://mypy.readthedocs.io/en/stable/installed_packages.html
