# codex レビュー結果 R1：学習と checkpoint の由来（2026-11-01 依頼 54）

依頼文: docs/review_request_20261101_train_provenance.md（codex exec -s read-only）

**判定：必須5件、推奨4件です。** Pod削除より前に由来処理が入る経路は見当たりませんが、通知の遅延と、由来を誤って記録する経路があります。

| 項目 | 判定 | 確認結果・修正案 |
|---|---|---|
| 由来処理全体の時間制限 | **必須** | [lab_train.sh:201](/Users/shimazueiichi/r2r2r-scripts/lab_train.sh:201) の300秒制限はPythonだけです。その後のHFアップロードには別途600秒あり、通知は合計約900秒＋終了待機分、遅れる可能性があります。`prov_spec`も制限外です。**spec生成・書込み・HF追加を含む全体**を300秒以内にし、失敗結果だけ親へ返す構成にしてください。 |
| `HFUP same`で過去の由来を取り込む | **必須** | [lab_train.sh:412](/Users/shimazueiichi/r2r2r-scripts/lab_train.sh:412) のダウンロードは、HFにある過去の`train_provenance.json`も取得します。比較からは除外されるため配置は成功し、今回の由来は`O_EXCL`で書けません。結果、**lab側は今回、checkpoint側は過去の由来**になります。ダウンロード対象から除外するか、今回作った一時フォルダ内で除去してください。既存1499には触れません。現行fakeはこのファイルを再現していません。 |
| 学習完了後の一覧取得失敗 | **必須** | [lab_train.sh:465](/Users/shimazueiichi/r2r2r-scripts/lab_train.sh:465) から`wrap_fail list`へ進むと、学習は完了済みでも`status.process=failed`になります。完了を検出した時点で記録し、その後の一覧取得・保存・削除の失敗では`completed`を維持して`error`へ追記してください。 |
| `--stop`時の学習設定 | **必須** | [lab_train.sh:516](/Users/shimazueiichi/r2r2r-scripts/lab_train.sh:516) ではGPU・時刻・EXPは復元しますが、STEPS・INIT・上限などは停止コマンドの既定値です。例えば`--steps 100`で開始し、`--stop`すると由来には1500と残ります。開始時の設定をSTATEへ保存して復元し、復元できない項目は不明として記録してください。 |
| openpiの部分取得をclean扱いする | **必須** | [lab_train.sh:658](/Users/shimazueiichi/r2r2r-scripts/lab_train.sh:658) はSSH終了コードを確認せず、コミット行だけあれば成功扱いします。コミット取得後に切断、または`git status`が失敗すると`dirty=false`になり得ます。リモート側でstatusの成功を確認し、最後の完了マーカーとSSH終了コードの両方を確認してください。不完全なら`dirty=null`とエラーを残します。 |
| コード・入力を測定する時点 | **推奨** | [lab_train.sh:201](/Users/shimazueiichi/r2r2r-scripts/lab_train.sh:201) では終了時のローカルコード・入力を測ります。学習中に編集すると、実際に送ったコードとは異なる由来になります。コードは実行開始／転送時、入力は利用前に測定して保持し、終了時は結果と費用を加える構成を推奨します。 |
| `.DS_Store`と由来自身の指紋 | **推奨** | [provenance.py:62](/Users/shimazueiichi/r2r2r-scripts/provenance.py:62) は仕様どおり`.DS_Store`を数えます。Finder操作だけでも指紋が変わり、由来配置後の再測定も保存済み指紋と一致しません。②③へ広げる前に、除外規則と「由来配置前を測る」検証手順を固定してください。規則を変更するなら指紋のバージョンも更新するのが適切です。 |
| 秘密情報の辞書キー | **推奨** | [provenance.py:175](/Users/shimazueiichi/r2r2r-scripts/provenance.py:175) の`_scrub`は値だけを処理し、辞書キーは伏せません。人工文字列によるメモリ内確認でも残りました。現在のlab用specではキーは固定ですが、共通部品の「記録のどこか」という契約に合わせ、キーも対象にしてください。 |
| 指紋・gitの境界テスト | **推奨** | NFC正規化後に同名になる別ファイル、リンク、タブ／改行を含む名前、gitのrename・staged変更が未検証です。特にNFC同名が共存する環境ではソート順が一意にならないため、衝突を検出してエラーにすることを推奨します。 |
| 終了コード・trap・cleanup | 据え置き | `set -e`はなく、通常の由来処理失敗は`finish`の保存済み`rc`を変更しません。`wrap_success`・`wrap_fail`ともPod削除を試みた後に`finish`へ進みます。追加部分に明白な未初期化変数参照は見当たりません。ただし時間制限は上記修正が必要です。 |
| 既存KIOXIA・未マウント時 | 据え置き | `PROV_CKPT_DIR`は新規配置と最終照合の成功後だけ設定され、既存1499には設定されません。`write`は`O_EXCL`、フォルダ作成なしです。由来処理自身がdatasets・runsへ書く経路も見当たりません。 |
| 鍵・PodのIP／ポート | 据え置き | 現在のlab用specにIP・ポートを直接渡す箇所はありません。SSH由来の文字列は既存の`lab_mask`を通り、鍵は引数の伏字・既知プレフィックス・secret-file内容の置換対象です。任意のIPを除去する機能ではないため、将来の呼出側でも明示的に渡さない設計を維持してください。 |
| HF比較・`lab_start.sh`・dirty対象 | 据え置き | リモート比較と`compare_with_pod`のルート由来ファイル除外は整合しています。`lab_start.sh --model corr`の取得先にJSONが増えても、確認した起動経路に破綻は見当たりません。dirty対象の4パスも妥当です。ただし外部の`add_trim_config.py`は指紋が名前・サイズだけなので、内容SHA256の追加には価値があります。 |

