## 🚀 Omen
**AIは地雷がどこにあるかを知らずにコードを書いてしまいます。**
Omenは、AIアシスタントに必要なコンテキストを提供します。複雑度の高いホットスポット、隠れた依存関係、欠陥が発生しやすいファイル、開発者自身が認める技術的負債などです。1つのコマンドで見えない部分を明らかにします。
**なぜ「Omen」なのか?** 予兆(Omen)は、これから起こることの兆しで、良いことも悪いこともあります。コードベースには予兆がいっぱいあります。低い複雑度とクリーンなアーキテクチャは、スムーズな開発を示していますが、頻繁な変更、技術的負債、コードのクローンは、問題の予兆を告げています。Omenはこれらのシグナルを明らかにし、「一時的な修正」が本番環境で3周年を迎える前に対策を講じることができます。
## 🚀 クイックスタート
```bash
# すべての分析器を実行
omen analyze
# 分析器の確認
omen analyze --help
✨ 主な機能
複雑度分析 - コードの理解とテストの難易度
複雑度には2種類あります。
- 循環的複雑度:コード内の異なる実行パスの数をカウントします。
if、for、while、switch 文があるたびに新しいパスが作成されます。循環的複雑度が10の関数は、10通りの実行パスがあることを意味します。数値が高いほど、すべてのシナリオをカバーするために必要なテストケースが増えます。
- 認知的複雑度:人間がコードを読むのがどれだけ難しいかを測定します。深くネストされたコード(
if 文の中に for 文があり、その中にさらに if 文があるなど)は、フラットなコードよりも高いペナルティが課されます。2つの関数が同じ循環的複雑度を持っていても、ネストが深い方は追跡が難しいため、認知的複雑度が高くなります。
重要な理由:研究によると、複雑なコードはバグが多く、修正に時間がかかります。McCabeの1976年の論文では、複雑度が10を超える関数は大幅に保守が難しいことがわかっています。SonarSourceの認知的複雑度は、開発者を混乱させる実際の要因を測定することで、これをさらに発展させています。
💡 使用アドバイス
関数ごとの循環的複雑度を10未満、認知的複雑度を15未満に保ちましょう。
自己認識型技術的負債(SATD) - 開発者がショートカットを取ったことを認めるコメント
開発者が TODO: 後で修正する や HACK: これはひどいけれども動く と書くとき、彼らは技術的負債を作り、それを認めています。Omenはこれらのコメントを見つけ、タイプ別にグループ化します。
| カテゴリ |
マーカー |
意味 |
| 設計 |
HACK, KLUDGE, SMELL |
見直す必要のあるアーキテクチャのショートカット |
| 欠陥 |
BUG, FIXME, BROKEN |
未修正の既知のバグ |
| 要件 |
TODO, FEAT |
欠けている機能または不完全な実装 |
| テスト |
FAILING, SKIP, DISABLED |
壊れているまたは無効にされたテスト |
| パフォーマンス |
SLOW, OPTIMIZE, PERF |
動作するが、高速化する必要のあるコード |
| セキュリティ |
SECURITY, VULN, UNSAFE |
既知のセキュリティ問題 |
重要な理由:PotdarとShihabの2014年の研究では、SATDコメントはしばしばコードベースに数年間残ることがわかっています。残る時間が長いほど、コンテキストを忘れるため修正が難しくなります。MaldonadoとShihab (2015)は、設計上の負債が最も一般的で最も危険なタイプであることを示しています。
💡 使用アドバイス
SATDを毎週レビューしましょう。TODOが6か月以上古い場合は、修正するか削除しましょう。
デッドコード検出 - 存在するが実行されないコード
デッドコードには以下が含まれます。
- 呼び出されない関数
- 代入されるが使用されない変数
- インスタンス化されないクラス
return 文の後で実行されないコード
重要な理由:デッドコードは単なるゴミではありません。新しい開発者を混乱させ、重要なコードだと思わせます。ビルド時間とバイナリサイズを増やします。最悪のことに、バグを隠す可能性があります。誰かがデッドコードを実行すると思って「修正」すると、時間を無駄にします。Romanoら (2020)は、デッドコードが他のコード品質問題の強い予測因子であることを発見しました。
💡 使用アドバイス
デッドコードを削除しましょう。バージョン管理システムにより、必要に応じていつでも復元できます。
Gitチャーン分析 - ファイルが時間とともにどれだけ頻繁に変更されるか
チャーンは、Gitの履歴を調べ、以下をカウントします。
- 各ファイルが変更された回数
- 追加および削除された行数
- 一緒に変更されるファイル
チャーンが高いファイルは「ホットスポット」です。常に触られているため、以下の可能性があります。
- システムの中心部分(誰もが変更する必要がある)
- 設計が不十分(頻繁なバグ修正)
- 良い抽象化が欠けている(機能が追加され続ける)
重要な理由:NagappanとBallの2005年のMicrosoftでの研究では、コードのチャーンがバグの最良の予測因子の1つであることがわかっています。頻繁に変更されるファイルは、より多くの欠陥を持つ傾向があります。複雑度データと組み合わせることで、チャーンは複雑で頻繁に変更されるファイル、つまり最もリスクの高いコードを見つけるのに役立ちます。
💡 使用アドバイス
チャーンと複雑度がともに高いファイルは、リファクタリングを優先しましょう。
コードクローン検出 - 複数の場所に出現する重複コード
クローンには3種類あります。
| タイプ |
説明 |
例 |
| Type-1 |
完全なコピー(空白やコメントが異なる場合がある) |
コピー&ペーストされたコード |
| Type-2 |
同じ構造、異なる名前 |
変数名が変更された同じ関数 |
| Type-3 |
いくつかの変更が加えられた類似コード |
ほぼ同じことを行う関数 |
重要な理由:あるコピーのバグを修正するとき、他のすべてのコピーにも修正を適用する必要があります。Juergensら (2009)は、クローンされたコードは修正が一貫して適用されないため、大幅に多くのバグを持つことを発見しました。クローンが多いほど、更新時に1つを見逃す可能性が高くなります。
💡 使用アドバイス
2回以上コピーされたものは、おそらく共有関数にするべきです。重複率を5%未満に目標としましょう。
欠陥予測 - ファイルにバグが含まれる可能性
Omenは、複数のシグナルを組み合わせ、PMAT加重メトリクスを使用して欠陥の確率を予測します。
- プロセス メトリクス(チャーン頻度、所有権の拡散)
- メトリクス(循環的/認知的複雑度)
- 年齢(コードの年齢と安定性)
- 総 サイズ(コード行数)
各ファイルには0%から100%までのリスクスコアが付けられます。
重要な理由:すべてのものを平等にレビューすることはできません。Menziesら (2007)は、欠陥予測がチームに問題が発生する可能性の高いファイルにテストとコードレビューの焦点を当てるのに役立つことを示しています。Rahmanら (2014)は、単純なモデルでもバグを見つけるためのランダムなファイル選択よりも優れていることを発見しました。
💡 使用アドバイス
欠陥確率が70%を超えるファイルのコードレビューを優先しましょう。
変更リスク分析(JIT) - どのコミットがバグを引き起こす可能性が高いかを予測
Just-in-Time(JIT)欠陥予測は、最近のコミットを分析して、問題が発生する前にリスクの高い変更を特定します。ファイルレベルの予測とは異なり、JITはコミットレベルで動作し、Kameiら (2013)の要因を使用します。
| 要因 |
名前 |
測定内容 |
| LA |
追加された行数 |
追加が多いほどリスクが高い |
| LD |
削除された行数 |
削除は一般的に安全 |
| LT |
変更されたファイル内の行数 |
ファイルが大きいほどリスクが高い |
| FIX |
バグ修正 |
バグ修正コミットは問題のある領域を示す |
| NDEV |
開発者の数 |
ファイルに関与する開発者が多いほどリスクが高い |
| AGE |
ファイルの平均年齢 |
ファイルの安定性の指標 |
| NUC |
ユニークな変更 |
変更のエントロピーが高いほどリスクが高い |
| EXP |
開発者の経験 |
経験が少ないほどリスクが高い |
パーセンタイルベースのリスク分類:
リスクレベルは、JIT欠陥予測のベストプラクティスに従って、パーセンタイルベースのしきい値を使用します。固定のしきい値ではなく、コミットはリポジトリ自身の分布に対してランク付けされます。
| レベル |
パーセンタイル |
意味 |
| 高 |
上位5% |
P95+ - 特別な精査が必要 |
| 中 |
上位20% |
P80 - P95 - 追加の注意が必要 |
| 低 |
下位80% |
P80未満 - 標準的なレビュープロセス |
このアプローチは、欠陥予測研究の80/20の法則と一致しています。約20%のコード変更が約80%の欠陥を含んでいます。これにより、リポジトリの特性に関係なく、実行可能な結果が得られます。規律が整ったリポジトリはしきい値が低く、チャーンの高いリポジトリはしきい値が高くなります。
重要な理由:Kameiら (2013)は、JIT予測がコミット時にリスクの高い変更をキャッチし、バグが広がる前に対処できることを示しています。彼らのエフォートを考慮したアプローチは、固定のしきい値ではなくランキングを使用し、限られたレビューリソースを最もリスクの高い約20%のコミットに集中させます。Zengら (2021)は、単純なJITモデルが深層学習と同程度の精度(約65%)を達成し、より高い解釈可能性を持つことを示しています。
💡 使用アドバイス
PRをマージする前に omen analyze changes を実行して、追加のレビューが必要なコミットを特定しましょう。
PR/ブランチ差分リスク分析 - マージ前にブランチの全体的なリスクを評価
JIT分析が個々のコミットを調べるのに対し、差分分析はターゲットブランチに対するブランチ全体の累積的な変更を評価します。これにより、レビュアーはコードレビューに入る前に迅速なリスク評価を行うことができます。
使い方:
omen analyze diff --target main
omen analyze diff --target abc123
omen analyze diff --target main -f markdown
リスク要因:
| 要因 |
測定内容 |
リスクへの影響 |
| 追加された行数 |
導入された新しいコードの総量 |
コードが多いほど潜在的なバグが多い |
| 削除された行数 |
削除されたコード |
一般的にリスクを減らす(コードが少なくなる) |
| 変更されたファイル |
変更の広がり |
ファイルが多いほど連鎖的な問題が発生する可能性が高い |
| コミット数 |
ブランチ内のコミット数 |
多くのコミットはスコープの拡大を示す可能性がある |
| エントロピー |
変更の散らばり具合 |
エントロピーが高いほど変更が到処にある |
リスクスコアの解釈:
| スコア |
レベル |
推奨アクション |
| < 0.2 |
低 |
標準的なレビュープロセス |
| 0.2 - 0.5 |
中 |
注意深いレビュー、追加のテストを検討 |
| > 0.5 |
高 |
徹底的なレビュー、包括的なテストカバレッジを確保 |
出力例:
ブランチ差分リスク分析
==========================
ソース: feature/new-api
ターゲット: main
ベース: abc123def
リスクスコア: 0.31 (中)
変更内容:
追加された行数: 63
削除された行数: 2
変更されたファイル: 2
コミット数: 1
リスク要因:
エントロピー: 0.084
追加された行数: 0.118
削除された行数: 0.003
ファイル数: 0.050
コミット数: 0.005
注目すべき点:
- 追加行数が多く、削除行数が少ない - 新機能の追加、徹底的なレビューが必要
- 追加と削除がバランスしている - リファクタリング、動作が変わっていないことを確認
- コードのネット減少 - クリーンアップ/簡素化、一般的に良い兆し
- エントロピーが高い - 散らばった変更、関係のない修正がないか確認
- 多くのファイルが変更されている - 影響範囲が広い、統合テストを確保
CI/CDへの統合:
- name: PRリスク評価
run: |
omen analyze diff --target ${{ github.base_ref }} -f markdown >> $GITHUB_STEP_SUMMARY
重要な理由:コードレビューの時間は限られています。差分分析は、レビュアーが注意を集中する場所を優先順位付けするのに役立ちます。10行の変更がある低リスクのPRは、17のファイルに影響を与える中リスクのPRよりも精査が少なくて済みます。エントロピーメトリクスは、関係のない変更がまとめられたPRをキャッチするのに特に有用です。これらのPRはレビューが難しく、バグを導入する可能性が高いです。
💡 使用アドバイス
PRを作成する前に omen analyze diff を実行して、レビュアーがあなたの変更をどのように見るかを理解しましょう。高リスクのPRは、小さく焦点を絞った変更に分割することを検討してください。
技術的負債勾配(TDG) - 各ファイルの総合的な「健全性スコア」
TDGは、複数のメトリクスを組み合わせて単一のスコア(0 - 100のスケール、高いほど良い)を算出します。
| 構成要素 |
最大ポイント |
測定内容 |
| 構造的複雑度 |
20 |
循環的複雑度とネストの深さ |
| 意味的複雑度 |
15 |
認知的複雑度 |
| 重複 |
15 |
クローンコードの量 |
| 結合度 |
15 |
他のモジュールへの依存関係 |
| ホットスポット |
10 |
チャーンと複雑度の相互作用 |
| 時間的結合度 |
10 |
他のファイルとの同時変更パターン |
| 一貫性 |
10 |
コードスタイルとパターンの遵守 |
| エントロピー |
10 |
パターンエントロピーとコードの均一性 |
| ドキュメント |
5 |
コメントのカバレッジ |
重要な理由:技術的負債は金融的な負債と同じで、少しは良いが、多すぎると致命的です。Cunninghamが1992年にこの用語を作り出し、Kruchtenら (2012)がそれを測定し管理する方法を定式化しました。TDGは、時間の経過とともに追跡し、ファイル間で比較するための単一の数値を提供します。
💡 使用アドバイス
新しい機能を追加する前に、スコアが70未満のファイルを修正しましょう。平均TDGを時間の経過とともに追跡し、上がる方向に推移するようにしましょう。
依存関係グラフ - モジュールがどのように相互に接続されているか
Omenは、どのファイルが他のどのファイルをインポートしているかを示すグラフを作成し、以下を計算します。
- PageRank:最も「中心的」なファイル(多くのものが依存している)
- 媒介中心性:コードベースの異なる部分の「橋渡し」となるファイル
- 結合度:モジュールがどれだけ相互に接続されているか
重要な理由:結合度の高いコードは脆弱です。1つのファイルを変更すると、多くの他のファイルが壊れてしまいます。Parnasの1972年のモジュール性に関する論文では、良いソフトウェア設計はモジュール間の依存関係を最小限に抑えることが示されています。依存関係グラフは、アーキテクチャがクリーンな部分と複雑な部分を示します。
💡 使用アドバイス
PageRankが高いファイルは、特に安定していて十分にテストされている必要があります。どこでも「橋渡し」の役割を果たしているファイルは分割することを検討してください。
ホットスポット分析 - 複雑度と頻繁な変更が重なる高リスクファイル
ホットスポットは、複雑で頻繁に変更されるファイルです。簡単なファイルが頻繁に変更されても問題ありません。扱いやすいからです。複雑なファイルがめったに変更されなくても管理できます。放置しておけばいいからです。しかし、常に変更される複雑なファイルは、バグの温床になります。
Omenは、正規化されたチャーンと複雑度の 幾何平均 を使用してホットスポットスコアを計算します。
hotspot = sqrt(churn_percentile * complexity_percentile)
両方の要素は、経験的な累積分布関数(CDF)を使用して業界のベンチマークに対して正規化されるため、スコアはプロジェクト間で比較可能です。
- チャーンパーセンタイル:このファイルのコミット数が典型的なOSSプロジェクトと比較してどの位置にあるか
- 複雑度パーセンタイル:平均認知的複雑度が業界のベンチマークと比較してどの位置にあるか
| ホットスポットスコア |
深刻度 |
アクション |
| >= 0.6 |
重大 |
直ちに優先する |
| >= 0.4 |
高 |
レビューをスケジュールする |
| >= 0.25 |
中 |
監視する |
| < 0.25 |
低 |
健全 |
重要な理由:Adam Tornhillの「Your Code as a Crime Scene」では、ホットスポット分析が最も影響力のあるリファクタリング対象を見つける方法として紹介されています。彼の研究によると、少数のファイル(通常は4 - 8%)がほとんどのバグを含んでいます。Gravesら (2000)とNagappanら (2005)は、相対的なコードチャーンが強力な欠陥予測因子であることを示しています。
💡 使用アドバイス
上位3つのホットスポットからリファクタリングを開始しましょう。チャーンの高いファイルの複雑度を下げることは、最も高い投資効果が得られます。
時間的結合度 - 一緒に変更されるファイルは隠れた依存関係を明らかにする
2つのファイルが常に同じコミットで変更される場合、それらは時間的に結合されています。これはしばしば以下を明らかにします。
- インポート文では見えない 隠れた依存関係
- 一方のファイルの変更が他方のファイルの変更を必要とする 論理的な結合
- コピー&ペーストや一貫性のない抽象化による 偶発的な結合
Omenは、Gitの履歴を分析して、一緒に変更されるファイルのペアを見つけます。
| 結合強度 |
意味 |
| > 80% |
ほぼ常に一緒に変更される - おそらく強い依存関係 |
| 50 - 80% |
頻繁に結合される - 関係を調査する |
| 20 - 50% |
中程度に結合される - 偶然の可能性がある |
| < 20% |
弱く結合される - おそらく独立している |
重要な理由:Ballら (1997)は、AT&Tで最初に同時変更パターンを研究し、静的分析では見えないアーキテクチャの違反を明らかにすることを発見しました。BeyerとNoack (2005)は、時間的結合度が将来の変更を予測することを示しています。以前に一緒に変更されたファイルは、将来も一緒に変更される可能性が高いです。
💡 使用アドバイス
2つのファイルの時間的結合度が50%を超え、インポート関係がない場合、共有モジュールを抽出するか、統合することを検討してください。
コードの所有権/バスファクター - 知識の集中とチームのリスク
バスファクターは、「このコードがメンテナンス不能になる前に、何人が事故に遭わなければならないか」を問います。バスファクターが低いということは、知識が少数の人に集中していることを意味します。
Omenは、git blameを使用して以下を計算します。
- 主要なオーナー:コードの大部分を書いた人
- 所有権比率:一人の人が所有する割合
- 貢献者数:ファイルに触れた人の数
- バスファクター:コードの5%以上を貢献した主要な貢献者の数
| 所有権比率 |
リスクレベル |
意味 |
| > 90% |
高リスク |
単一障害点 |
| 70 - 90% |
中リスク |
知識の共有が限られている |
| 50 - 70% |
低リスク |
健全な分散 |
| < 50% |
非常に低い |
広い所有権 |
重要な理由:Birdら (2011)は、多くのマイナーな貢献者を持つコードは、明確な所有権を持つコードよりもバグが多いことを発見しましたが、一人の人に所有されるコードは組織的なリスクを生み出します。理想的なのは、モジュールごとに2 - 4人の重要な貢献者がいることです。Nagappanら (2008)は、組織的なメトリクス(所有権など)がコードのメトリクスだけでなく、欠陥を予測することを示しています。
💡 使用アドバイス
単一の所有権が80%を超えるファイルは、知識移譲の文書化が必要です。重要なファイルは、少なくとも2人が理解している必要があります。
CKメトリクス - オブジェクト指向設計の品質測定
Chidamber - Kemerer(CK)メトリクスセットは、オブジェクト指向設計の品質を測定します。
| メトリクス |
名前 |
測定内容 |
しきい値 |
| WMC |
クラスごとの加重メソッド数 |
メソッドの複雑度の合計 |
< 20 |
| CBO |
オブジェクト間の結合度 |
使用される他のクラスの数 |
< 10 |
| RFC |
クラスの応答 |
呼び出される可能性のあるメソッド |
< 50 |
| LCOM |
メソッドの凝集度の欠如 |
フィールドを共有しないメソッド |
< 3 |
| DIT |
継承ツリーの深さ |
継承チェーンの長さ |
< 5 |
| NOC |
子クラスの数 |
直接のサブクラス |
< 6 |
LCOM(凝集度の欠如) は特に重要です。LCOMが低いということは、クラス内のメソッドが同じインスタンス変数を使用していることを意味し、クラスが焦点を絞っています。LCOMが高いということは、クラスが関係のないことを行っているため、分割する必要がある可能性があります。
重要な理由:ChidamberとKemererの1994年の論文では、これらのメトリクスがオブジェクト指向の品質測定の基礎として確立されました。Basiliら (1996)は、これらを実証的に検証し、WMCとCBOが障害の発生率と強く相関することを発見しました。これらのメトリクスは何千回も引用され、オブジェクト指向設計分析の標準として残っています。
💡 使用アドバイス
複数のCKしきい値に違反するクラスは、リファクタリングの対象となります。高いWMCと高いLCOMは、しばしば分割すべき「神クラス」を示しています。
リポジトリマップ - LLMのコンテキスト用のPageRankでランク付けされたシンボルインデックス
リポジトリマップは、コードベースの重要なシンボルのコンパクトな要約を提供し、PageRankを使用して構造的な重要度でランク付けされます。これは、LLMのコンテキストウィンドウ用に設計されており、最も重要な関数と型が最初に表示されます。
各シンボルについて、マップには以下が含まれます。
- 名前と種類(関数、クラス、メソッド、インターフェース)
- ファイルの場所と行番号
- シグネチャ:迅速な理解のため
- PageRankスコア:他のシンボルがどれだけ依存しているかに基づく
- 入力/出力次数:依存関係の接続を示す
重要な理由:LLMsのコンテキストウィンドウは限られています。全体のファイルを詰め込むと、重要でないコードにトークンが浪費されます。BrinとPage (1998)によって開発されたPageRankは、グラフ内の構造的に重要なノードを特定します。コードに適用すると、コードベースを理解するために最も中心的なシンボルが明らかになります。
スケーラビリティ:Omenは、PageRankの計算に疎行列のべき乗反復アルゴリズムを使用しており、エッジの数O(E)に対して線形にスケーリングし、ノードの数O(V^2)に対して二次的にスケーリングするのではなく、25,000以上のシンボルを持つ大規模なモノレポを30秒以内で高速に分析することができます。
出力例:
# リポジトリマップ (PageRankで上位20のシンボル)
## parser.ParseFile (関数) - pkg/parser/parser.go:45
PageRank: 0.0823 | 入力: 12 | 出力: 5
func ParseFile(path string) (*Result, error)
## models.TdgScore (構造体) - pkg/models/tdg.go:28
PageRank: 0.0651 | 入力: 8 | 出力: 3
type TdgScore struct
💡 使用アドバイス
omen context --repo-map --top 50 を使用して、LLMのプロンプト用のコンテキストを生成しましょう。上位50のシンボルは、通常、エッセンシャルなアーキテクチャを捉えることができます。
フィーチャーフラグ検出 - コードベース全体のフィーチャーフラグを見つけて追跡する
フィーチャーフラグは強力ですが、危険性もあります。コードを有効にせずにリリースし、A/Bテストを実行し、機能を段階的にロールアウトすることができます。しかし、蓄積してしまいます。2019年の「一時的なフラグ」がまだ本番環境に残っているかもしれません。1週間の実験用に追加したフラグが、今では重要なインフラストラクチャになっているかもしれません。
Omenは、人気のあるプロバイダー全体でフィーチャーフラグの使用を検出します。
| プロバイダー |
言語 |
検出内容 |
| LaunchDarkly |
JS/TS、Python、Go、Java |
variation()、boolVariation() 呼び出し |
| Split |
JS/TS、Python、Go |
getTreatment() 呼び出し |
| Unleash |
JS/TS、Go |
isEnabled()、getVariant() 呼び出し |
| PostHog |
JS/TS、Python、Go、Java、Ruby |
isFeatureEnabled()、getFeatureFlag() 呼び出し |
| Flipper |
Ruby |
enabled?()、Flipper.enabled?() 呼び出し |
各フラグについて、Omenは以下を報告します。
- フラグキー:コードで使用される識別子
- プロバイダー:使用されているSDK
- 参照:フラグがチェックされるすべての場所
- 古さ:フラグが最初に変更された時期と最後に変更された時期(Gitの履歴を使用)
カスタムプロバイダー:社内のフィーチャーフラグシステムの場合は、omen.toml でカスタムのTree - Sitterクエリを定義します。
[[feature_flags.custom_providers]]
name = "feature"
languages = ["ruby"]
query = '''
(call
receiver: (constant) @receiver
(#eq? @receiver "Feature")
method: (identifier) @method
(#match? @method "^(enabled\\?|get_feature_flag)$")
arguments: (argument_list
.
(simple_symbol) @flag_key))
'''
重要な理由:Meinickeら (2020)は、オープンソースプロジェクト全体のフィーチャーフラグを研究し、フラグの所有権(フラグを導入した開発者がそれを削除すること)がフラグの寿命を短くすることに関連し、技術的負債を抑えるのに役立つことを発見しました。Rahmanら (2018)は、Google Chromeの12,000以上のフィーチャートグルを研究し、これらが迅速なリリースと柔軟なデプロイを可能にする一方で、技術的負債と追加のメンテナンス負担をもたらすことを発見しました。定期的なフラグ監査により、コードベースが未使用のトグルの迷路になるのを防ぎます。
💡 使用アドバイス
フィーチャーフラグを毎月監査しましょう。実験用のフラグは90日以上古いものを、リリースフラグは14日以上古いものを削除しましょう。CIパイプラインでフラグの古さを追跡しましょう。
リポジトリスコア - 総合的な健全性スコア(0 - 100)
Omenは、複数の分析次元を組み合わせた総合的なリポジトリ健全性スコア(0 - 100)を計算します。これにより、コードベースの品質を迅速に概観し、CI/CDでの品質ゲートを有効にすることができます。
スコアの構成要素:
| 構成要素 |
重み |
測定内容 |
| 複雑度 |
25% |
複雑度のしきい値を超える関数の割合 |
| 重複 |
20% |
非線形のペナルティ曲線を持つコードクローン率 |
| SATD |
10% |
1K LOCあたりのSeverity-weighted TODO/FIXME密度 |
| TDG |
15% |
技術的負債勾配の総合スコア |
| 結合度 |
10% |
循環依存、SDP違反、および不安定性 |
| 臭い |
5% |
コードベースのサイズに対するアーキテクチャの臭い |
| 凝集度 |
15% |
オブジェクト指向コードベースのクラスの凝集度(LCOM) |
正規化の哲学:
各構成要素のメトリクスは、常に高い値が良い0 - 100のスケールに正規化されます。正規化関数は以下のように設計されています。
- 公平性:同じ深刻度の異なるメトリクスは、同様のスコアを生成する
- 校正:SonarQube、CodeClimate、およびCISQの業界のベンチマークに基づく
- 非線形性:軽微な問題には緩やかなペナルティ、深刻な問題には急激なペナルティ
- 深刻度意識:影響に応じて項目に重みを付ける、単なるカウントではない
例えば、SATD(自己認識型技術的負債)は、深刻度に応じた重み付けスコアリングを使用します。
- 重大(SECURITY, VULN):4倍の重み
- 高(FIXME, BUG):2倍の重み
- 中(HACK, REFACTOR):1倍の重み
- 低(TODO, NOTE):0.25倍の重み
これにより、低深刻度の項目(ドキュメントのTODOなど)が不公平にスコアを下げることが防止されます。
TDG(技術的負債勾配)は、各ファイル内の構造的複雑度、意味的複雑度、重複パターン、および結合度を分析することで、補完的な視点を提供します。
使い方:
omen score .
omen score . -f json
しきい値の調整:
実際のコードベースでスコア100を達成することはほぼ不可能です。omen.toml でコードベースに基づいた現実的なしきい値を設定しましょう。
[score.thresholds]
score = 80
complexity = 85
duplication = 65
defect = 80
debt = 75
coupling = 70
smells = 90
omen score を実行して現在のスコアを確認し、それらの値よりも少し低いしきい値を設定しましょう。時間の経過とともに徐々に引き上げます。
Lefthookを使用してコミット時に強制する:
lefthook.yml に追加します。
pre-push:
commands:
omen-score:
run: omen score
これにより、品質しきい値を満たさないコードのプッシュが防止されます。
重要な理由:単一の健全性スコアにより、品質ゲートを有効にし、時間の経過とともにトレンドを追跡し、コードベースを迅速に評価することができます。重み付けされた総合スコアにより、重大な問題(欠陥、複雑度)が、表面的な問題よりも大きな影響を与えます。
💡 使用アドバイス
達成可能なしきい値から始め、コードベースを改善するにつれて引き上げましょう。レガシーコードでは、重複率が改善が最も難しいメトリクスであることが多いです。
MCPサーバー - モデルコンテキストプロトコルを介したLLMツールの統合
Omenには、Model Context Protocol(MCP)サーバーが含まれており、ClaudeなどのLLMに対してすべての分析器をツールとして公開します。これにより、AIアシスタントが標準化されたツール呼び出しを通じてコードベースを直接分析することができます。
利用可能なツール:
analyze_complexity - 循環的および認知的複雑度
analyze_satd - 自己認識型技術的負債の検出
analyze_deadcode - 未使用の関数と変数
analyze_churn - Gitファイルの変更頻度
analyze_duplicates - コードクローンの検出
analyze_defect - ファイルレベルの欠陥確率(PMAT)
analyze_changes - コミットレベルの変更リスク(JIT)
analyze_tdg - 技術的負債勾配のスコア
analyze_graph - 依存関係グラフの生成
analyze_hotspot - 高いチャーンと複雑度を持つファイル
analyze_temporal_coupling - 一緒に変更されるファイル
analyze_ownership - コードの所有権とバスファクター
analyze_cohesion - CKのオブジェクト指向メトリクス
analyze_repo_map - PageRankでランク付けされたシンボルマップ
analyze_smells - アーキテクチャの臭いの検出
analyze_flags - フィーチャーフラグの検出と古さ
score_repository - 総合的な健全性スコア(0 - 100)
get_context - 特定のファイルまたはシンボルの詳細なコンテキスト
各ツールには、解釈ガイド付きの詳細な説明が含まれており、LLMがメトリクスの意味と各分析器の使用時期を理解するのに役立ちます。
ツールの出力は、デフォルトでTOON (Token - Oriented Object Notation)形式になります。これは、LLMワークフロー用に設計されたコンパクトなシリアライゼーション形式で、JSONと比較してトークン使用量を30 - 60%削減しながら、高い理解精度を維持します。JSONおよびMarkdown形式も利用可能です。
重要な理由:LLMは、構造化されたツールにアクセスできる場合、非構造化な出力を解析するよりもうまく機能します。MCPは、LLMツール統合の新しい標準であり、Claude Desktopや他のAIアシスタントによってサポートされています。TOON出力は、コンテキストウィンドウ内の情報密度を最大化します。
💡 使用アドバイス
AIアシスタントでOmenをMCPサーバーとして構成し、「最も複雑な関数を見つける」や「技術的負債のホットスポットを表示する」などの自然言語クエリを有効にしましょう。
📦 インストール
Homebrew (macOS/Linux)
brew install panbanda/omen/omen
Go Install
go install github.com/panbanda/omen/cmd/omen@latest
バイナリのダウンロード
リリースページから事前にビルドされたバイナリをダウンロードします。
ソースからビルド
git clone https://github.com/panbanda/omen.git
cd omen
go build -o omen ./cmd/omen
🔧 設定
omen.toml または .omen/omen.toml を作成します(yaml、json、toml をサポート)。
omen init
すべてのオプションについては、 を参照してください。
💡 使用アドバイス
Claude Codeを使用している場合は、setup-config スキルを実行して、リポジトリを分析し、検出されたフィーチャーフラグプロバイダーや言語固有の除外パターンを含む、技術スタックに適した賢いデフォルト値を持つ omen.toml を生成しましょう。
MCPサーバーの設定
Claude Desktop
Claude Desktopの設定ファイル(macOSの場合は ~/Library/Application Support/Claude/claude_desktop_config.json)に以下を追加します。
{
"mcpServers": {
"omen": {
"command": "omen",
"args": ["mcp"]
}
}
}
Claude Code
claude mcp add omen -- omen mcp
使い方の例
設定が完了すると、Claudeに以下のような質問をすることができます。
- "このコードベースの複雑度を分析して"
- "srcディレクトリの技術的負債を見つけて"
- "リファクタリングが必要なホットスポットファイルは何か"
- "このプロジェクトのバスファクターのリスクを見せて"
- "削除すべき古いフィーチャーフラグを見つけて"
Claude Codeプラグイン
OmenはClaude Codeプラグインとして利用可能で、分析駆動型のスキルを提供し、Claudeをコード分析ワークフローに導きます。
インストール
/plugin install panbanda/omen
/skills でインストールを確認し、利用可能なOmenスキルを表示します。
前提条件
スキルを使用するには、上記のMCPサーバーのセクションでOmen MCPサーバーを構成する必要があります。
実世界のリポジトリ分析例
ディレクトリには、人気のあるオープンソースプロジェクトの包括的な健全性レポートが含まれており、