Coverband に「時系列」という観点を追加して、AI と繋いだ
私たち GLOBIS DevEx チームは、日頃から Claude Code を Workflow に取り入れ、開発体験向上を行っている。
私は Coverband のデータをもとに不要コードを定期的に提案する仕組み(ゴール: PR 自動作成)を模索していた。しかし、Coverband が教えてくれるのは「今この瞬間のスナップショット」だけ。いつ実行されたのか、本当に使われていないのか を判断するには、情報が足りなかった。
Datadog APM, Logging を利用している為、最初は Datadog MCP を利用して解析を試みたが、保存期間の問題で挫折した。
課題の深掘り:Coverband だけでは分からなかったこと
Coverband は幅広く利用されている、素晴らしいツール。
本番環境で実際に実行されたコード行を記録し、デッドコードの発見に役立てられる。
しかし、実際に運用してみるとやり辛さがあった。
既存 Endpoint での /json リターンではファイル単位
WebGUI ではファイルを指定することで、行単位の実行回数を確認する事ができるが、json return の場合には File 単位のため、調査用 CLI でグリグリ回すには不便だった。
{
"total_files": 2632,
"lines_of_code": 52915,
"lines_covered": 45827,
"lines_missed": 7088,
"covered_strength": 1428693.8249078724,
"covered_percent": 86.60493243881697,
"files": {
"app/hoge/fugafuga.rb": {
"filename": "/webapp/app/hoge/fugafuga.rb",
"hash": "3b362c3af2c678c2d6237d73e8b02b82c35b64cd",
"never_loaded": false,
"runtime_percentage": 57.14,
"lines_of_code": 28,
"lines_covered": 16,
"lines_runtime": 16,
"lines_missed": 0,
"covered_percent": 100.0,
"covered_strength": 6785.8
},
~~~~ 以下略 ~~~~
累積カウントとリセットの重み
Coverband は実行回数を累積でカウントする。
問題はカウンターをリセットしたとき、リセットは対象ファイル又は、全ファイルに影響するため、「先週までは動いていたコード」と「本当に使われていないコード」の区別がつかなくなる。
デプロイのたびに「今回のリリースで影響を受けたのはどこか」を知りたいのに、最新情報のみではそれが分からない。
「時系列で追えたら…」というひらめき
「最新情報だけじゃなくて、時系列データで追えたらいいのでは?」
元々監視データの生値をいじってたこともあり、毎時カバレッジデータを取得して差分を計算すれば、「この 1 時間で何行実行されたか」が分かる。それを積み重ねれば、「過去 90 日間、一度も実行されていないメソッド」を高い確度で特定できるのでは?と。
(Aurora MySQL Instance にデータ保存しているが1年分で 30 GB程度の為、長期間データを保存できる)
さらに、時系列データがあれば:
- デプロイ後の影響確認:リリース前後でカバレッジがどう変わったか、利用タイミング含めて可視化が可能
- デッドコードの確信度向上:「3 ヶ月動いていない」という根拠
- コード品質の傾向分析:カバレッジの推移をグラフで可視化
これらを実現するには、Coverband から行レベルのカバレッジデータをプログラマティックに取得する必要があった。
Slack つぶやきからの、OSS コントリビュート の背景と翌日マージの体験
冒頭にも記載した通り、既存の Coverband では CLI では /json で Return される内容は File 単位のため、Slackで、「行単位で取れなくてつらー」と、呟いていた。
すると、我らがリーダ @technuma が光の速さで PR を出してくれました。

Coverband のコードを読むと、JSONReport クラスは既に line_coverage オプションをサポートしていた。しかし、HTTP の /json エンドポイントからはこのオプションにアクセスできなかった。
必要なのは、4 行の変更だった。
# web.rb への追加
line_coverage = request.params['line_coverage'] == 'true'
# ...
Coverband::Reporters::[JSONReport.new](http://JSONReport.new)(store, {
line_coverage: line_coverage
}).report
1 月 16 日
- PR #601 を作成。タイトルは "Add line_coverage param to /json endpoint"。翌日にはメンテナーからレビューが入り、そのままマージされた。
1 月 20 日
- v6.1.7 Tag が付与された
1 月 21 日
- 弊社プロダクト本番環境で Version Up PR が Merge され、HTTP 経由で行レベルカバレッジデータを
/json?line_coverage=true"で取得できるようになった。
{
"total_files": 2632,
"lines_of_code": 52923,
"lines_covered": 45854,
"lines_missed": 7069,
"covered_strength": 1436771.0582922336,
"covered_percent": 86.64285849252688,
"files": {
"app/hoge/fugafuga.rb": {
"filename": "/webapp/app/hoge/fugafuga.rb",
"hash": "3b362c3af2c678c2d6237d73e8b02b82c35b64cd",
"never_loaded": false,
"runtime_percentage": 57.14,
"lines_of_code": 28,
"lines_covered": 16,
"lines_runtime": 16,
"lines_missed": 0,
"covered_percent": 100.0,
"covered_strength": 6848.4,
##### 各行が何回実行されたかを List 形式で取得 #####
"coverage": [
null,
null,
15638,
15638,
15638,
null,
15638,
null,
15638,
12,
12,
12,
null,
12,
null,
null,
15638,
12,
12,
12,
12,
null,
null,
12,
null,
null,
15638,
null
]
},
~~~~ 以下略 ~~~~
社内にはエンジニアが検証に自由に使える AWS アカウント (SUNABA) が存在するので、ひとまず EventBridge, Lambda, RDS を用意して毎時 Json を取得し MySQL に保存しデータ蓄積を始めた。
2 週間で作った coverband-timeline:開発タイムライン
PR がマージされた 1 ヶ月後、プロダクト開発の傍ら隙間時間で Claude Code と共に coverband-timeline の開発を始めた。
開発の時系列
| 日付 | 内容 |
|---|---|
| 2/27 | 初回コミット。基本構成(バッチ + ビューア)を実装 |
| 3/2〜6 | インフラ整備。GitHub Actions、ECR、k8s、ドメイン設定 |
| 3/9 | README 整備、社内共有開始 |
| 3/11 | コードビュー追加、git 履歴表示、MCP 機能追加 |
| 3/12 | Prism AST パーサによるメソッドレベルカバレッジ追加 |
| 3/13 | メソッド単位 git blame 連携、リモート MCP 対応 |
| 3/16 | リモート MCP マージ。完成形に |
約 2 週間で、MCP サーバー付きの時系列カバレッジ分析ツールが完成した。
アーキテクチャ解説:図解付きで構成を説明
coverband-timeline は、大きく 2 つのコンポーネントで構成される。
全体構成
今回相乗りさせた Schema/Table 情報
CREATE DATABASE IF NOT EXISTS coverband_timeline CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE coverband_timeline;
CREATE TABLE coverage_records (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
filename VARCHAR(512) NOT NULL,
file_hash VARCHAR(40) NOT NULL,
never_loaded BOOLEAN NOT NULL,
runtime_percentage DECIMAL(6,2) NOT NULL,
lines_of_code INT NOT NULL,
lines_covered INT NOT NULL,
lines_runtime INT NOT NULL,
lines_missed INT NOT NULL,
covered_percent DECIMAL(6,2) NOT NULL,
covered_strength DECIMAL(16,2) NOT NULL,
raw_coverage JSON NOT NULL COMMENT '差分計算用の生データ(累積値)',
diff_coverage JSON NOT NULL COMMENT '前回との差分(初回は0/null)',
created_at DATETIME NOT NULL,
UNIQUE INDEX idx_file_hash_time (filename, file_hash, created_at)
) ENGINE=InnoDB;
技術的な工夫
1. 差分計算ロジック
Coverband のカウントは累積値なので、前回取得時との差分を計算して「この 1 時間で何行実行されたか」を記録する。
2. file_hash によるファイル変更検知
ファイルが変更されると行番号がずれる。Coverband が返す file_hash を監視し、hash が変わったら旧データを物理削除して初回扱いにする。
3. Prism AST パーサによるメソッドレベル分析
Ruby 3.3 の Prism パーサを使い、ソースコードから各メソッドの開始行・終了行を抽出。行単位のカバレッジデータと突き合わせて、メソッドごとの active/dead 判定を行う。
4. git blame 連携
メソッド単位で最終コミット情報を取得(4 並列で高速化)。「90 日以上コミットがない dead method」のような期間指定フィルタを実現。
5. 本番デプロイに合わせて最新 Code, Commit 情報取り込み Deploy
coverband-timeline では内部にプロダクト Code と、Git Commit 情報を抱えてる。
これは Viewer や MCP で利用する時に Json で得られる行番号に対して Code を当てる際に利用。
その為、本番デプロイ時に GitHub Apps 経由で coverband-timeline の GHA を Kick し、Code 更新に合わせてデプロイ。
6. 応答性能調整
API Request 時に行計算や、Commit 情報を検索すると API Return が重くなるため、CD の中で全部のデータを集約、Container に保存しておく事で Viewer や MCP 利用時の API Return 性能を確保
AI との連携:MCP サーバーで Claude Code と繋ぐ
coverband-timeline のメイン機能は、MCP(Model Context Protocol)サーバーの組み込み。
MCP とは
MCP は、AI アシスタントが外部ツールやデータソースにアクセスするための標準プロトコル。Claude Code は MCP サーバーに接続し、定義されたツールを呼び出せる。
提供ツール一覧
| ツール名 | 機能 |
|---|---|
coverband_stats |
カバレッジ統計サマリー |
coverband_files |
ファイル一覧(検索・フィルタ・ソート) |
coverband_file_timeline |
特定ファイルのカバレッジ時系列推移 |
coverband_file_coverage |
行レベルカバレッジ差分 |
coverband_file_source |
ソースコード取得 |
coverband_git_info |
デプロイ済みコミット情報 |
coverband_file_methods |
メソッド別カバレッジ + git 情報 |
coverband_dead_methods |
複数ファイル横断の dead method 検索 |
実際の活用シーン
Claude Code に「dead method を探して削除 PR を作って」と指示すると:
-
coverband_dead_methodsで dead method 一覧を取得 -
coverband_file_methodsで各メソッドの git 情報を確認 -
coverband_file_sourceでソースコードを取得 - 削除しても安全か判断し、PR を作成
これにより、「coverband のデータをもとに不要コードを定期提案(PR 自動作成)」という当初の目標が、AI との対話形式 で実現。
しかし、機能開発途中の今後1,2週間で導線が用意される機能や、来季から公開される機能などは Count UP されないので、Dead Code 対象として検知される
精度向上のためにも、もう一工夫が必要な状況
Schema/Table が利用可能な為、何かしら永続的なデータを保存しておくことで対応できないか手探り中。
得られた効果・気づき
デッドコード削除の確信度が上がった
「過去 90 日間、1 度も実行されていない」「最後のコミットは 1 年前」という情報があれば、自信を持って削除できる。月次バッチの罠にも引っかからない。
デプロイの影響が可視化された
リリース前後のカバレッジ推移を見れば、「新機能が本番で使われ始めた」「この変更で既存コードのカバレッジが下がった」が分かる。
学び:小さな観点追加の力
既存の OSS に「時系列」という 1 つの観点を追加しただけで、できることが大きく広がった。
既存ツールに観点を追加して拡張するアプローチ
今回のプロジェクトで学んだことは 3 つ。
-
既存 OSS に欠けている観点を見つけ、自分で埋める
Coverband は素晴らしいツールだが、「時系列」という観点が欠けていた。それを追加することで、新しい価値が生まれた。
当初、時系列データの話をしたら OSS に直に PR を出すんだ。と言われたがチキンな私にはかなりハードルが高かったので fork することも検討したが、メンテナンスが大変なので挫折。
Endpoint 利用の形で切り出す事で、自由度が増した。 -
小さな OSS コントリビュートでも、大きな影響を与えられる
4 行の PR が、外部ツール連携の扉を開いた。完璧な大機能より、小さくても意味のある変更を。 -
AI との連携は、MCP で簡単に実現できる
MCP サーバーを組み込むことで、開発ツールが「AI の目と手」になる。
今回初めて Remote MCP を用意、利用したが、便利すぎた。
GLOBIS DevEx チーム



