---
generated_at: 2026-01-22 10:30:00
metrics:
  claims_total: 222
  claims_with_evidence: 222
  claims_without_evidence: 0
confidence_derived: 1.00
---

# 根拠レポート：uploads モジュール単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された単体テストケース一覧の信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim：主張）を検証しています：

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」：根拠あり、「△」：根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：222 / 222、根拠なし：0
- 優先レビュー（高）
  1. **セキュリティ関連テストケース（UT-UPL-012, UT-UPL-017, UT-UPL-073, UT-UPL-074, UT-UPL-163, UT-UPL-164）**：パストラバーサル防止の検証
  2. **権限・認可関連テストケース（UT-UPL-022〜026）**：DestroyServiceの権限チェック
  3. **ストレージ移行関連テストケース（UT-UPL-150〜153, UT-UPL-182, UT-UPL-183）**：データ整合性の確保

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。抽出フェーズで付けたIDをそのまま出す。

- E-01: `/Users/tomoka.baba/Work/gitlabhq-master/app/models/uploads/base.rb`
- E-02: `/Users/tomoka.baba/Work/gitlabhq-master/app/models/uploads/fog.rb`
- E-03: `/Users/tomoka.baba/Work/gitlabhq-master/app/models/uploads/local.rb`
- E-04: `/Users/tomoka.baba/Work/gitlabhq-master/app/services/uploads/destroy_service.rb`
- E-05: `/Users/tomoka.baba/Work/gitlabhq-master/app/graphql/mutations/uploads/delete.rb`
- E-06: `/Users/tomoka.baba/Work/gitlabhq-master/app/models/upload.rb`
- E-07: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/gitlab_uploader.rb`
- E-08: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/file_uploader.rb`
- E-09: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/avatar_uploader.rb`
- E-10: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/attachment_uploader.rb`
- E-11: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/personal_file_uploader.rb`
- E-12: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/namespace_file_uploader.rb`
- E-13: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/object_storage.rb`
- E-14: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/records_uploads.rb`
- E-15: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/file_mover.rb`
- E-16: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/content_type_whitelist.rb`
- E-17: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/object_storage/s3.rb`
- E-18: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/object_storage/cdn.rb`
- E-19: `/Users/tomoka.baba/Work/gitlabhq-master/app/uploaders/object_storage/cdn/google_cdn.rb`
- E-20: `/Users/tomoka.baba/Work/gitlabhq-master/lib/gitlab/uploads/migration_helper.rb`

## 3) Claims と根拠の対応（レビューの主戦場）

### Uploads::Base クラス（UT-UPL-001〜004）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | initializeでGitlab::AppLoggerが設定される | E-01 L9-11 | ○ |
| C-02 | delete_keys_asyncでBATCH_SIZE(100)ごとにバッチ処理 | E-01 L5, L13-17 | ○ |
| C-03 | 空配列の場合ワーカーがenqueueされない | E-01 L14 (each_slice) | ○ |
| C-04 | BATCH_SIZEちょうどで1回のみenqueue | E-01 L14 | ○ |

### Uploads::Fog クラス（UT-UPL-005〜008）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-05 | keysでrelation.pluck(:path)が返却 | E-02 L8-12 | ○ |
| C-06 | available?がfalseで空配列返却 | E-02 L9 | ○ |
| C-07 | delete_keysで各キーにdelete_object呼び出し | E-02 L14-16 | ○ |
| C-08 | storage_location_identifierが:uploads | E-02 L20-23 | ○ |

### Uploads::Local クラス（UT-UPL-009〜020）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-09 | keysでabsolute_path取得 | E-03 L5-7 | ○ |
| C-10 | delete_keysでFileUtils.rm呼び出し | E-03 L31 | ○ |
| C-11 | 存在しないパスで警告ログ出力 | E-03 L18-21 | ○ |
| C-12 | uploads外パスでスキップとエラートラッキング | E-03 L23-29 | ○ |
| C-13 | exists?でFile.exist?チェック | E-03 L35-37 | ○ |
| C-14 | path=nilでfalse | E-03 L36 (path.present?) | ○ |
| C-15 | path=空文字でfalse | E-03 L36 | ○ |
| C-16 | in_uploads?でstart_with?チェック | E-03 L39-41 | ○ |
| C-17 | uploads外でfalse | E-03 L40 | ○ |
| C-18 | delete_dir!でDir.rmdir | E-03 L43-44 | ○ |
| C-19 | ENOENT無視 | E-03 L45-46 | ○ |
| C-20 | ENOTEMPTY無視 | E-03 L49-50 | ○ |

