付録: Ground Truth 全75項目の評価詳細
Express.js v5.2.1(+ router@2.2.0、finalhandler@2.1.1)のソースコードを精読し、タスク4(エラーハンドリング設計)33項目、タスク5(ミドルウェア設計)42項目、計75項目の正解チェックリストを作成しました。各ツールの出力をこのチェックリストと照合し、1ページ目「Recall」セクションの評価基準に従って評価しています。
| 記号 | 意味 | スコア |
|---|
| ◎ | 正確かつソースコード(ファイル名・行番号)の根拠あり | 1.00 |
| ○ | 概念的に正確(コード根拠なし) | 0.75 |
| △ | 部分的にカバー | 0.50 |
| × | 不到達・言及なし | 0 |
| - | ツールの構造上、返却不可能(0点扱い。全ツール共通で75項目を分母に算出) | — |
略称: cbm = codebase-memory-mcp(初回 = lib 6ファイルのみ、設定後 = router/finalhandler 追加)、cg = codegraph(初回 = explore のみ、設定後 = node/callers 併用)、cn = cognee(H4.5 = Haiku 4.5 / lib 6ファイル、S5 = Sonnet 5 / 10ファイル)
Task 4: エラーハンドリング設計(33項目)
| # | 検証項目 | grep | cbm (初回) | cbm (設定後) | cg (初回) | cg (設定後) | cn (H4.5) | cn (S5) |
|---|
| A. 基本メカニズム(5項目) | | | | | | | |
| 1 | エラーハンドラは引数4つ(err, req, res, next)で判別される仕組みを説明できたか | △ | × | ◎ | ○ | ◎ | ○ | ○ |
| 2 | エラー発生時に4引数ハンドラだけを呼び出す内部関数を特定できたか | × | × | ◎ | △ | ◎ | ○ | ○ |
| 3 | 通常リクエスト時にエラーハンドラをスキップする仕組みを説明できたか | × | × | ◎ | △ | ◎ | ○ | ○ |
| 4 | next(err) を呼ぶとエラーモードに切り替わることを説明できたか | ○ | × | ○ | × | ◎ | ○ | ○ |
| 5 | ハンドラの例外が try/catch で捕捉され next(err) に変換されることを説明できたか | × | × | ◎ | × | ◎ | ○ | ○ |
| B. エラーフロー(5項目) | | | | | | | |
| 6 | ルート内部でエラーが発生した際の分岐処理を説明できたか | × | × | ◎ | × | ◎ | △ | ○ |
| 7 | ルーターがエラーをミドルウェアスタック全体に伝播するループを説明できたか | × | × | ◎ | △ | ◎ | ○ | ○ |
| 8 | エラーモード中はルート層がスキップされることを説明できたか | × | × | ◎ | × | ◎ | △ | ○ |
| 9 | パスプレフィックス除去後にエラーハンドラへ渡される経路を特定できたか | × | × | ○ | × | ◎ | × | △ |
| 10 | 全ミドルウェアを通過してもエラーが処理されなかった場合の終端処理を説明できたか | × | △ | ◎ | × | ◎ | × | ○ |
| C. Finalhandler(7項目) | | | | | | | |
| 11 | 全ミドルウェアを通過したエラーの最終受け皿がどこで生成されるか特定できたか | × | △ | ◎ | △ | ◎ | ○ | ○ |
| 12 | どのルートにもマッチしなかった場合に 404 を返す仕組みを説明できたか | × | × | ◎ | △ | ◎ | ○ | ○ |
| 13 | エラーオブジェクトからステータスコードを取得する仕組みを説明できたか | × | × | ○ | × | ◎ | △ | ○ |
| 14 | ステータス未指定時にデフォルト 500 になることを説明できたか | × | × | △ | × | ◎ | △ | ○ |
| 15 | 開発環境と本番環境でエラーレスポンスの詳細度が変わることを説明できたか | × | × | ◎ | × | ◎ | ○ | ○ |
| 16 | レスポンス送信済みの場合にソケットを破棄する挙動を説明できたか | × | × | ◎ | △ | ◎ | × | ○ |
| 17 | エラーレスポンスに CSP 等のセキュリティヘッダが付与されることを説明できたか | × | × | ◎ | × | ◎ | × | ○ |
| D. Express v5 固有(3項目) | | | | | | | |
| 18 | async ハンドラの Promise rejection が自動的に next(err) に変換されることを説明できたか | × | × | ◎ | ○ | ◎ | ○ | ○ |
| 19 | Express v5 でルーターが外部パッケージ(router@2.x)に分離されたことを説明できたか | × | △ | × | ○ | ○ | × | × |
| 20 | thenable オブジェクトに対する非推奨警告の存在を説明できたか | - | × | ◎ | × | ◎ | × | ○ |
| E. センチネル値(2項目) | | | | | | | |
| 21 | next('route') で現在のルートをスキップするフロー制御を説明できたか | × | × | ◎ | × | ◎ | ○ | ○ |
| 22 | next('router') でルーター全体を抜ける仕組みを説明できたか | × | × | ◎ | × | ◎ | ○ | ○ |
| F. Sub-app エラー伝播(1項目) | | | | | | | |
| 23 | サブアプリ内のエラーが親アプリにバブリングする仕組みを特定できたか | × | ○ | ◎ | ◎ | ◎ | × | × |
| G. 設計意図(5項目) | | | | | | | |
| 24 | 引数の数で通常 MW とエラー MW の責務が分離される設計を説明できたか | △ | × | ◎ | ○ | ◎ | ○ | ○ |
| 25 | Express にデフォルトのエラー MW が存在しない設計判断を説明できたか | - | × | △ | △ | △ | △ | △ |
| 26 | エラーハンドリングにはユーザーが明示的に MW を登録する必要があることを説明できたか | × | × | △ | △ | △ | △ | △ |
| 27 | エラー MW は app.use() でのみ登録可能であることを説明できたか | △ | × | ○ | × | ○ | △ | △ |
| 28 | 同期的な next() 連鎖のスタックオーバーフロー防止策を説明できたか | - | × | ◎ | × | ◎ | × | ○ |
| H. その他エラー源(5項目) | | | | | | | |
| 29 | res.format() で Accept ヘッダに一致する形式がない場合の 406 エラーを特定できたか | ◎ | ◎ | × | × | × | × | × |
| 30 | テンプレートレンダリングのエラーが next(err) 経由で伝播することを説明できたか | ○ | ○ | × | △ | ○ | △ | × |
| 31 | res.sendFile() のエラーハンドリング(EISDIR 等)を説明できたか | × | ○ | × | × | ◎ | × | × |
| 32 | URL パラメータのデコード失敗時に 400 エラーが発生する仕組みを特定できたか | × | × | △ | × | ◎ | × | △ |
| 33 | テスト環境以外でエラーが console.error に出力される仕組みを特定できたか | ○ | ○ | △ | △ | ◎ | × | × |
Task 5: ミドルウェア設計(42項目)
| # | 検証項目 | grep | cbm (初回) | cbm (設定後) | cg (初回) | cg (設定後) | cn (H4.5) | cn (S5) |
|---|
| A. コアアーキテクチャ(5項目) | | | | | | | |
| 34 | Express アプリが関数として生成されるファクトリパターンを特定できたか | × | ◎ | ◎ | ◎ | ◎ | △ | ○ |
| 35 | リクエスト処理が app からルーターに委譲される流れを説明できたか | × | ○ | ◎ | △ | ◎ | △ | ○ |
| 36 | ルーターが Layer の順序付き配列でミドルウェアを管理することを説明できたか | × | × | ◎ | △ | ◎ | ○ | ○ |
| 37 | ミドルウェア層とルート層が内部的に区別されることを説明できたか | × | × | ◎ | × | ◎ | × | ○ |
| 38 | Route が独自のハンドラスタックを持ちメソッド別にディスパッチすることを説明できたか | × | × | ◎ | × | ◎ | × | ○ |
| B. 登録(4項目) | | | | | | | |
| 39 | app.use() がプレフィックスマッチ(前方一致)で登録されることを説明できたか | × | △ | ○ | ○ | ◎ | △ | ○ |
| 40 | app.get() 等がパスの完全一致で登録されることを説明できたか | × | × | △ | ○ | ◎ | × | ○ |
| 41 | Route にメソッド別のハンドラ Layer が追加される仕組みを特定できたか | × | × | ○ | × | ◎ | × | ○ |
| 42 | layer.route プロパティでミドルウェアとルートが判別される仕組みを特定できたか | × | × | ◎ | × | ◎ | × | ○ |
| C. ディスパッチフロー(6項目) | | | | | | | |
| 43 | ルーターの next() クロージャがスタックを順に走査する仕組みを説明できたか | × | × | ◎ | △ | ◎ | ○ | ○ |
| 44 | 各 Layer がリクエストパスとマッチングされる仕組みを説明できたか | × | × | ○ | × | ◎ | △ | ○ |
| 45 | マウントパスが除去されて req.url が書き換わる仕組みを特定できたか | × | × | ◎ | × | ◎ | × | ○ |
| 46 | Route が対応する HTTP メソッドをチェックする仕組みを特定できたか | × | × | ◎ | × | ◎ | × | ○ |
| 47 | Route 内部で HTTP メソッドによるハンドラのフィルタリングを特定できたか | × | × | ◎ | × | ◎ | × | ○ |
| 48 | エラーモード中にルート層がスキップされる挙動を説明できたか | × | × | ◎ | × | ◎ | △ | ○ |
| D. next() メカニズム(5項目) | | | | | | | |
| 49 | next() を引数なしで呼ぶと次のミドルウェアに進むことを説明できたか | ○ | × | ◎ | ○ | ◎ | ○ | ○ |
| 50 | next(err) でエラーモードに入りルートがスキップされることを説明できたか | ○ | × | ◎ | ○ | ◎ | ○ | ○ |
| 51 | next('route') で現在のルートをスキップする仕組みを説明できたか | × | × | ◎ | × | ◎ | ○ | ○ |
| 52 | next('router') でルーター全体を抜ける仕組みを説明できたか | × | × | ◎ | × | ◎ | ○ | ○ |
| 53 | 同期的な next() 連鎖のスタックオーバーフロー防止策を説明できたか | × | × | ◎ | × | ◎ | × | ○ |
| E. エラーハンドリング(4項目) | | | | | | | |
| 54 | 関数の引数の数でハンドラの種類を判別する仕組みを説明できたか | × | × | ◎ | ○ | ◎ | ○ | ○ |
| 55 | 通常リクエスト処理時にエラーハンドラ(引数4つ)がスキップされることを説明できたか | × | × | ◎ | ○ | ◎ | △ | ○ |
| 56 | エラー処理時に通常ハンドラ(引数3つ)がスキップされることを説明できたか | × | × | ◎ | × | ◎ | × | ○ |
| 57 | エラーが4引数ハンドラに到達するまで伝播し続けることを説明できたか | × | × | ○ | × | ◎ | ○ | ○ |
| F. パスハンドリング(4項目) | | | | | | | |
| 58 | マウントポイントでパスプレフィックスが除去される仕組みを特定できたか | × | × | ◎ | × | ◎ | △ | ○ |
| 59 | req.baseUrl にマウントプレフィックスが反映されることを説明できたか | × | × | ◎ | × | ◎ | × | ○ |
| 60 | ルーター処理後に req のプロパティが復元される仕組みを特定できたか | × | △ | ◎ | × | ◎ | × | △ |
| 61 | req.originalUrl がルーティング中も書き換えられないことを説明できたか | × | × | ○ | × | ○ | △ | × |
| G. Promise サポート(3項目) | | | | | | | |
| 62 | ハンドラが Promise を返した場合に自動検出される仕組みを説明できたか | × | × | ◎ | ○ | ◎ | ○ | ○ |
| 63 | Promise の rejection が自動的に next(error) に変換されることを説明できたか | × | × | ◎ | ○ | ◎ | △ | ○ |
| 64 | async ミドルウェアで try/catch を書かなくてもエラーが伝播することを説明できたか | × | × | ◎ | × | ◎ | × | ○ |
| H. パラメータ処理(3項目) | | | | | | | |
| 65 | ルートパラメータの前処理コールバックを登録する仕組みを説明できたか | × | △ | ○ | × | ◎ | × | ○ |
| 66 | ハンドラ実行前にパラメータコールバックが走る仕組みを特定できたか | × | × | ◎ | × | ◎ | × | ○ |
| 67 | 同じパラメータ値に対するコールバックの再実行がキャッシュで防止されることを特定できたか | × | × | ◎ | × | ◎ | × | ○ |
| I. Sub-app(4項目) | | | | | | | |
| 68 | サブアプリを app.use() でマウントする仕組みを説明できたか | △ | ○ | ◎ | ◎ | ◎ | △ | ○ |
| 69 | Express が渡されたオブジェクトをサブアプリと判定する条件を特定できたか | × | ○ | △ | ◎ | ◎ | × | ○ |
| 70 | サブアプリ実行後に親アプリのプロトタイプを復元するラッパーを特定できたか | × | ◎ | ◎ | ◎ | ◎ | △ | ○ |
| 71 | マウント時に親アプリの設定が子に継承される仕組みを説明できたか | × | ○ | △ | ○ | ◎ | × | ○ |
| J. 高度な機能(4項目) | | | | | | | |
| 72 | OPTIONS リクエストに対して許可メソッドが自動応答される仕組みを説明できたか | × | × | ◎ | × | ◎ | × | ○ |
| 73 | HEAD リクエストが GET ハンドラにフォールバックする仕組みを説明できたか | × | × | ◎ | × | ◎ | × | ○ |
| 74 | 子ルーターのパラメータが親のパラメータと統合されるオプションを説明できたか | × | × | ◎ | × | ◎ | × | △ |
| 75 | Router がプロパティアクセス時に遅延初期化される仕組みを特定できたか | × | ◎ | × | × | ◎ | × | ○ |
集計
| ツール | ◎ | ○ | △ | × | - | 加重スコア | 全75項目比 |
|---|
| grep | 1 | 5 | 4 | 62 | 3 | 6.75 | 9.0% |
| codebase-memory-mcp(初回) | 4 | 8 | 6 | 57 | 0 | 13.00 | 17.3% |
| codebase-memory-mcp(設定後) | 52 | 10 | 8 | 5 | 0 | 63.50 | 84.7% |
| codegraph(初回 / explore のみ) | 5 | 13 | 13 | 44 | 0 | 21.25 | 28.3% |
| codegraph(設定後 / node+callers 併用) | 68 | 4 | 2 | 1 | 0 | 72.00 | 96.0% |
| cognee(Haiku 4.5 / lib 6ファイル) | 0 | 22 | 19 | 34 | 0 | 26.00 | 34.7% |
| cognee(Sonnet 5 / 10ファイル) | 0 | 61 | 7 | 7 | 0 | 49.25 | 65.7% |
codebase-memory-mcp(初回)は lib/ 6ファイルのみをインデックスしたデフォルト構成、(設定後)は index_repository で依存パッケージ(node_modules/router/、node_modules/finalhandler/)を追加した構成です。codegraph(初回)は explore コマンドのみの計測結果、(設定後)は node/callers コマンドを併用した結果です(詳細は2ページ目「インデックス範囲の設計」参照)。cognee は LLM を Sonnet 5 に変更し router/finalhandler を含む10ファイルに拡大して再計測。grep の「-」3項目は、不在の証明やランタイム固有の動作など、テキスト検索では原理的に回答できない項目です。カテゴリ別の加重スコアは2ページ目「カテゴリ別加重スコア」表を参照してください。