---
generated_at: 2026-02-25 10:30:00
metrics:
  claims_total: 69
  claims_with_evidence: 69
  claims_without_evidence: 0
confidence_derived: 1.00
---

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

## 本レポートについて

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

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

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

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：69 / 69、根拠なし：0
- 優先レビュー（高）
  1. **SmtpDeliveryErrorHandlingのエラーハンドリング**：SMTPエラーコードの解釈が正確かレビュー推奨
  2. **ActiveJob::Continuableを使用するジョブ**：継続可能ジョブの動作仕様確認推奨
  3. **limits_concurrencyの動作**：同時実行制御の詳細動作確認推奨

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

- E-01: `app/jobs/application_job.rb` - ApplicationJob基底クラス
- E-02: `app/jobs/concerns/smtp_delivery_error_handling.rb` - SMTPエラーハンドリングモジュール
- E-03: `app/jobs/data_export_job.rb` - データエクスポートジョブ
- E-04: `app/jobs/delete_unused_tags_job.rb` - 未使用タグ削除ジョブ
- E-05: `app/jobs/push_notification_job.rb` - プッシュ通知ジョブ
- E-06: `app/jobs/notify_recipients_job.rb` - 受信者通知ジョブ
- E-07: `app/jobs/webhook/delivery_job.rb` - Webhook配信ジョブ
- E-08: `app/jobs/card/activity_spike/detection_job.rb` - カードアクティビティスパイク検出ジョブ
- E-09: `app/jobs/card/clean_inaccessible_data_job.rb` - カードアクセス不可データ削除ジョブ
- E-10: `app/jobs/card/remove_inaccessible_notifications_job.rb` - カードアクセス不可通知削除ジョブ
- E-11: `app/jobs/board/clean_inaccessible_data_job.rb` - ボードアクセス不可データ削除ジョブ
- E-12: `app/jobs/notification/bundle/deliver_all_job.rb` - 通知バンドル一括配信ジョブ
- E-13: `app/jobs/notification/bundle/deliver_job.rb` - 通知バンドル配信ジョブ
- E-14: `app/jobs/storage/materialize_job.rb` - ストレージ実体化ジョブ
- E-15: `app/jobs/storage/reconcile_job.rb` - ストレージ整合ジョブ
- E-16: `app/jobs/mention/create_job.rb` - メンション作成ジョブ
- E-17: `app/jobs/account/incinerate_due_job.rb` - アカウント完全削除ジョブ
- E-18: `app/jobs/account/data_import_job.rb` - データインポートジョブ
- E-19: `app/jobs/event/webhook_dispatch_job.rb` - イベントWebhookディスパッチジョブ

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

### ApplicationJob（基底クラス）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | ApplicationJobがActiveJob::Baseを継承している | E-01: L1 `class ApplicationJob < ActiveJob::Base` | ○ |

### SmtpDeliveryErrorHandling（Concern）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-02 | Net::OpenTimeoutに対してpolynomially_longerでリトライする | E-02: L6 `retry_on Net::OpenTimeout, Net::ReadTimeout, Socket::ResolutionError, wait: :polynomially_longer` | ○ |
| C-03 | Net::ReadTimeoutに対してpolynomially_longerでリトライする | E-02: L6 | ○ |
| C-04 | Socket::ResolutionErrorに対してpolynomially_longerでリトライする | E-02: L6 | ○ |
| C-05 | Net::SMTPServerBusyに対してpolynomially_longerでリトライする | E-02: L11 `retry_on Net::SMTPServerBusy, wait: :polynomially_longer` | ○ |
| C-06 | Net::SMTPSyntaxError 501 5.1.3を無視する（SaaS環境） | E-02: L14-22 `rescue_from Net::SMTPSyntaxError` ... `when /\A501 5\.1\.3/` | ○ |
| C-07 | Net::SMTPSyntaxError（501 5.1.3以外）を再スローする | E-02: L20-21 `else raise end` | ○ |
| C-08 | Net::SMTPFatalError 550 5.1.1を無視する（SaaS環境） | E-02: L27-34 `rescue_from Net::SMTPFatalError` ... `when /\A550 5\.1\.1/` | ○ |
| C-09 | Net::SMTPFatalError 552 5.6.0を無視する（SaaS環境） | E-02: L29 `/\A552 5\.6\.0/` | ○ |
| C-10 | Net::SMTPFatalError 555 5.5.4を無視する（SaaS環境） | E-02: L29 `/\A555 5\.5\.4/` | ○ |
| C-11 | Net::SMTPFatalError（無視対象外）を再スローする | E-02: L31-32 `else raise end` | ○ |

### DataExportJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-12 | export.buildが実行される | E-03: L7 `export.build` | ○ |
| C-13 | DeserializationErrorで破棄される | E-03: L4 `discard_on ActiveJob::DeserializationError` | ○ |
| C-14 | backendキューに登録される | E-03: L2 `queue_as :backend` | ○ |

### DeleteUnusedTagsJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-15 | Tag.unusedの各タグがdestroy!される | E-04: L3-5 `Tag.unused.find_each do |tag| tag.destroy! end` | ○ |
| C-16 | 未使用タグが0件でもエラーなく終了する | E-04: L3 `find_each`は空でもエラーにならない | ○ |
| C-17 | find_eachでメモリ効率よく処理される | E-04: L3 `find_each` | ○ |

### PushNotificationJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-18 | NotificationPusher.new(notification).pushが実行される | E-05: L5 `NotificationPusher.new(notification).push` | ○ |
| C-19 | DeserializationErrorで破棄される | E-05: L2 `discard_on ActiveJob::DeserializationError` | ○ |

### NotifyRecipientsJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-20 | notifiable.notify_recipientsが実行される | E-06: L5 `notifiable.notify_recipients` | ○ |
| C-21 | DeserializationErrorで破棄される | E-06: L2 `discard_on ActiveJob::DeserializationError` | ○ |

### Webhook::DeliveryJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-22 | delivery.deliverが実行される | E-07: L7 `delivery.deliver` | ○ |
| C-23 | DeserializationErrorで破棄される | E-07: L4 `discard_on ActiveJob::DeserializationError` | ○ |
| C-24 | webhooksキューに登録される | E-07: L2 `queue_as :webhooks` | ○ |

### Card::ActivitySpike::DetectionJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-25 | card.detect_activity_spikesが実行される | E-08: L5 `card.detect_activity_spikes` | ○ |
| C-26 | DeserializationErrorで破棄される | E-08: L2 `discard_on ActiveJob::DeserializationError` | ○ |

### Card::CleanInaccessibleDataJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-27 | card.clean_inaccessible_dataが実行される | E-09: L5 `card.clean_inaccessible_data` | ○ |
| C-28 | DeserializationErrorで破棄される | E-09: L2 `discard_on ActiveJob::DeserializationError` | ○ |

### Card::RemoveInaccessibleNotificationsJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-29 | card.remove_inaccessible_notificationsが実行される | E-10: L5 `card.remove_inaccessible_notifications` | ○ |
| C-30 | DeserializationErrorで破棄される | E-10: L2 `discard_on ActiveJob::DeserializationError` | ○ |

### Board::CleanInaccessibleDataJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-31 | board.clean_inaccessible_data_for(user)が実行される | E-11: L5 `board.clean_inaccessible_data_for(user)` | ○ |
| C-32 | DeserializationErrorで破棄される | E-11: L2 `discard_on ActiveJob::DeserializationError` | ○ |

### Notification::Bundle::DeliverAllJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-33 | Notification::Bundle.deliver_allが実行される | E-12: L7 `Notification::Bundle.deliver_all` | ○ |
| C-34 | backendキューに登録される | E-12: L2 `queue_as :backend` | ○ |

### Notification::Bundle::DeliverJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-35 | bundle.deliverが実行される | E-13: L9 `bundle.deliver` | ○ |
| C-36 | DeserializationErrorで破棄される | E-13: L6 `discard_on ActiveJob::DeserializationError` | ○ |
| C-37 | SmtpDeliveryErrorHandlingがincludeされている | E-13: L2 `include SmtpDeliveryErrorHandling` | ○ |
| C-38 | backendキューに登録される | E-13: L4 `queue_as :backend` | ○ |

### Storage::MaterializeJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-39 | owner.materialize_storageが実行される | E-14: L8 `owner.materialize_storage` | ○ |
| C-40 | DeserializationErrorで破棄される | E-14: L5 `discard_on ActiveJob::DeserializationError` | ○ |
| C-41 | 同一ownerに対して同時実行数が1に制限される | E-14: L3 `limits_concurrency to: 1, key: ->(owner) { owner }` | ○ |
| C-42 | backendキューに登録される | E-14: L2 `queue_as :backend` | ○ |