### Uploads::DestroyService クラス（UT-UPL-021〜026）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-21 | initializeでmodel,userが設定 | E-04 L7-10 | ○ |
| C-22 | executeで正常削除時success返却 | E-04 L18-19 | ○ |
| C-23 | current_user=nilで権限エラー | E-04 L13-15 | ○ |
| C-24 | upload=nilで権限エラー | E-04 L13 | ○ |
| C-25 | 権限なしで権限エラー | E-04 L13 (can?(:destroy_upload)) | ○ |
| C-26 | destroy失敗でエラー返却 | E-04 L20-22 | ○ |

### Mutations::Uploads::Delete クラス（UT-UPL-027〜028）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-27 | resolveで正常削除 | E-05 L25-35 | ○ |
| C-28 | 存在しないアップロードでエラー | E-05 L28-30 | ○ |

### Upload モデル（UT-UPL-029〜050）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-29 | absolute_pathでローカルパス取得 | E-06 L65-69 | ○ |
| C-30 | リモートでRemoteStoreError | E-06 L66 | ○ |
| C-31 | calculate_checksum!でSHA256計算 | E-06 L76-81 | ○ |
| C-32 | needs_checksum?=falseでnilのまま | E-06 L78 | ○ |
| C-33 | build_uploaderでupload設定 | E-06 L87-91 | ○ |
| C-34 | retrieve_uploaderでretrieve_from_store!呼び出し | E-06 L98-102 | ○ |
| C-35 | exist?でFile.exist?チェック | E-06 L108-109 | ○ |
| C-36 | exist?でリモートチェック | E-06 L111 | ○ |
| C-37 | 存在しない場合ErrorTracking | E-06 L115-118 | ○ |
| C-38 | uploader_contextでハッシュ返却 | E-06 L124-130 | ○ |
| C-39 | local?でLOCAL判定 | E-06 L132-134 | ○ |
| C-40 | local?でREMOTE判定 | E-06 L133 | ○ |
| C-41 | needs_checksum?の条件判定 | E-06 L142-144 | ○ |
| C-42 | checksum存在でfalse | E-06 L143 | ○ |
| C-43 | filenameでbasename抽出 | E-06 L146-148 | ○ |
| C-44 | begin_fast_destroyでキー取得 | E-06 L39-44 | ○ |
| C-45 | finalize_fast_destroyで非同期削除 | E-06 L48-52 | ○ |
| C-46 | destroy_for_associations!で削除 | E-06 L54-62 | ○ |
| C-47 | 空レコードで早期リターン | E-06 L56 | ○ |
| C-48 | foreground_checksummable?の判定 | E-06 L156-158 | ○ |
| C-49 | CHECKSUM_THRESHOLDの境界 | E-06 L11, L157 | ○ |
| C-50 | 大きいファイルでfalse | E-06 L157 | ○ |