追加テストでは、特に「過去の由来入りHFからのsame取得」「学習完了後の一覧取得失敗」「既定値以外で開始してからの`--stop`」「コミット行だけ返ってSSH失敗」を押さえてください。

シェル4ファイルとPython4ファイルの構文確認は成功しました。テスト本体は書込み・プロセス操作を伴うため実行しておらず、**OK 166／NG 0は未追試**です。ファイル変更、実機・Pod・Hugging Faceの操作は行っていません。

## 反映（Claude Code）
- 必須 1（全体の時間）: provenance.py write を 120 秒、Hugging Face へ足すのを 120 秒（LAB_HF_UP_TO）に。prov_spec は jq と date だけ。合わせて 240 秒まで
- 必須 2（same で前の回の由来）: place_ckpt で hf download のあと、自分の一時フォルダの train_provenance.json を消してから比べ・移す。偽の hf download（hf_same）に前の回の由来を置き、今回のものが置かれるのを確かめる
- 必須 3（学習が終わったあとの一覧で止まる）: wrap_success の頭で TRAIN_DONE=1. wrap_fail は TRAIN_DONE=1 なら completed のまま error に書く（list_empty で確かめ）
- 必須 4（--stop の設定）: lab_pod.json に init・limit_hours・prov_start を残し、--stop で steps・init・limit_hours・始めたときのコードと入力を戻す。記録にないものは空（null）
- 必須 5（openpi の途中で切れる）: Pod 側で git status まで通ったときだけ OPENPI_END を出し、ssh の終了コード 0 と両方そろったときだけ使う。そろわなければ commit・dirty は null。コマンドを Mac の bash で一時の git リポジトリに流して確かめる
- 推奨（測る時点）: 0. で provenance.py prepare によりコードと入力の指紋を測って持ち、終わったときはそれを使う（測れなければ終わったときに測る）
- 推奨（辞書のキー）: _scrub でキーも伏せる
- 推奨（境界）: NFC で同じ名前になる2つは ValueError（この Mac では同じ名前とみなされるので skip）、リンクはたどらない、git の rename・staged のテストを足す。config の入力（add_trim_config.py）には中身の sha256 も残す
- 据え置き（.DS_Store・由来自身の指紋）: 決まり（12節）の数えないものを変えることになるので、エイイチに決めてもらう
