# 環境構築手順 (Environment Setup)

## 前提ツール (Prerequisites)

| ツール | 用途 | 備考 |
| --- | --- | --- |
| git | バージョン管理 | 運用は `.claude/rules/git-conventions.md` |
| gh | GitHub CLI | PR 作成・リポジトリ設定 |
| uv | Python・依存管理 | `winget install astral-sh.uv` |
| Python 3.7 以上 ＋ bash | `.claude/hooks/` の実行 | Windows は Git for Windows 付属の bash．※ Python が見つからないとアクセス制限フックが全ツールをブロックする |
| OpenSSH | サーバ接続 | Windows 11 標準（`C:\Windows\System32\OpenSSH\ssh.exe`） |

## 手元 PC のセットアップ (Local Setup)

```bash
git clone https://github.com/rintoHasegawa/TIASJudgeModel.git
cd TIASJudgeModel
uv sync
```

手元には **CPU 版の PyTorch** が入る（[ENV_01「CPU / GPU の依存差」](ENV_01_技術スタック.md)）．学習は回さず，実装と合成データでの動作確認に使う．

## 臨床データの取り扱い (Clinical Data Handling)

**手元 PC に臨床データを置かない．** これは手順ではなく守るべき制約である．

- 実データは研究室 PC が原本，学習用のコピーは Newton の `~/data/TIASJudgeModel/`（[ENV_03](ENV_03_管理者用環境構築手順.md)）
- 手元へ回収するのは非個人情報の派生物のみ（指標・学習曲線・混同行列・ログ・モデル重み）
- 画像・ラベル・患者 ID を含むファイルは回収しない
- `data/`・`runs/` は `.gitignore` 済み

## 合成データでの動作確認 (Synthetic Data)

実データが無い手元で学習パイプラインを流すため，合成データ生成スクリプトを使う（実装フェーズで作成）．

- 出力先: `data/synthetic/`（`.gitignore` 対象）
- 目的は「落ちずに 1 エポック回り，指標が書き出される」ことの確認であり，精度は意味を持たない

## 研究室サーバの利用 (Lab Server)

| Host 名 | アドレス | 用途 |
| --- | --- | --- |
| `Newton` | `192.168.23.14`（研究室 LAN 内．`Newton.local`） | 学習の実行．RTX A6000×3・Ubuntu 22.04・uv |
| `Archimedes` | `192.168.23.15`（研究室 LAN 内） | 学習の実行．RTX A6000×2・Ubuntu 22.04・uv（2026-09-27 導入）．**`/home` の空きが少ない**（2026-09-27 時点で使用率 97%・空き 64 GB） |
| 踏み台 `labpc` | 研究室 PC（Tailscale 経由） | 学外から接続する場合は `-J labpc` を付ける |

- どちらのサーバを使うかはリモート実行ツールが空き GPU から自動で選ぶ（[SPEC_03](../04_SPEC/SPEC_03_リモート実行仕様.md)．Newton 優先）
- `Newton-via-lab` のような別名は `~/.ssh/config` で定義しているが，Archimedes には別名が無い．リモート実行ツールはアドレスと `-J labpc` で直接指定するため別名に依存しない

- SSH の鍵と `~/.ssh/config` は **SmTIAS-LightSim で構築済みのものを流用する**（設定手順は同プロジェクトの `docs/02_ENV/ENV_02_環境構築手順.md`「研究室サーバ編」を参照）
- **サーバ上では編集しない**．コードは常に手元から送る（次節）
- サーバに GitHub の認証情報を置かない

## 日常の流れ (Daily Workflow)

リモート実行ツール `tias-remote` を使う（コマンドは [ENV_04](ENV_04_開発コマンド.md)「リモート実行」，仕様は [SPEC_03](../04_SPEC/SPEC_03_リモート実行仕様.md)）．

1. 手元でコードを編集する
2. `uv run tias-remote gpus` で空き状況を見る（任意）
3. `uv run tias-remote run --name <ジョブ名> -- <コマンド>` で起動する（空いている GPU を両サーバから自動で選び，コードを送ってから tmux で起動する）
4. `uv run tias-remote logs <ジョブ名>` で様子を見る
5. `uv run tias-remote pull <実験ID>` で結果（指標・図・ログ）を持ち帰る

## 環境再現性のルール (Reproducibility Rules)

- 依存の追加は `uv add`．`uv.lock` はコミットする
- 絶対パスをコードにハードコードしない（設定 YAML と環境変数で渡す）
- 乱数シードを設定ファイルで固定し，`runs/<実験ID>/config.yaml` に実際に使った設定を保存する

## トラブルシューティング (Troubleshooting)

| 症状 | 原因 | 対処 |
| --- | --- | --- |
| サーバで `torch.cuda.is_available()` が `False` | CPU 版 wheel が入った | ENV_01「CPU / GPU の依存差」に従い `[tool.uv.sources]` で PyTorch の CUDA インデックスを指定する |
| `ssh Newton 'cat ...'` が応答せず止まる | 標準入力が開いたまま（LightSim で実測） | `ssh -n` を付ける |
| 学外からの転送が遅い | Tailscale が DERP 中継経由になっている | `tailscale ping` で経路を確認し，転送は差分だけにする |
| ファイル操作系のツールが全てブロックされる | フック用の Python が見つからない | `python3` / `python` / `py` のいずれかが起動できるようにする |
| サーバで `uv: command not found` | 非対話 ssh の PATH に `~/.local/bin` が入らない | コマンドの前に `export PATH="$HOME/.local/bin:$PATH"` を付ける（リモート実行ツールもこれを行う） |
| `tias-remote` で「接続不可（Host key verification failed）」 | 手元の `known_hosts` にそのサーバの **IP アドレスのホスト鍵**が無い（別名 `newton.local` 等でしか接続したことが無い） | 一度 `ssh -J labpc hasegawa@<IP> exit` を実行して登録する．既存の別名の鍵と同じかを `ssh-keygen -lF <IP>` と `ssh-keygen -lF <別名>` の指紋で確かめる |
| 踏み台経由で `connect failed`（ホスト名不明） | 踏み台側の mDNS（`Newton.local`）の解決が一時的に失敗する | 時間をおいて再試行する．頻発する場合は踏み台の `~/.ssh/config` で Newton を IP 指定にする |
