---
generated_at: 2026-02-25 03:00:00
metrics:
  claims_total: 72
  claims_with_evidence: 72
  claims_without_evidence: 0
confidence_derived: 1.00
---

# 根拠レポート：lib-root.csv

## 本レポートについて

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

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

1. **根拠の有無確認**：各テストケースに対して、ソースコードに該当する処理・分岐が存在するか
2. **根拠との整合性**：テストケースの内容がソースコードの実装と矛盾していないか
3. **網羅性**：テスト対象のクラス・メソッドを適切にカバーしているか

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

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

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**1.00**
  - 根拠あり：72 / 72、根拠なし：0
- 優先レビュー（高）
  1. なし - 全てのテストケースにソースコードの根拠あり

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

- E-01: `lib/fizzy.rb` - Fizzyモジュールおよび Fizzy::DbAdapterクラス（33行）
- E-02: `lib/deployment.rb` - Deploymentモジュールのエントリポイント（2行）
- E-03: `lib/deployment/database_resolver.rb` - Deployment::DatabaseResolverクラス（18行）
- E-04: `lib/web_push/pool.rb` - WebPush::Poolクラス（56行）
- E-05: `lib/web_push/notification.rb` - WebPush::Notificationクラス（29行）
- E-06: `lib/auto_link_scrubber.rb` - AutoLinkScrubberクラス（79行）

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

### Fizzyモジュール（lib/fizzy.rb）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | saas?メソッドはSAAS環境変数でtrueを返す | E-01 (行5: `!!(((ENV["SAAS"] || ...`) | ○ |
| C-02 | saas?メソッドはsaas.txtファイル存在でtrueを返す | E-01 (行5: `File.exist?(File.expand_path("../tmp/saas.txt"...`) | ○ |
| C-03 | saas?メソッドはSAAS=falseでfalseを返す | E-01 (行5: `ENV["SAAS"] != "false"`) | ○ |
| C-04 | saas?メソッドは条件不成立時falseを返す | E-01 (行5: 条件式全体) | ○ |
| C-05 | saas?メソッドは結果をメモ化する | E-01 (行4-5: `return @saas if defined?(@saas)`, `@saas = ...`) | ○ |
| C-06 | db_adapterはDATABASE_ADAPTER環境変数を使用 | E-01 (行9: `ENV.fetch("DATABASE_ADAPTER", ...)`) | ○ |
| C-07 | db_adapterはSaaS環境でmysqlをデフォルトとする | E-01 (行9: `saas? ? "mysql" : "sqlite"`) | ○ |
| C-08 | db_adapterは非SaaS環境でsqliteをデフォルトとする | E-01 (行9: `saas? ? "mysql" : "sqlite"`) | ○ |
| C-09 | db_adapterは結果をメモ化する | E-01 (行9: `@db_adapter ||= ...`) | ○ |
| C-10 | configure_bundleはSaaS環境でGemfile.saasを設定 | E-01 (行13-15: `if saas?`, `ENV["BUNDLE_GEMFILE"] = "Gemfile.saas"`) | ○ |
| C-11 | configure_bundleは非SaaS環境で何もしない | E-01 (行12-16: if文の条件分岐) | ○ |

### Fizzy::DbAdapterクラス（lib/fizzy.rb）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-12 | initializeは文字列でアダプタ名を受け取る | E-01 (行20-22: `def initialize(name)`, `@name = name.to_s`) | ○ |
| C-13 | initializeはシンボルを文字列に変換する | E-01 (行21: `@name = name.to_s`) | ○ |
| C-14 | to_sはアダプタ名を返す | E-01 (行24-26: `def to_s`, `@name`) | ○ |
| C-15 | sqlite?はsqliteの場合trueを返す | E-01 (行29-31: `def sqlite?`, `@name == "sqlite"`) | ○ |
| C-16 | sqlite?は他のアダプタでfalseを返す | E-01 (行30: `@name == "sqlite"`) | ○ |

### Deployment::DatabaseResolverクラス（lib/deployment/database_resolver.rb）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-17 | in_primary_datacenter?はPRIMARY_DATACENTER環境変数でtrueを返す | E-03 (行4: `ENV["PRIMARY_DATACENTER"].present?`) | ○ |
| C-18 | in_primary_datacenter?はローカル環境でtrueを返す | E-03 (行4: `Rails.env.local?`) | ○ |
| C-19 | in_primary_datacenter?は条件不成立時falseを返す | E-03 (行4: 条件式全体) | ○ |
| C-20 | reading_request?はsuperの結果を使用する | E-03 (行8: `super || ...`) | ○ |
| C-21 | reading_request?は非プライマリDCで常にtrueを返す | E-03 (行9: `!DatabaseResolver.in_primary_datacenter?`) | ○ |
| C-22 | reading_request?はプライマリDCでPOSTならfalseを返す | E-03 (行8-9: superの結果に依存) | ○ |