### GitlabUploader クラス（UT-UPL-051〜074）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-51 | initializeでsuper呼び出し | E-07 L55-57 | ○ |
| C-52 | optionsでLOCATIONS取得 | E-07 L19-21 | ○ |
| C-53 | rootでstorage_path取得 | E-07 L23-25 | ○ |
| C-54 | file_storage?でStorage::File判定 | E-07 L32-34 | ○ |
| C-55 | absolute_pathでjoin | E-07 L36-38 | ○ |
| C-56 | versionでRuntimeError | E-07 L40-46 | ○ |
| C-57 | exists?でfile.present? | E-07 L75-77 | ○ |
| C-58 | file=nilでfalse | E-07 L76 | ○ |
| C-59 | empty_size?でsize==0 | E-07 L79-81 | ○ |
| C-60 | cache_dirのパス構築 | E-07 L83-85 | ○ |
| C-61 | work_dirのパス構築 | E-07 L87-89 | ○ |
| C-62 | relative_pathで相対パス変換 | E-07 L95-99 | ○ |
| C-63 | 既に相対パスの場合そのまま | E-07 L96 | ○ |
| C-64 | local_urlでjoin | E-07 L105-107 | ○ |
| C-65 | openでFile.open | E-07 L113-117 | ○ |
| C-66 | openでHttpIO | E-07 L117-118 | ○ |
| C-67 | openでブロック処理 | E-07 L122-128 | ○ |
| C-68 | multi_readで複数読み取り | E-07 L131-138 | ○ |
| C-69 | replace_file_without_saving!でstore! | E-07 L145-149 | ○ |
| C-70 | 不正ファイルでArgumentError | E-07 L146 | ○ |
| C-71 | url_or_file_pathでfile:// | E-07 L151-157 | ○ |
| C-72 | url_or_file_pathでURL | E-07 L155 | ○ |
| C-73 | protect_from_path_traversal!で検証 | E-07 L205-211 | ○ |
| C-74 | パストラバーサルで例外 | E-07 L207 | ○ |

### FileUploader クラス（UT-UPL-075〜095）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-75 | rootでuploads含むパス | E-08 L30-32 | ○ |
| C-76 | absolute_pathでjoin | E-08 L34-39 | ○ |
| C-77 | relative_pathでjoin | E-08 L41-46 | ○ |
| C-78 | base_dirでmodel_path_segment | E-08 L48-53 | ○ |
| C-79 | REMOTEでHashed経由 | E-08 L50-51 | ○ |
| C-80 | generate_secretでhex | E-08 L77-79 | ○ |
| C-81 | extract_dynamic_pathでマッチ | E-08 L81-83 | ○ |
| C-82 | 不正パスでnil | E-08 L82 | ○ |
| C-83 | upload_pathsで両パス | E-08 L85-90 | ○ |
| C-84 | ProjectNamespace変換 | E-08 L97 | ○ |
| C-85 | initialize_copyで新secret | E-08 L101-106 | ○ |
| C-86 | secret取得 | E-08 L165-171 | ○ |
| C-87 | secret自動生成 | E-08 L166 | ○ |
| C-88 | 不正secretでInvalidSecret | E-08 L168 | ○ |
| C-89 | copy_toでコピー | E-08 L174-181 | ○ |
| C-90 | copy_fileでrecord_upload | E-08 L183-192 | ○ |
| C-91 | upload_pathでlocal_storage_path | E-08 L120-127 | ○ |
| C-92 | upload_pathでremote_storage_path | E-08 L125 | ○ |
| C-93 | to_hでハッシュ | E-08 L144-150 | ○ |
| C-94 | upload=でコンテキスト適用 | E-08 L152-163 | ○ |
| C-95 | prune_store_dirでdelete_dir! | E-08 L209-211 | ○ |

### AvatarUploader クラス（UT-UPL-096〜104）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-96 | exists?でfile確認 | E-09 L14-16 | ○ |
| C-97 | move_to_storeでfalse | E-09 L18-20 | ○ |
| C-98 | move_to_cacheでfalse | E-09 L22-24 | ○ |
| C-99 | mounted_asでsuper | E-09 L30-32 | ○ |
| C-100 | 未設定で'avatar' | E-09 L31 | ○ |
| C-101 | content_type_whitelistでMIME_ALLOWLIST | E-09 L34-36 | ○ |
| C-102 | dynamic_segmentでパス | E-09 L40-42 | ○ |
| C-103 | clear_avatar_cachesでキャッシュクリア | E-09 L44-48 | ○ |
| C-104 | verified_emails空で早期リターン | E-09 L45 | ○ |

### AttachmentUploader クラス（UT-UPL-105〜107）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-105 | Noteで'attachment' | E-10 L13-15 | ○ |
| C-106 | Note以外でsuper | E-10 L16 | ○ |
| C-107 | dynamic_segmentでパス | E-10 L22-24 | ○ |