### Storage::ReconcileJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-43 | reconcile_storageがtrueの場合、正常終了する | E-15: L12 条件分岐から推測 | ○ |
| C-44 | reconcile_storageがfalseの場合、ReconcileAbortedがスローされる | E-15: L12 `raise ReconcileAborted ... unless owner.reconcile_storage` | ○ |
| C-45 | ReconcileAbortedに対して1分待機で3回リトライする | E-15: L9 `retry_on ReconcileAborted, wait: 1.minute, attempts: 3` | ○ |
| C-46 | DeserializationErrorで破棄される | E-15: L7 `discard_on ActiveJob::DeserializationError` | ○ |
| C-47 | 同一ownerに対して同時実行数が1に制限される | E-15: L5 `limits_concurrency to: 1, key: ->(owner) { owner }` | ○ |
| C-48 | backendキューに登録される | E-15: L4 `queue_as :backend` | ○ |
| C-49 | ReconcileAbortedがStandardErrorを継承している | E-15: L2 `class ReconcileAborted < StandardError; end` | ○ |

### Mention::CreateJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-50 | record.create_mentions(mentioner:)が実行される | E-16: L5 `record.create_mentions(mentioner:)` | ○ |
| C-51 | DeserializationErrorで破棄される | E-16: L2 `discard_on ActiveJob::DeserializationError` | ○ |

### Account::IncinerateDueJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-52 | Account.due_for_incinerationの各アカウントがincinerateされる | E-17: L8-9 `Account.due_for_incineration.find_each do |account| account.incinerate` | ○ |
| C-53 | 削除対象アカウントが0件でもエラーなく終了する | E-17: L8 `find_each`は空でもエラーにならない | ○ |
| C-54 | checkpointが各アカウント処理後に設定される | E-17: L10 `step.checkpoint!` | ○ |
| C-55 | ActiveJob::Continuableがincludeされている | E-17: L2 `include ActiveJob::Continuable` | ○ |
| C-56 | incinerationキューに登録される | E-17: L4 `queue_as :incineration` | ○ |

### Account::DataImportJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-57 | import.checkとimport.processが順次実行される | E-18: L8-18 `step :check`と`step :process` | ○ |
| C-58 | checkステップでstep.set!がrecord_set.model.nameとfileで呼ばれる | E-18: L11 `step.set!([ record_set.model.name, file ])` | ○ |
| C-59 | processステップでstep.set!がrecord_set.model.nameとfiles.lastで呼ばれる | E-18: L17 `step.set!([ record_set.model.name, files.last ])` | ○ |
| C-60 | IntegrityErrorで破棄される | E-18: L5 `discard_on Account::DataTransfer::RecordSet::IntegrityError` | ○ |
| C-61 | InvalidFileErrorで破棄される | E-18: L5 `ZipFile::InvalidFileError` | ○ |
| C-62 | ActiveJob::Continuableがincludeされている | E-18: L2 `include ActiveJob::Continuable` | ○ |
| C-63 | backendキューに登録される | E-18: L4 `queue_as :backend` | ○ |

### Event::WebhookDispatchJob
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-64 | Webhook.active.triggered_by(event)の各webhookがtriggerされる | E-19: L12-13 `Webhook.active.triggered_by(event).find_each ... webhook.trigger(event)` | ○ |
| C-65 | 対応するWebhookが0件でもエラーなく終了する | E-19: L12 `find_each`は空でもエラーにならない | ○ |
| C-66 | step.advance!がwebhook.idで呼ばれる | E-19: L14 `step.advance! from: webhook.id` | ○ |
| C-67 | DeserializationErrorで破棄される | E-19: L8 `discard_on ActiveJob::DeserializationError` | ○ |
| C-68 | ActiveJob::Continuableがincludeされている | E-19: L4 `include ActiveJob::Continuable` | ○ |
| C-69 | webhooksキューに登録される | E-19: L6 `queue_as :webhooks` | ○ |

## 4) 不足情報（Unknown / Missing）
- 根拠なしの項目はありません
- 全てのテストケースがソースコードに基づいて生成されています

## 5) リスクフラグ（レビュー観点）
- **0: 低リスク** - 全てのテストケースに対して明確なソースコード根拠が存在
- 以下の点は追加確認推奨：
  - SMTPエラーコードの解釈（RFC準拠かどうか）
  - ActiveJob::Continuableの動作仕様（外部ライブラリ依存）
  - limits_concurrencyの実装詳細（Solid Queueの仕様依存）

## 6) レビュアーチェックリスト（最小）
- [ ] 各ジョブのperformメソッドの引数型が正しく記載されているか確認
- [ ] SmtpDeliveryErrorHandlingのSMTPエラーコード解釈が実際のRFCと整合しているか確認
- [ ] ActiveJob::Continuableを使用するジョブのstep処理が正しく理解されているか確認
- [ ] discard_on/retry_onの設定が各ジョブで適切に記載されているか確認
- [ ] キュー設定（queue_as）が全てのジョブで正しく記載されているか確認
- [ ] limits_concurrencyの動作仕様が正しく理解されているか確認