### WebPush::Poolクラス（lib/web_push/pool.rb）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-23 | initializeでスレッドプールを初期化する | E-04 (行6-9: `@delivery_pool = ...`, `@invalidation_pool = ...`, `@connection = ...`) | ○ |
| C-24 | delivery_poolの最大スレッド数は50 | E-04 (行6: `max_threads: 50`) | ○ |
| C-25 | delivery_poolのキューサイズは10000 | E-04 (行6: `queue_size: 10000`) | ○ |
| C-26 | invalidation_poolのスレッド数は1 | E-04 (行7: `FixedThreadPool.new(1)`) | ○ |
| C-27 | queueはサブスクリプションごとにdeliver_laterを呼ぶ | E-04 (行13-15: `subscriptions.find_each`, `deliver_later`) | ○ |
| C-28 | queueは空サブスクリプションでもエラーにならない | E-04 (行13: `find_each`は空でも安全) | ○ |
| C-29 | queueは1件のサブスクリプションを処理できる | E-04 (行13-15: find_eachの汎用性) | ○ |
| C-30 | shutdownで全プールをシャットダウンする | E-04 (行18-22: `connection.shutdown`, `shutdown_pool`) | ○ |
| C-31 | shutdown_poolは1秒後にkillする | E-04 (行53-54: `wait_for_termination(1)`, `pool.kill`) | ○ |
| C-32 | deliver_laterはスレッドプールにpostする | E-04 (行30: `delivery_pool.post`) | ○ |
| C-33 | deliver_laterはRejectedExecutionErrorを無視する | E-04 (行35: `rescue Concurrent::RejectedExecutionError`) | ○ |
| C-34 | deliverはnotification.deliverを呼ぶ | E-04 (行39: `notification.deliver(connection: connection)`) | ○ |
| C-35 | deliverはExpiredSubscriptionで無効化処理を呼ぶ | E-04 (行40-41: `rescue WebPush::ExpiredSubscription`, `invalidate_subscription_later`) | ○ |
| C-36 | deliverはOpenSSLErrorで無効化処理を呼ぶ | E-04 (行40-41: `OpenSSL::OpenSSLError`) | ○ |
| C-37 | deliverはハンドラがnilなら無効化処理を呼ばない | E-04 (行41: `if invalid_subscription_handler`) | ○ |

### WebPush::Notificationクラス（lib/web_push/notification.rb）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-38 | initializeで全パラメータを設定する | E-05 (行2-4: `def initialize(...)`, インスタンス変数への代入) | ○ |
| C-39 | deliverはWebPush.payload_sendを呼ぶ | E-05 (行8-13: `WebPush.payload_send`) | ○ |
| C-40 | deliverはurgency: "high"を設定する | E-05 (行13: `urgency: "high"`) | ○ |
| C-41 | deliverはconnection: nilでも動作する | E-05 (行7, 12: `connection: nil`がデフォルト) | ○ |
| C-42 | vapid_identificationはsupportメールを含む | E-05 (行18: `subject: "mailto:support@fizzy.do"`) | ○ |
| C-43 | encoded_messageはJSON形式でデータを生成する | E-05 (行22-23: `JSON.generate title: @title, options: {...}`) | ○ |
| C-44 | icon_pathは固定パスを返す | E-05 (行26-28: `"/apple-touch-icon.png"`) | ○ |

### AutoLinkScrubberクラス（lib/auto_link_scrubber.rb）

| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-45 | initializeでdirectionをtop_downに設定 | E-06 (行22: `@direction = :top_down`) | ○ |
| C-46 | scrubはテキストノード内のURLをリンク化する | E-06 (行28-30: `if node.text?`, `autolink_text_node`) | ○ |
| C-47 | scrubはメールアドレスをリンク化する | E-06 (行16, 68-69: `EMAIL_AUTOLINK_REGEXP`, `mailto:`) | ○ |
| C-48 | scrubはaタグ内をスキップする | E-06 (行6, 26: `EXCLUDED_ELEMENTS`, `return Loofah::Scrubber::STOP`) | ○ |
| C-49 | scrubはcodeタグ内をスキップする | E-06 (行6: `%w[a figcaption pre code]`) | ○ |
| C-50 | scrubはpreタグ内をスキップする | E-06 (行6: `%w[a figcaption pre code]`) | ○ |
| C-51 | scrubはfigcaptionタグ内をスキップする | E-06 (行6: `%w[a figcaption pre code]`) | ○ |
| C-52 | scrubはリンクなしテキストを変更しない | E-06 (行30: `node.replace(replacement) if replacement`) | ○ |
| C-53 | scrubは複数URLを処理する | E-06 (行60: `text.scan(AUTOLINK_REGEXP)`) | ○ |
| C-54 | scrubはURLとメールの混在を処理する | E-06 (行16, 60: AUTOLINK_REGEXPの構成) | ○ |
| C-55 | scrubはrel属性を設定する | E-06 (行49: `rel: "noopener noreferrer"`) | ○ |
| C-56 | find_linksはHTTPS URLを検出する | E-06 (行15: `URI::DEFAULT_PARSER.make_regexp(%w[http https])`) | ○ |
| C-57 | find_linksはHTTP URLを検出する | E-06 (行15: `%w[http https]`) | ○ |
| C-58 | find_linksはメールアドレスを検出する | E-06 (行14, 16: `EMAIL_AUTOLINK_REGEXP`) | ○ |
| C-59 | find_linksは空文字列で空配列を返す | E-06 (行58-73: scanの動作) | ○ |
| C-60 | find_linksは位置情報を返す | E-06 (行62, 66: `start_pos`, `length`) | ○ |
| C-61 | clean_urlは末尾ピリオドを除去する | E-06 (行18-19, 77: `TRAILING_PUNCTUATION`, `sub`) | ○ |
| C-62 | clean_urlは末尾カンマを除去する | E-06 (行18: `.?,:!;"'<>`) | ○ |
| C-63 | clean_urlは末尾コロンを除去する | E-06 (行18: `.?,:!;"'<>`) | ○ |
| C-64 | clean_urlは末尾感嘆符を除去する | E-06 (行18: `.?,:!;"'<>`) | ○ |
| C-65 | clean_urlは末尾セミコロンを除去する | E-06 (行18: `.?,:!;"'<>`) | ○ |
| C-66 | clean_urlは末尾引用符を除去する | E-06 (行18: `.?,:!;"'<>`) | ○ |
| C-67 | clean_urlは複数句読点を除去する | E-06 (行19: `+\z`の正規表現) | ○ |
| C-68 | clean_urlは句読点なしURLをそのまま返す | E-06 (行77: `sub`の動作) | ○ |
| C-69 | autolink_text_nodeはリンクを含むテキストを変換する | E-06 (行37-55: autolink_text_nodeの実装) | ○ |
| C-70 | autolink_text_nodeはリンクのみのテキストを変換する | E-06 (行47-52: linksループ処理) | ○ |
| C-71 | autolink_text_nodeはリンクなしでnilを返す | E-06 (行41: `return nil if links.empty?`) | ○ |
| C-72 | autolink_text_nodeはmailto:リンクを生成する | E-06 (行69: `href: "mailto:#{email}"`) | ○ |

## 4) 不足情報（Unknown / Missing）
- なし - 全てのテストケースにソースコードの根拠あり

## 5) リスクフラグ（レビュー観点）
- 0: 低リスク - 全テストケースがソースコードに基づいて生成されている
- 注意点：
  - WebPush関連のテスト（C-23〜C-44）は外部ライブラリ（web-push gem）との連携があり、モック/スタブが必要
  - スレッドプール関連のテスト（C-23〜C-37）は並行処理のため、テスト実行順序に注意が必要
  - AutoLinkScrubberのテスト（C-45〜C-72）はNokogiri/Loofahとの連携があり、HTMLパース処理の理解が必要

## 6) レビュアーチェックリスト（最小）
- [ ] Fizzy.saas?の環境変数とファイル判定ロジックが正しくテストされているか
- [ ] Fizzy.db_adapterのデフォルト値分岐（SaaS/非SaaS）が正しくテストされているか
- [ ] Deployment::DatabaseResolverのプライマリDC判定ロジックが正しくテストされているか
- [ ] WebPush::Poolのスレッドプール初期化パラメータが正しくテストされているか
- [ ] WebPush::Poolの例外処理（ExpiredSubscription, OpenSSLError）が正しくテストされているか
- [ ] WebPush::Notificationのメッセージエンコード形式が正しくテストされているか
- [ ] AutoLinkScrubberの除外要素（a, figcaption, pre, code）が全て網羅されているか
- [ ] AutoLinkScrubberのURL/メール検出正規表現の境界条件が適切にテストされているか
- [ ] clean_urlの全ての末尾句読点（.?,:!;"'<>）が個別にテストされているか