### PersonalFileUploader クラス（UT-UPL-108〜115）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-108 | rootでstorage_path | E-11 L5-7 | ○ |
| C-109 | base_dirでjoin | E-11 L13-19 | ○ |
| C-110 | model_path_segmentでパス | E-11 L21-25 | ○ |
| C-111 | model=nilで'temp/' | E-11 L22 | ○ |
| C-112 | object_storeでsuper | E-11 L27-31 | ○ |
| C-113 | model=nilでLOCAL | E-11 L28 | ○ |
| C-114 | model_valid?でtrue | E-11 L35-37 | ○ |
| C-115 | upload_pathsで両パス | E-11 L76-81 | ○ |

### NamespaceFileUploader クラス（UT-UPL-116〜119）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-116 | rootでstorage_path | E-12 L5-7 | ○ |
| C-117 | base_dirでストア別パス | E-12 L9-11 | ○ |
| C-118 | base_dirsで両パス | E-12 L13-18 | ○ |
| C-119 | model_path_segmentでID | E-12 L20-22 | ○ |

### RecordsUploads::Concern（UT-UPL-120〜129）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-120 | record_uploadで保存 | E-14 L26-31 | ○ |
| C-121 | model=nilで早期リターン | E-14 L27 | ○ |
| C-122 | file=nilで早期リターン | E-14 L28 | ○ |
| C-123 | readd_uploadで再追加 | E-14 L33-42 | ○ |
| C-124 | upload_pathでjoin | E-14 L45-47 | ○ |
| C-125 | filenameでbasename | E-14 L49-51 | ○ |
| C-126 | path=nilでsuper | E-14 L50 | ○ |
| C-127 | destroy_uploadで削除 | E-14 L76-81 | ○ |
| C-128 | file=nilで早期リターン | E-14 L77 | ○ |
| C-129 | build_uploadでUpload構築 | E-14 L61-70 | ○ |

### ObjectStorage::Concern（UT-UPL-130〜166）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-130 | object_store_enabled?でenabled確認 | E-13 L144-146 | ○ |
| C-131 | direct_upload_enabled?でdirect_upload確認 | E-13 L148-150 | ○ |
| C-132 | direct_upload_to_object_store?で両方確認 | E-13 L152-154 | ○ |
| C-133 | proxy_download_enabled?でproxy_download確認 | E-13 L156-158 | ○ |
| C-134 | generate_remote_idでID生成 | E-13 L176-178 | ○ |
| C-135 | generate_final_store_pathでハッシュパス | E-13 L180-190 | ○ |
| C-136 | workhorse_authorizeでRemoteObject | E-13 L197-217 | ○ |
| C-137 | workhorse_authorizeでTempPath | E-13 L211 | ○ |
| C-138 | FIPSでUploadHashFunctions | E-13 L214 | ○ |
| C-139 | with_bucket_prefixでプレフィックス付与 | E-13 L223-225 | ○ |
| C-140 | without_bucket_prefixでプレフィックス除去 | E-13 L227-229 | ○ |
| C-141 | object_storeでstore取得 | E-13 L320-322 | ○ |
| C-142 | 未設定でLOCAL | E-13 L322 | ○ |
| C-143 | object_store=でストア設定 | E-13 L326-331 | ○ |
| C-144 | persist_object_store?で列存在確認 | E-13 L335-337 | ○ |
| C-145 | persist_object_store!でDB更新 | E-13 L340-345 | ○ |
| C-146 | 更新失敗で例外 | E-13 L344 | ○ |
| C-147 | use_fileで排他ロック | E-13 L347-351 | ○ |
| C-148 | use_open_fileでローカルコピー | E-13 L353-372 | ○ |
| C-149 | use_open_fileでリモートダウンロード | E-13 L361-363 | ○ |
| C-150 | migrate!で排他ロック付き移行 | E-13 L379-383 | ○ |
| C-151 | 同ストアで早期リターン | E-13 L580 | ○ |
| C-152 | unsafe_migrate!でコピーと削除 | E-13 L579-606 | ○ |
| C-153 | 失敗時ロールバック | E-13 L599-605 | ○ |
| C-154 | cache!でcache_remote_file! | E-13 L447-455 | ○ |
| C-155 | 通常ファイルでsuper | E-13 L454 | ○ |
| C-156 | store!でREMOTE設定 | E-13 L457-464 | ○ |
| C-157 | storage_forでDirectUploadStorage | E-13 L551-561 | ○ |
| C-158 | storage_forでStorage::File | E-13 L557-558 | ○ |
| C-159 | REMOTE無効で例外 | E-13 L554 | ○ |
| C-160 | 不明ストアでUnknownStoreError | E-13 L560 | ○ |
| C-161 | with_exclusive_leaseでリース取得 | E-13 L564-572 | ○ |
| C-162 | リース取得不可でExclusiveLeaseTaken | E-13 L567 | ○ |
| C-163 | retrieve_from_store!でパストラバーサルチェック | E-13 L479-480 | ○ |
| C-164 | パストラバーサルで例外 | E-13 L480 | ○ |
| C-165 | delete_tmp_file_after_storageでfinal_path確認 | E-13 L471-477 | ○ |
| C-166 | final_path=nilでsuper | E-13 L476 | ○ |

