# 開発進捗ログ

<!--
本ファイルは追記型のフル進捗ログ．

- 最新エントリは下に追記する（時系列順．古いものが上，新しいものが下）
- CLAUDE.md の「開発進捗」セクションは最新 1 行のみ（上書き運用）
- 詳細・失敗パターン・設計判断はすべて本ファイルに残す
- 書式・運用ルールは .claude/rules/progress-log.md を参照
  （本ファイルの編集時に自動ロードされる）
-->

## 立ち上げ（フェーズ 1: 方針決定）

- [x] **プロジェクト方針の確定と要件定義書の作成**: TIASjudge（ルールベースの舌診支援アプリ）の舌色 5 分類を機械学習で推定する研究プロジェクトとして，目的・スコープ・成功基準を確定し [PLAN_01 要件定義書](03_PLAN/PLAN_01_要件定義書.md) を作成した．開発モードは solo．
  - 前提（データ取り扱い）: 臨床データは手元 PC に置かない．原本は研究室 PC に保管し，研究室 LAN 内で計算サーバへ一度だけコピーする．手元へ持ち帰るのは非個人情報の派生物（集計指標・ログ・モデル重み）のみ．リモート実行の構成は SmTIAS-LightSim の方式（コードを手元から送り，結果を回収）を踏襲する
  - 設計判断: 本フェーズのゴールを「現状把握」とし精度の絶対値目標を置かない．評価は**患者単位分割を必須**とし（画像単位のランダム分割は同一患者が train / test に跨り過大評価になる），既存ルールベースを同一テストセットのベースラインとして並べて比較する
  - スコープ外: セグメンテーションの学習・5 分類以外の所見・TIASjudge への組み込み実装・撮影条件の色補正
  - 未確定: 画像枚数・患者数・クラス分布・ラベル形式・患者 ID の追跡可否は研究室 PC で実データを確認して確定する

## 立ち上げ（フェーズ 2〜3: 技術選定・環境構築）

- [x] **技術スタックの確定**: PyTorch ＋ timm・uv・YAML ＋ pydantic・リモート実行は SmTIAS-LightSim の `sm-remote` 移植，実験記録は軽量自作，CI なしと決め [ENV_01](02_ENV/ENV_01_技術スタック.md) を作成した．
  - 設計判断: 実験管理に W&B・MLflow を採らず自作にしたのは，臨床データ由来の指標を外部サービスへ送らない方針と，実験数に対する運用コストの釣り合いから
- [x] **環境構築**: GitHub private リポジトリを作成し Dependabot alerts / security updates を有効化（検証済み）．`.github/dependabot.yml`（`uv` ＋ `github-actions`）・`.gitignore` 更新（`data/`・`runs/`・重み）・`pyproject.toml`（Python 3.12）・パッケージ骨組み・README を作成し，[ENV_02](02_ENV/ENV_02_環境構築手順.md)〜[ENV_04](02_ENV/ENV_04_開発コマンド.md) を整備した．Newton に `~/work/TIASJudgeModel` と `~/data/TIASJudgeModel`（700）を作り，コードを tar over ssh で送って `uv sync` を通し **torch 2.14.0+cu130・CUDA 有効・GPU 3 台**を確認した．
  - 確認できたこと: Linux では PyPI の wheel がそのまま CUDA 版で入る（ENV_01 の想定どおりで `[tool.uv.sources]` での対処は不要）．GPU は 3 台のうち 1 台が他ユーザー使用中で，共用前提の GPU 指定が必要
  - 失敗パターン: ① 手元の `uv sync` が PyPI からのダウンロードで connection reset（`safetensors`）→ 再試行中 / ② 非対話 ssh では `uv` が PATH に無く `command not found`（`export PATH="$HOME/.local/bin:$PATH"` が必要）/ ③ 踏み台経由で `Newton.local` の名前解決が一時的に失敗（再試行で復帰）．② ③ は ENV_02 のトラブルシューティングに記録した
  - 未実施: push・PR，臨床データの初回コピー（研究室 PC → Newton），倫理審査・データ利用許諾の確認．仕様設計（フェーズ 4）はドラフトを提示済みで保存保留

## 立ち上げ（フェーズ 4〜6: 仕様設計・規約整備・開発計画）

