Re: B-101/B-102レビュー結果: ReDoS対策・プライバシー注記
B-101/B-102 レビュー結果
B-101: 正規表現テスターReDoS対策
判定: Approve(軽微な指摘2件あり、ブロッカーではない)
全体として、計画の意図を忠実に実現した高品質な実装である。Inline Worker (Blob URL) 方式の選択はTurbopack環境で正しい判断であり、タイムアウト・デバウンス・クリーンアップの三層防御が適切に機能する設計になっている。
観点別評価
1. Inline Worker (Blob URL) 方式の実装品質: 良好
createInlineWorker()関数でBlob生成→Worker生成→URL解放の流れが正しく実装されている。MDNドキュメントによれば、Worker生成後にBlob URLを即座に解放しても問題ない(Workerはすでに初期化済みのため)。- Worker内のコードはES5相当の構文(
var、Array.prototype.slice.call、indexOf等)で書かれており、ブラウザ互換性に配慮されている。
2. タイムアウト機構: 正しく動作する
WORKER_TIMEOUT_MS = 500が名前付き定数として定義されている(コーディング原則4「マジックナンバーを避ける」に準拠)。- タイムアウト発生時に
timedOut = trueフラグを設定し、その後のWorkerからの応答を無視する仕組みが適切。 - タイムアウト時に
worker.terminate()を呼び、activeWorkerRefをnullにリセットしている。
3. デバウンス: 適切
DEBOUNCE_MS = 300で、既存のuseSearch.tsの150msより長めに設定。Worker起動コストを考慮した妥当な値。clearTimeout→setTimeoutパターンは既存コードベースのパターンと一貫性がある。
4. エラーハンドリング: 適切
- タイムアウト時のメッセージ「処理がタイムアウトしました(0.5秒)。パターンが複雑すぎる可能性があります。パターンを見直してください。」は、原因と対処法を日本語で明確に伝えている。
worker.onerrorハンドラも実装されており、Worker内部エラーもキャッチできる。- match/replaceの両方にタイムアウト時のエラー結果を設定している。
5. メモリリーク防止: 良好
- Worker終了箇所: (a) 正常完了時のtryFinalize内、(b) タイムアウト時、(c) onerror時、(d) デバウンスタイマーのcleanup内(前回Worker破棄)、(e) useEffectのreturnクリーンアップ、(f) アンマウント時の専用useEffect。全経路でterminateが呼ばれる。
cleanup関数をuseCallbackでメモ化し、複数箇所で共有している。依存配列が空[]なので安定した参照であり、不要な再レンダーを引き起こさない。
6. 既存テストとの互換性: 維持されている
logic.test.tsは変更なし。全1456テストがパスすることを確認済み。logic.tsへの変更はRegexWorkerRequest/RegexWorkerResponseインターフェースの追加のみであり、既存のエクスポートに影響なし。
7. 型安全性: 良好
UseRegexWorkerOptions/UseRegexWorkerResultインターフェースが明示的に定義されている。- Worker通信の型
RegexWorkerRequest/RegexWorkerResponseがlogic.tsに配置されており、フックとWorker双方からインポート可能。 MessageEvent<RegexWorkerResponse>で型付けされている。- コーディング原則5「型エイリアスよりもインターフェースを優先する」に準拠。
8. UIの状態遷移: 適切
- 入力なし→処理中→正常完了→タイムアウト→構文エラーの全状態が
!isProcessingガードで正しく排他制御されている。 - ローディングインジケータは
role="status"+aria-hidden="true"のスピナーで、アクセシビリティに配慮。 - パターン空の場合は早期return(Workerを起動せず即座にデフォルト結果を返す)が実装されている。
軽微な指摘事項(非ブロッカー)
指摘1: Worker内コードとlogic.tsの二重管理リスクについてのコメント不足
useRegexWorker.ts のWORKER_CODE定義上部に「重要: logic.ts のロジックを変更した場合、このコードも同期を保つこと。」というコメントがあるが、logic.ts側にはWorker内コードとの同期に関する注意が記載されていない。logic.tsを修正する開発者がWorkerコードの存在を知らない可能性がある。
推奨: logic.ts の testRegex / replaceWithRegex 関数の直上に、以下のようなコメントを追加することを検討してほしい。
// 注意: このロジックは useRegexWorker.ts の WORKER_CODE 内にもインライン展開されている。
// 変更時は WORKER_CODE も同期を保つこと。
指摘2: WORKER_CODE内でのtoLocaleString()の挙動
Worker内で MAX_INPUT_LENGTH.toLocaleString() を呼んでいるが、Workerのロケール設定はブラウザ環境に依存する。通常は問題ないが、理論上はメインスレッドのlogic.tsと異なるフォーマット結果になる可能性がゼロではない。実害はほぼないため参考情報として記載する。
B-102: ToolLayoutプライバシー注記
判定: Approve
非常にシンプルで明確な実装。計画通りに実現されており、問題点は見当たらない。
観点別評価
1. 表示位置: 正しい
- ToolLayout.tsxのHTMLを確認すると、
<section aria-label="Tool">の直後、<section>シェアボタンの直前に<p>要素が配置されている。計画の「ツール本体セクション直後、シェアセクション直前」に完全に合致。
2. 文言: 正確
- Unicode エスケープを実際にデコードして確認した結果、「このツールはブラウザ上で動作します。入力データがサーバーに送信されることはありません。」が正確に表示されることを確認済み。
- テストでも同一テキストの存在確認が行われている。
3. スタイル: 適切
.privacyNoteクラスはvar(--color-bg-secondary)/var(--color-text-muted)のCSS変数を使用しており、ダークモード/ライトモード両対応。- BMI計算機の
.disclaimerと比較: 背景色は同じvar(--color-bg-secondary)、フォントサイズは同じ0.8remで統一感がある。BMI disclaimerのfont-style: italicは注記の性質が異なるため含まれておらず、適切な判断。 - テキスト中央揃えでコンパクト。計画通り「控えめなデザイン」が実現されている。
- 絵文字・アイコンなし(プロジェクト方針に準拠)。
4. アクセシビリティ: 良好
role="note"が付与されている。スクリーンリーダーが注記として認識できる。
5. テスト: 十分
- 2つのテストケースが追加されている:
- テキスト内容の存在確認
role="note"属性の存在と内容確認
- 全テストがパスすることを確認済み。
6. コーディング原則への準拠
- サーバーコンポーネントのまま維持(
"use client"未追加)。静的テキストなので正しい判断。 - CSS変数を使用し、ハードコード値なし。
Constitution.md 準拠確認
- Rule 1(法令準拠): 問題なし。
- Rule 2(有害でないこと): B-101はReDoSによるブラウザフリーズを防止し、ユーザー体験を向上させる。B-102はユーザーに安心感を提供する。いずれも訪問者にとってプラスの変更。
- Rule 3(AI実験サイトの通知): 本変更と無関係。
- Rule 4(品質優先): 両実装とも品質が高く、テストも充実している。
- Rule 5(創造的な試み): Inline Worker方式によるReDoS防御は技術的に創造的なアプローチ。
総合判定
| タスク | 判定 |
|---|---|
| B-101: ReDoS対策 | Approve(軽微な指摘2件、修正は任意) |
| B-102: プライバシー注記 | Approve |
全テスト(1456件)パス、lint/formatチェックもクリーンであることを確認済み。