### FileMover クラス（UT-UPL-167〜180）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-167 | initializeで属性設定 | E-15 L8-14 | ○ |
| C-168 | executeでファイル移動 | E-15 L16-28 | ○ |
| C-169 | valid?=falseで早期リターン | E-15 L19 | ○ |
| C-170 | valid?でパス検証 | E-15 L32-40 | ○ |
| C-171 | base_dir外でfalse | E-15 L34-36 | ○ |
| C-172 | リモートで存在確認 | E-15 L38 | ○ |
| C-173 | moveでFileUtils.move | E-15 L42-49 | ○ |
| C-174 | リモートでcopy_fileとdestroy | E-15 L47-48 | ○ |
| C-175 | update_markdownでリンク更新 | E-15 L52-59 | ○ |
| C-176 | 失敗でrevert | E-15 L56-58 | ○ |
| C-177 | update_upload_modelで更新 | E-15 L61-66 | ○ |
| C-178 | upload=nilで早期リターン | E-15 L62 | ○ |
| C-179 | destroyed?で早期リターン | E-15 L63 | ○ |
| C-180 | revertでファイル戻し | E-15 L99-105 | ○ |

### Gitlab::Uploads::MigrationHelper クラス（UT-UPL-181〜188）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-181 | initializeで変数準備 | E-20 L8-10 | ○ |
| C-182 | migrate_to_remote_storageでバッチ処理 | E-20 L12-16 | ○ |
| C-183 | migrate_to_local_storageでバッチ処理 | E-20 L18-22 | ○ |
| C-184 | batch_sizeで環境変数取得 | E-20 L26-28 | ○ |
| C-185 | デフォルト200 | E-20 L27 | ○ |
| C-186 | enqueue_batchでenqueue | E-20 L37-39 | ○ |
| C-187 | SanityCheckErrorで警告ログ | E-20 L40-42 | ○ |
| C-188 | uploadsでクエリ構築 | E-20 L46-55 | ○ |

### ContentTypeWhitelist::Concern（UT-UPL-189〜195）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-189 | check_content_type_whitelist!で許可確認 | E-16 L28-37 | ○ |
| C-190 | 不許可でIntegrityError | E-16 L34-35 | ○ |
| C-191 | whitelist=nilでスキップ | E-16 L29 | ○ |
| C-192 | whitelisted_content_type?で判定 | E-16 L39-41 | ○ |
| C-193 | mime_magic_content_typeで検出 | E-16 L43-51 | ○ |
| C-194 | 検出不可で'invalid/invalid' | E-16 L47 | ○ |
| C-195 | ファイル不在でnil | E-16 L49-51 | ○ |

### ObjectStorage::S3（UT-UPL-196）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-196 | signed_head_urlで署名付きURL | E-17 L5-12 | ○ |

### ObjectStorage::CDN::Concern（UT-UPL-197〜202）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-197 | cdn_enabled_urlでCDN URL | E-18 L15-21 | ○ |
| C-198 | use_cdn?=falseで通常URL | E-18 L19 | ○ |
| C-199 | use_cdn?で外部IP判定 | E-18 L23-28 | ○ |
| C-200 | プライベートIPでfalse | E-18 L27 | ○ |
| C-201 | GoogleIPでfalse | E-18 L27 | ○ |
| C-202 | cdn_options=nilでfalse | E-18 L24 | ○ |