- [x] **仕様設計**: [SPEC_01 アーキテクチャ設計](04_SPEC/SPEC_01_アーキテクチャ設計.md)と [SPEC_02 学習・評価仕様](04_SPEC/SPEC_02_学習・評価仕様.md)を作成した．
  - 設計判断 ①: 手元へ持ち帰れるものを**回収ホワイトリスト**として仕様に固定した（画像・manifest・個票は回収しない）．「回収しないよう気を付ける」では守れないため，ツールの制約として実装しテストで固定する
  - 設計判断 ②: `manifest.csv` を学習の唯一の入口とし，`patient_id` を必須にした．取得できない場合に画像 ID を患者 ID と見なす代替はしない（同一患者が分割を跨ぐと評価が壊れる）
  - 設計判断 ③: **色を変えるデータ拡張を既定で禁止**した．舌の色そのものが正解ラベルであり，color jitter 等はラベルを壊す
  - 設計判断 ④: クラス ID を固定表（0=淡白 … 4=紫）にして混同行列の軸をぶらさないようにした
- [x] **規約整備**: `.claude/rules/` に coding-style・project-structure・testing・error-handling を作成し（path-scoped rule），`pyproject.toml` に ruff の選択ルールと pytest の `slow` マーカーを追加した．CLAUDE.md の必須ルール欄にプロジェクト固有の制約（データの持ち出し禁止・患者単位分割・色拡張の禁止等）を明記した．
  - 方針: 書式・命名・docstring 等の標準部分は SmTIAS-LightSim と同一にし，本プロジェクト固有の規則（臨床データの扱い・個人情報を含むログの禁止・データ整合性の fail fast）だけを追加した
- [x] **開発計画**: [PLAN_02 開発ステップ](03_PLAN/PLAN_02_開発ステップ.md)を作成した（Step 1 基盤 → 2 リモート実行 → 3 データセット集計 → 4 学習最小版 → 5 評価 → 6 ベースライン比較 → 7 実験反復 → 8 結論）．
  - 順序の理由: Step 1・2 は手元で完結しデータのコピー待ちの間に進められる．実データの素性が判明する Step 3 の後に SPEC を更新してから学習に入る

## データセット構成の調査（Step 3 の前倒し分）

- [x] **研究室 PC 上の実データの構成を調査し，仕様に反映**: 画像本体とファイル名を手元に持ち出さず，フォルダ名・件数・画像メタデータ・画素値の集計のみを取得した（記録は [TEST_01](06_TEST/TEST_01_データセット構成調査.md)）．
  - 判明したこと: 9 フォルダ（`<クラス>＿あり` / `<クラス>＿ややあり`，淡紅は「（正常）」のみ）に PNG 計 1085 枚．5 クラス集約で 暗赤紅 380・淡紅 337・紫 145・紅 119・淡白 104（不均衡 3.7 倍）．全画像 `Format24bppRgb`（アルファなし）で**マスク外は黒 (0,0,0)**．サイズは幅 449〜900・高さ 279〜1025 でばらばら（舌領域のバウンディングボックス切り出し）
  - 確定した設計: 程度（あり / ややあり）は manifest の `severity` 列として保持し，**学習は 5 クラス**（9 クラスは最小 51 枚・不均衡 6.6 倍で不利）．評価では `severity` 別の層別 recall を見る．リサイズの余白は背景と同じ黒で埋める．クラス表示名は元データに合わせ「暗赤紅」に修正
  - 分割の前提: **1 患者 1 枚**とユーザーが確認したため画像単位＝患者単位となる．ただし実装は `patient_id` 単位で分割し，将来複数枚が入っても壊れないようにする（前提が変わった時に patient_id を実 ID へ入れ直す）
  - 転送方式の判断: 日本語フォルダ名をそのまま scp すると CP932 と UTF-8 の差で名前が壊れるため，`<label>_<severity>` の ASCII スラッグへ対応付けてコピーする手順を ENV_03 に記載した
  - 運用上の発見: 研究室 PC は「ドキュメント」が OneDrive（大学テナント）にリダイレクトされているため，臨床データをそこに置くとクラウドへ同期される．プロファイル直下の独自フォルダ（`clinical-data`）を使う方針を ENV_03 に明記した
  - 調査の技術メモ: 研究室 PC の PowerShell 出力は CP932 で返るため取得側で UTF-8 変換が必要．複雑なスクリプトは `-EncodedCommand`（UTF-16LE + Base64）で渡すと引用符の問題を回避できる