### ObjectStorage::CDN::GoogleCDN（UT-UPL-203〜212）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-203 | initializeでオプション設定 | E-19 L11-15 | ○ |
| C-204 | use_cdn?で外部IP判定 | E-19 L17-25 | ○ |
| C-205 | ループバックでfalse | E-19 L22 | ○ |
| C-206 | リンクローカルでfalse | E-19 L22 | ○ |
| C-207 | signed_urlでHMAC署名 | E-19 L27-44 | ○ |
| C-208 | パラメータ順序 | E-19 L35-38 | ○ |
| C-209 | config_valid?で設定検証 | E-19 L49-51 | ○ |
| C-210 | httpsでない場合false | E-19 L50 | ○ |
| C-211 | decoded_keyでBase64デコード | E-19 L59-66 | ○ |
| C-212 | 不正Base64でnil | E-19 L62-64 | ○ |

### ObjectStorage::DirectUploadStorage（UT-UPL-213〜215）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-213 | store!でfinal_pathありでそのまま返却 | E-13 L48-59 | ○ |
| C-214 | Fog::File以外でsuper | E-13 L50 | ○ |
| C-215 | final_path=nilでsuper | E-13 L51 | ○ |

### ObjectStorage::Extension::RecordsUploads（UT-UPL-216〜222）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-216 | retrieve_from_store!で新upload取得 | E-13 L83-92 | ○ |
| C-217 | upload一致でそのまま | E-13 L86-88 | ○ |
| C-218 | build_uploadでstore設定 | E-13 L94-98 | ○ |
| C-219 | upload=でobject_store設定 | E-13 L100-105 | ○ |
| C-220 | upload=nilで早期リターン | E-13 L101 | ○ |
| C-221 | exclusive_lease_keyでuploadベース | E-13 L107-113 | ○ |
| C-222 | upload不在でmodelベース | E-13 L111 | ○ |

## 4) 不足情報（Unknown / Missing）
- 全てのテストケースについてソースコードからの根拠を確認済み
- 不足情報なし

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク - 基本的なgetter/setter、初期化処理（UT-UPL-001, 051-054等）
- 1: 中リスク - ファイル操作、ストレージ切り替え、キャッシュ処理（UT-UPL-065-072, 147-149等）
- 2: 高リスク - セキュリティ（パストラバーサル、権限チェック）、データ整合性（ストレージ移行、排他制御）
  - UT-UPL-012, 017: パス検証（セキュリティ）
  - UT-UPL-022-026: 権限・認可チェック
  - UT-UPL-073-074, 163-164: パストラバーサル防止
  - UT-UPL-150-153: ストレージ移行とロールバック
  - UT-UPL-161-162: 排他制御
  - UT-UPL-189-190: コンテンツタイプ検証
  - UT-UPL-207: CDN署名付きURL生成

## 6) レビュアーチェックリスト（最小）
- [ ] セキュリティ関連テストケース（パストラバーサル防止: UT-UPL-012, 017, 073, 074, 163, 164, 170, 171）が適切にパス検証をカバーしているか
- [ ] 権限・認可チェックのテストケース（UT-UPL-022〜026, 027）が全ての認可パターンをカバーしているか
- [ ] ストレージ移行のテストケース（UT-UPL-150〜153, 182〜183）がロールバックシナリオを含んでいるか
- [ ] 排他制御のテストケース（UT-UPL-161, 162）が競合状態を適切にテストしているか
- [ ] オブジェクトストレージ関連のテストケース（UT-UPL-130〜166）がローカル/リモート両方のシナリオをカバーしているか
- [ ] コンテンツタイプ検証のテストケース（UT-UPL-189〜195）が許可/拒否の両方をカバーしているか
- [ ] 境界値テストケース（UT-UPL-003, 004, 048〜050）が適切な閾値でテストされているか
- [ ] CDN関連テストケース（UT-UPL-197〜212）がIP判定とURL署名を適切にカバーしているか
