{"id":34982942,"url":"https://github.com/panbanda/omen","last_synced_at":"2026-02-05T02:05:09.257Z","repository":{"id":327284844,"uuid":"1104562113","full_name":"panbanda/omen","owner":"panbanda","description":"Code intelligence for AI agents. Complexity, hotspots, and tech debt analysis over MCP.","archived":false,"fork":false,"pushed_at":"2026-01-31T21:30:37.000Z","size":7450,"stargazers_count":4,"open_issues_count":7,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-01T03:49:21.902Z","etag":null,"topics":["claude-plugins","mcp-server","static-analysis","tech-debt","vibe-coding"],"latest_commit_sha":null,"homepage":"https://panbanda.github.io/omen/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/panbanda.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-26T11:32:40.000Z","updated_at":"2026-01-31T21:30:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/panbanda/omen","commit_stats":null,"previous_names":["panbanda/omen"],"tags_count":92,"template":false,"template_full_name":null,"purl":"pkg:github/panbanda/omen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panbanda%2Fomen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panbanda%2Fomen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panbanda%2Fomen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panbanda%2Fomen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/panbanda","download_url":"https://codeload.github.com/panbanda/omen/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panbanda%2Fomen/sbom","scorecard":{"id":1240332,"data":{"date":"2025-12-09T20:38:07Z","repo":{"name":"github.com/panbanda/omen","commit":"f1e3b1623daafcf6ec32d882963a3dd7260171f3"},"scorecard":{"version":"v5.3.0","commit":"c22063e786c11f9dd714d777a687ff7c4599b600"},"score":4.9,"checks":[{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yaml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dependency-update-tool"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/17 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/release.yml:238","Info: jobLevel 'actions' permission set to 'read': .github/workflows/scorecard.yml:19","Info: jobLevel 'contents' permission set to 'read': .github/workflows/scorecard.yml:20","Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/scorecard.yml:11","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"project was created within the last 90 days. Please review its contents carefully","details":["Warn: Repository was created within the last 90 days."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#maintained"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#security-policy"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":8,"reason":"dependency not pinned by hash detected -- score normalized to 8","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/panbanda/omen/ci.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating gcr.io/distroless/static-debian12:nonroot to gcr.io/distroless/static-debian12:nonroot@sha256:2b7c93f6d6648c11f0e80a48558c8f77885eb0445213b8e69a6a0d7c89fc6ae4","Info:  13 out of  13 GitHub-owned GitHubAction dependencies pinned","Info:   6 out of   7 third-party GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#pinned-dependencies"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yml:34"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#packaging"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact omen-v2.4.2 not signed: https://api.github.com/repos/panbanda/omen/releases/268881167","Warn: release artifact omen-v2.4.1 not signed: https://api.github.com/repos/panbanda/omen/releases/268823664","Warn: release artifact omen-v2.4.0 not signed: https://api.github.com/repos/panbanda/omen/releases/268776292","Warn: release artifact omen-v2.3.0 not signed: https://api.github.com/repos/panbanda/omen/releases/268764402","Warn: release artifact omen-v2.4.2 does not have provenance: https://api.github.com/repos/panbanda/omen/releases/268881167","Warn: release artifact omen-v2.4.1 does not have provenance: https://api.github.com/repos/panbanda/omen/releases/268823664","Warn: release artifact omen-v2.4.0 does not have provenance: https://api.github.com/repos/panbanda/omen/releases/268776292","Warn: release artifact omen-v2.3.0 does not have provenance: https://api.github.com/repos/panbanda/omen/releases/268764402"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#signed-releases"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#sast"}},{"name":"Branch-Protection","score":4,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'main'","Warn: 'stale review dismissal' is disabled on branch 'main'","Warn: required approving review count is 1 on branch 'main'","Warn: codeowners review is not required on branch 'main'","Warn: 'last push approval' is disabled on branch 'main'","Warn: 'up-to-date branches' is disabled on branch 'main'","Info: status check found to merge onto on branch 'main'","Info: PRs are required in order to make changes on branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#branch-protection"}},{"name":"Contributors","score":10,"reason":"project has 4 contributing companies or organizations","details":["Info: found contributions from: aquaponics-ai, dispatchitinc, dispatchitinc @thefarmhub, tulua-io"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#contributors"}},{"name":"CI-Tests","score":6,"reason":"19 out of 30 merged PRs checked by a CI test -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#ci-tests"}}]},"last_synced_at":"2025-12-09T21:20:50.134Z","repository_id":327284844,"created_at":"2025-12-09T21:20:50.134Z","updated_at":"2025-12-09T21:20:50.134Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29107301,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T00:52:08.035Z","status":"online","status_checked_at":"2026-02-05T02:00:07.839Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude-plugins","mcp-server","static-analysis","tech-debt","vibe-coding"],"created_at":"2025-12-27T01:07:15.176Z","updated_at":"2026-02-05T02:05:09.234Z","avatar_url":"https://github.com/panbanda.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# Omen\n\n\u003cimg src=\"assets/omen-logo.jpg\" alt=\"Omen - Code Analysis CLI\" width=\"100%\"\u003e\n\n[![Rust Version](https://img.shields.io/badge/rust-1.92%2B-orange)](https://www.rust-lang.org/)\n[![License](https://img.shields.io/github/license/panbanda/omen)](https://github.com/panbanda/omen/blob/main/LICENSE)\n[![CI](https://github.com/panbanda/omen/actions/workflows/ci.yml/badge.svg)](https://github.com/panbanda/omen/actions/workflows/ci.yml)\n[![Release](https://img.shields.io/github/v/release/panbanda/omen)](https://github.com/panbanda/omen/releases)\n[![Crates.io](https://img.shields.io/crates/v/omen-cli)](https://crates.io/crates/omen-cli)\n\n**Your AI writes code without knowing where the landmines are.**\n\nOmen gives AI assistants the context they need: complexity hotspots, hidden dependencies, defect-prone files, and self-admitted debt. One command surfaces what's invisible.\n\n**Why \"Omen\"?** An omen is a sign of things to come - good or bad. Your codebase is full of omens: low complexity and clean architecture signal smooth sailing ahead, while high churn, technical debt, and code clones warn of trouble brewing. Omen surfaces these signals so you can act before that \"temporary fix\" celebrates its third anniversary in production.\n\n\u003c/div\u003e\n\n---\n\n## Features\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eComplexity Analysis\u003c/strong\u003e - How hard your code is to understand and test\u003c/summary\u003e\n\nThere are two types of complexity:\n\n- **Cyclomatic Complexity** counts the number of different paths through your code. Every `if`, `for`, `while`, or `switch` creates a new path. A function with cyclomatic complexity of 10 means there are 10 different ways to run through it. The higher the number, the more test cases you need to cover all scenarios.\n\n- **Cognitive Complexity** measures how hard code is for a human to read. It penalizes deeply nested code (like an `if` inside a `for` inside another `if`) more than flat code. Two functions can have the same cyclomatic complexity, but the one with deeper nesting will have higher cognitive complexity because it's harder to keep track of.\n\n**Why it matters:** Research shows that complex code has more bugs and takes longer to fix. [McCabe's original 1976 paper](https://ieeexplore.ieee.org/document/1702388) found that functions with complexity over 10 are significantly harder to maintain. [SonarSource's cognitive complexity](https://www.sonarsource.com/docs/CognitiveComplexity.pdf) builds on this by measuring what actually confuses developers.\n\n\u003e [!TIP]\n\u003e Keep cyclomatic complexity under 10 and cognitive complexity under 15 per function.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eSelf-Admitted Technical Debt (SATD)\u003c/strong\u003e - Comments where developers admit they took shortcuts\u003c/summary\u003e\n\nWhen developers write `TODO: fix this later` or `HACK: this is terrible but works`, they're creating technical debt and admitting it. Omen finds these comments and groups them by type:\n\n| Category    | Markers                 | What it means                                  |\n| ----------- | ----------------------- | ---------------------------------------------- |\n| Design      | HACK, KLUDGE, SMELL     | Architecture shortcuts that need rethinking    |\n| Defect      | BUG, FIXME, BROKEN      | Known bugs that haven't been fixed             |\n| Requirement | TODO, FEAT              | Missing features or incomplete implementations |\n| Test        | FAILING, SKIP, DISABLED | Tests that are broken or turned off            |\n| Performance | SLOW, OPTIMIZE, PERF    | Code that works but needs to be faster         |\n| Security    | SECURITY, VULN, UNSAFE  | Known security issues                          |\n\n**Why it matters:** [Potdar and Shihab's 2014 study](https://ieeexplore.ieee.org/document/6976075) found that SATD comments often stay in codebases for years. The longer they stay, the harder they are to fix because people forget the context. [Maldonado and Shihab (2015)](https://ieeexplore.ieee.org/document/7332619) showed that design debt is the most common and most dangerous type.\n\n\u003e [!TIP]\n\u003e Review SATD weekly. If a TODO is older than 6 months, either fix it or delete it.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eDead Code Detection\u003c/strong\u003e - Code that exists but never runs\u003c/summary\u003e\n\nDead code includes:\n\n- Functions that are never called\n- Variables that are assigned but never used\n- Classes that are never instantiated\n- Code after a `return` statement that can never execute\n\n**Why it matters:** Dead code isn't just clutter. It confuses new developers who think it must be important. It increases build times and binary sizes. Worst of all, it can hide bugs - if someone \"fixes\" dead code thinking it runs, they've wasted time. [Romano et al. (2020)](https://ieeexplore.ieee.org/document/8370748) found that dead code is a strong predictor of other code quality problems.\n\n\u003e [!TIP]\n\u003e Delete dead code. Version control means you can always get it back if needed.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eGit Churn Analysis\u003c/strong\u003e - How often files change over time\u003c/summary\u003e\n\nChurn looks at your git history and counts:\n\n- How many times each file was modified\n- How many lines were added and deleted\n- Which files change together\n\nFiles with high churn are \"hotspots\" - they're constantly being touched, which could mean they're:\n\n- Central to the system (everyone needs to modify them)\n- Poorly designed (constant bug fixes)\n- Missing good abstractions (features keep getting bolted on)\n\n**Why it matters:** [Nagappan and Ball's 2005 research at Microsoft](https://www.microsoft.com/en-us/research/publication/use-of-relative-code-churn-measures-to-predict-system-defect-density/) found that code churn is one of the best predictors of bugs. Files that change a lot tend to have more defects. Combined with complexity data, churn helps you find the files that are both complicated AND frequently modified - your highest-risk code.\n\n\u003e [!TIP]\n\u003e If a file has high churn AND high complexity, prioritize refactoring it.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCode Clone Detection\u003c/strong\u003e - Duplicated code that appears in multiple places\u003c/summary\u003e\n\nThere are three types of clones:\n\n| Type   | Description                                        | Example                                 |\n| ------ | -------------------------------------------------- | --------------------------------------- |\n| Type-1 | Exact copies (maybe different whitespace/comments) | Copy-pasted code                        |\n| Type-2 | Same structure, different names                    | Same function with renamed variables    |\n| Type-3 | Similar code with some modifications               | Functions that do almost the same thing |\n\n**Why it matters:** When you fix a bug in one copy, you have to remember to fix all the other copies too. [Juergens et al. (2009)](https://ieeexplore.ieee.org/document/5070547) found that cloned code has significantly more bugs because fixes don't get applied consistently. The more clones you have, the more likely you'll miss one during updates.\n\n\u003e [!TIP]\n\u003e Anything copied more than twice should probably be a shared function. Aim for duplication ratio under 5%.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eDefect Prediction\u003c/strong\u003e - The likelihood that a file contains bugs\u003c/summary\u003e\n\nOmen combines multiple signals to predict defect probability using PMAT-weighted metrics:\n\n- **Process** metrics (churn frequency, ownership diffusion)\n- **Metrics** (cyclomatic/cognitive complexity)\n- **Age** (code age and stability)\n- **Total** size (lines of code)\n\nEach file gets a risk score from 0% to 100%.\n\n**Why it matters:** You can't review everything equally. [Menzies et al. (2007)](https://ieeexplore.ieee.org/document/4027145) showed that defect prediction helps teams focus testing and code review on the files most likely to have problems. [Rahman et al. (2014)](https://dl.acm.org/doi/10.1145/2568225.2568269) found that even simple models outperform random file selection for finding bugs.\n\n\u003e [!TIP]\n\u003e Prioritize code review for files with \u003e70% defect probability.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eChange Risk Analysis (JIT)\u003c/strong\u003e - Predict which commits are likely to introduce bugs\u003c/summary\u003e\n\nJust-in-Time (JIT) defect prediction analyzes recent commits to identify risky changes before they cause problems. Unlike file-level prediction, JIT operates at the commit level using change-scope factors from [Kamei et al. (2013)](https://ieeexplore.ieee.org/document/6341763), augmented with file-level risk signals from the software engineering research literature.\n\n**Change-scope factors (75% of score):**\n\nWeighted using Kamei's median logistic regression coefficients (relative ordering across projects):\n\n| Factor  | Name                   | Weight | What it measures                           |\n| ------- | ---------------------- | ------ | ------------------------------------------ |\n| LA      | Lines Added            | 0.16   | More additions = more risk (strongest predictor) |\n| ENTROPY | Change Entropy         | 0.14   | Scattered changes = harder to review       |\n| FIX     | Bug Fix                | 0.12   | Bug fix commits indicate problematic areas |\n| LD      | Lines Deleted          | 0.08   | Deletions are generally safer              |\n| NF      | Number of Files        | 0.08   | More files = more coordination risk        |\n| NUC     | Unique Changes         | 0.07   | More unique prior commits on files         |\n| NDEV    | Number of Developers   | 0.05   | More developers on files = more risk       |\n| EXP     | Developer Experience   | 0.05   | Less experience = more risk                |\n\n**File-level risk signals (25% of score):**\n\n| Signal              | Weight | Source                                             |\n| ------------------- | ------ | -------------------------------------------------- |\n| File Churn          | 0.10   | [Nagappan \u0026 Ball (2005)](https://dl.acm.org/doi/10.1145/1062455.1062514) - historical change frequency predicts defects |\n| File Complexity     | 0.08   | [Zimmermann \u0026 Nagappan (2008)](https://dl.acm.org/doi/10.1145/1368088.1368161) - cyclomatic complexity is predictive but weaker than change metrics |\n| Ownership Diffusion | 0.07   | [Bird et al. (2011)](https://dl.acm.org/doi/10.1145/2025113.2025119) - files with many minor contributors (no clear owner) have more defects |\n\nOwnership diffusion is `1 - max_author_percentage`: files where no single author dominates score higher risk. This follows Bird et al.'s finding that concentrated ownership (a clear primary author) correlates with *fewer* defects, while diffuse ownership correlates with more.\n\n**Percentile-based risk classification:**\n\nRisk levels use percentile-based thresholds following JIT defect prediction best practices. Rather than fixed thresholds, commits are ranked relative to the repository's own distribution:\n\n| Level  | Percentile | Meaning                                    |\n| ------ | ---------- | ------------------------------------------ |\n| High   | Top 5%     | P95+ - Deserve extra scrutiny              |\n| Medium | Top 20%    | P80-P95 - Worth additional attention       |\n| Low    | Bottom 80% | Below P80 - Standard review process        |\n\nThis approach aligns with the 80/20 rule from defect prediction research: ~20% of code changes contain ~80% of defects. It ensures actionable results regardless of repository characteristics - well-disciplined repos will have lower thresholds, while high-churn repos will have higher ones.\n\n**Why it matters:** [Kamei et al. (2013)](https://ieeexplore.ieee.org/document/6341763) demonstrated that JIT prediction catches risky changes at commit time, before bugs propagate. Their effort-aware approach uses ranking rather than fixed thresholds, focusing limited review resources on the riskiest ~20% of commits. [Zeng et al. (2021)](https://ieeexplore.ieee.org/document/9463091) showed that simple JIT models match deep learning accuracy (~65%) with better interpretability.\n\n\u003e [!TIP]\n\u003e Run `omen changes` before merging PRs to identify commits needing extra review.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003ePR/Branch Diff Risk Analysis\u003c/strong\u003e - Assess overall risk of a branch before merging\u003c/summary\u003e\n\nWhile JIT analysis examines individual commits, diff analysis evaluates an entire branch's cumulative changes against a target branch. This gives reviewers a quick risk assessment before diving into code review.\n\n**Usage:**\n\n```bash\n# Compare current branch against main\nomen diff --target main\n\n# Compare against a specific commit\nomen diff --target abc123\n\n# Output as markdown for PR comments\nomen diff --target main -f markdown\n```\n\n**Risk Factors:**\n\nThe diff analyzer uses the same research-backed weight model as `omen changes` (see above), combining change-scope factors with file-level signals:\n\n| Factor | What it measures | Category |\n| ------ | ---------------- | -------- |\n| Lines Added | Total new code introduced | Change-scope |\n| Lines Deleted | Code removed | Change-scope |\n| Files Modified | Spread of changes | Change-scope |\n| Commits | Number of commits in branch | Change-scope |\n| Entropy | How scattered changes are | Change-scope |\n| File Churn | Historical change frequency of touched files | File-level |\n| File Complexity | Max cyclomatic complexity of touched files | File-level |\n| Ownership Diffusion | How diffusely owned the touched files are | File-level |\n\n**Risk Score Interpretation:**\n\n| Score | Level | Recommended Action |\n| ----- | ----- | ------------------ |\n| \u003c 0.2 | LOW | Standard review process |\n| 0.2 - 0.5 | MEDIUM | Careful review, consider extra testing |\n| \u003e 0.5 | HIGH | Thorough review, ensure comprehensive test coverage |\n\n**Example Output:**\n\n```\nBranch Diff Risk Analysis\n==========================\n\nSource:   feature/new-api\nTarget:   main\nBase:     abc123def\n\nRisk Score: 0.31 (MEDIUM)\n\nChanges:\n  Lines Added:    530\n  Lines Deleted:  39\n  Files Modified: 3\n  Commits:        1\n\nRisk Factors:\n  entropy:              0.023\n  lines_added:          0.140\n  lines_deleted:        0.008\n  num_files:            0.014\n  commits:              0.007\n  file_churn:           0.080\n  file_complexity:      0.045\n  ownership_diffusion:  0.000\n\nFile Risk:\n  max_complexity:       6.78\n  max_churn:            1.00\n  ownership_diffusion:  0.00\n```\n\n**What to Look For:**\n\n- **High lines added, low deleted** - New feature, needs thorough review\n- **Balanced add/delete** - Refactoring, verify behavior unchanged\n- **Net code reduction** - Cleanup/simplification, generally positive\n- **High entropy** - Scattered changes, check for unrelated modifications\n- **Many files** - Wide impact, ensure integration testing\n- **High file_churn** - Touching historically volatile files that change often\n- **High ownership_diffusion** - No clear owner for the touched files; ensure someone takes responsibility for review\n\n**CI/CD Integration:**\n\n```yaml\n# Add to GitHub Actions workflow\n- name: PR Risk Assessment\n  run: |\n    omen diff --target ${{ github.base_ref }} -f markdown \u003e\u003e $GITHUB_STEP_SUMMARY\n```\n\n**Why it matters:** Code review time is limited. Diff analysis helps reviewers prioritize their attention - a LOW risk PR with 10 lines changed needs less scrutiny than a MEDIUM risk PR touching 17 files. The entropy metric is particularly useful for catching PRs that bundle unrelated changes, which are harder to review and more likely to introduce bugs.\n\n\u003e [!TIP]\n\u003e Run `omen diff` before creating a PR to understand how reviewers will perceive your changes. Consider splitting HIGH risk PRs into smaller, focused changes.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eTechnical Debt Gradient (TDG)\u003c/strong\u003e - A composite \"health score\" for each file\u003c/summary\u003e\n\nTDG combines multiple metrics into a single score (0-100 scale, higher is better):\n\n| Component             | Max Points | What it measures                        |\n| --------------------- | ---------- | --------------------------------------- |\n| Structural Complexity | 20         | Cyclomatic complexity and nesting depth |\n| Semantic Complexity   | 15         | Cognitive complexity                    |\n| Duplication           | 15         | Amount of cloned code                   |\n| Coupling              | 15         | Dependencies on other modules           |\n| Hotspot               | 10         | Churn x complexity interaction          |\n| Temporal Coupling     | 10         | Co-change patterns with other files     |\n| Consistency           | 10         | Code style and pattern adherence        |\n| Entropy               | 10         | Pattern entropy and code uniformity     |\n| Documentation         | 5          | Comment coverage                        |\n\n**Why it matters:** Technical debt is like financial debt - a little is fine, too much kills you. [Cunningham coined the term in 1992](http://c2.com/doc/oopsla92.html), and [Kruchten et al. (2012)](https://ieeexplore.ieee.org/document/6336722) formalized how to measure and manage it. TDG gives you a single number to track over time and compare across files.\n\n\u003e [!TIP]\n\u003e Fix files with scores below 70 before adding new features. Track average TDG over time - it should go up, not down.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eDependency Graph\u003c/strong\u003e - How your modules connect to each other\u003c/summary\u003e\n\nOmen builds a graph showing which files import which other files, then calculates:\n\n- **PageRank**: Which files are most \"central\" (many things depend on them)\n- **Betweenness**: Which files are \"bridges\" between different parts of the codebase\n- **Coupling**: How interconnected modules are\n\n**Why it matters:** Highly coupled code is fragile - changing one file breaks many others. [Parnas's 1972 paper on modularity](https://dl.acm.org/doi/10.1145/361598.361623) established that good software design minimizes dependencies between modules. The dependency graph shows you where your architecture is clean and where it's tangled.\n\n\u003e [!TIP]\n\u003e Files with high PageRank should be especially stable and well-tested. Consider breaking up files that appear as \"bridges\" everywhere.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eHotspot Analysis\u003c/strong\u003e - High-risk files where complexity meets frequent changes\u003c/summary\u003e\n\nHotspots are files that are both complex AND frequently modified. A simple file that changes often is probably fine - it's easy to work with. A complex file that rarely changes is also manageable - you can leave it alone. But a complex file that changes constantly? That's where bugs breed.\n\nOmen calculates hotspot scores using the **geometric mean** of normalized churn and complexity:\n\n```\nhotspot = sqrt(churn_percentile * complexity_percentile)\n```\n\nBoth factors are normalized against industry benchmarks using empirical CDFs, so scores are comparable across projects:\n\n- **Churn percentile** - Where this file's commit count ranks against typical OSS projects\n- **Complexity percentile** - Where the average cognitive complexity ranks against industry benchmarks\n\n| Hotspot Score | Severity | Action                 |\n| ------------- | -------- | ---------------------- |\n| \u003e= 0.6        | Critical | Prioritize immediately |\n| \u003e= 0.4        | High     | Schedule for review    |\n| \u003e= 0.25       | Moderate | Monitor                |\n| \u003c 0.25        | Low      | Healthy                |\n\n**Why it matters:** [Adam Tornhill's \"Your Code as a Crime Scene\"](https://pragprog.com/titles/atcrime/your-code-as-a-crime-scene/) introduced hotspot analysis as a way to find the most impactful refactoring targets. His research shows that a small percentage of files (typically 4-8%) contain most of the bugs. [Graves et al. (2000)](https://ieeexplore.ieee.org/document/859533) and [Nagappan et al. (2005)](https://www.microsoft.com/en-us/research/publication/use-of-relative-code-churn-measures-to-predict-system-defect-density/) demonstrated that relative code churn is a strong defect predictor.\n\n\u003e [!TIP]\n\u003e Start refactoring with your top 3 hotspots. Reducing complexity in high-churn files has the highest ROI.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eTemporal Coupling\u003c/strong\u003e - Files that change together reveal hidden dependencies\u003c/summary\u003e\n\nWhen two files consistently change in the same commits, they're temporally coupled. This often reveals:\n\n- **Hidden dependencies** not visible in import statements\n- **Logical coupling** where a change in one file requires a change in another\n- **Accidental coupling** from copy-paste or inconsistent abstractions\n\nOmen analyzes your git history to find file pairs that change together:\n\n| Coupling Strength | Meaning                                                 |\n| ----------------- | ------------------------------------------------------- |\n| \u003e 80%             | Almost always change together - likely tight dependency |\n| 50-80%            | Frequently coupled - investigate the relationship       |\n| 20-50%            | Moderately coupled - may be coincidental                |\n| \u003c 20%             | Weakly coupled - probably independent                   |\n\n**Why it matters:** [Ball et al. (1997)](https://www.researchgate.net/publication/2791666_If_Your_Version_Control_System_Could_Talk) first studied co-change patterns at AT\u0026T and found they reveal architectural violations invisible to static analysis. [Beyer and Noack (2005)](https://www.semanticscholar.org/paper/Clustering-software-artifacts-based-on-frequent-Beyer-Noack/1afc4eeb182d92631c3ce400e6999eebbca71c12) showed that temporal coupling predicts future changes - if files changed together before, they'll likely change together again.\n\n\u003e [!TIP]\n\u003e If two files have \u003e50% temporal coupling but no import relationship, consider extracting a shared module or merging them.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCode Ownership/Bus Factor\u003c/strong\u003e - Knowledge concentration and team risk\u003c/summary\u003e\n\nBus factor asks: \"How many people would need to be hit by a bus before this code becomes unmaintainable?\" Low bus factor means knowledge is concentrated in too few people.\n\nOmen uses git blame to calculate:\n\n- **Primary owner** - Who wrote most of the code\n- **Ownership ratio** - What percentage one person owns\n- **Contributor count** - How many people have touched the file\n- **Bus factor** - Number of major contributors (\u003e5% of code)\n\n| Ownership Ratio | Risk Level  | What it means             |\n| --------------- | ----------- | ------------------------- |\n| \u003e 90%           | High risk   | Single point of failure   |\n| 70-90%          | Medium risk | Limited knowledge sharing |\n| 50-70%          | Low risk    | Healthy distribution      |\n| \u003c 50%           | Very low    | Broad ownership           |\n\n**Why it matters:** [Bird et al. (2011)](https://ieeexplore.ieee.org/document/6032488) found that code with many minor contributors has more bugs than code with clear ownership, but code owned by a single person creates organizational risk. The sweet spot is 2-4 significant contributors per module. [Nagappan et al. (2008)](https://www.microsoft.com/en-us/research/publication/the-influence-of-organizational-structure-on-software-quality/) showed that organizational metrics (like ownership) predict defects better than code metrics alone.\n\n\u003e [!TIP]\n\u003e Files with \u003e80% single ownership should have documented knowledge transfer. Critical files should have at least 2 people who understand them.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCK Metrics\u003c/strong\u003e - Object-oriented design quality measurements\u003c/summary\u003e\n\nThe Chidamber-Kemerer (CK) metrics suite measures object-oriented design quality:\n\n| Metric | Name                        | What it measures             | Threshold |\n| ------ | --------------------------- | ---------------------------- | --------- |\n| WMC    | Weighted Methods per Class  | Sum of method complexities   | \u003c 20      |\n| CBO    | Coupling Between Objects    | Number of other classes used | \u003c 10      |\n| RFC    | Response for Class          | Methods that can be invoked  | \u003c 50      |\n| LCOM   | Lack of Cohesion in Methods | Methods not sharing fields   | \u003c 3       |\n| DIT    | Depth of Inheritance Tree   | Inheritance chain length     | \u003c 5       |\n| NOC    | Number of Children          | Direct subclasses            | \u003c 6       |\n\n**LCOM (Lack of Cohesion)** is particularly important. Low LCOM means methods in a class use similar instance variables - the class is focused. High LCOM means the class is doing unrelated things and should probably be split.\n\n**Why it matters:** [Chidamber and Kemerer's 1994 paper](https://ieeexplore.ieee.org/document/295895) established these metrics as the foundation of OO quality measurement. [Basili et al. (1996)](https://ieeexplore.ieee.org/document/544352) validated them empirically, finding that WMC and CBO strongly correlate with fault-proneness. These metrics have been cited thousands of times and remain the standard for OO design analysis.\n\n\u003e [!TIP]\n\u003e Classes violating multiple CK thresholds are candidates for refactoring. High WMC + high LCOM often indicates a \"god class\" that should be split.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eRepository Map\u003c/strong\u003e - PageRank-ranked symbol index for LLM context\u003c/summary\u003e\n\nRepository maps provide a compact summary of your codebase's important symbols, ranked by structural importance using PageRank. This is designed for LLM context windows - you get the most important functions and types first.\n\nFor each symbol, the map includes:\n\n- **Name and kind** (function, class, method, interface)\n- **File location** and line number\n- **Signature** for quick understanding\n- **PageRank score** based on how many other symbols depend on it\n- **In/out degree** showing dependency connections\n\n**Why it matters:** LLMs have limited context windows. Stuffing them with entire files wastes tokens on less important code. PageRank, [developed by Brin and Page (1998)](https://snap.stanford.edu/class/cs224w-readings/Brin98Anatomy.pdf), identifies structurally important nodes in a graph. Applied to code, it surfaces the symbols that are most central to understanding the codebase.\n\n**Scalability:** Omen uses a sparse power iteration algorithm for PageRank computation, scaling linearly with the number of edges O(E) rather than quadratically with nodes O(V^2). This enables fast analysis of large monorepos with 25,000+ symbols in under 30 seconds.\n\n**Example output:**\n\n```\n# Repository Map (Top 20 symbols by PageRank)\n\n## parser.ParseFile (function) - pkg/parser/parser.go:45\n  PageRank: 0.0823 | In: 12 | Out: 5\n  func ParseFile(path string) (*Result, error)\n\n## models.TdgScore (struct) - pkg/models/tdg.go:28\n  PageRank: 0.0651 | In: 8 | Out: 3\n  type TdgScore struct\n```\n\n\u003e [!TIP]\n\u003e Use `omen context --repo-map --top 50` to generate context for LLM prompts. The top 50 symbols usually capture the essential architecture.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eFeature Flag Detection\u003c/strong\u003e - Find and track feature flags across your codebase\u003c/summary\u003e\n\nFeature flags are powerful but dangerous. They let you ship code without enabling it, run A/B tests, and roll out features gradually. But they accumulate. That \"temporary\" flag from 2019 is still in production. The flag you added for a one-week experiment is now load-bearing infrastructure.\n\nOmen detects feature flag usage across popular providers:\n\n| Provider     | Languages                | What it finds                                  |\n| ------------ | ------------------------ | ---------------------------------------------- |\n| LaunchDarkly | JS/TS                    | `variation()`, `boolVariation()` calls         |\n| Split        | JS/TS                    | `getTreatment()` calls                         |\n| Unleash      | JS/TS, Python            | `isEnabled()`, `is_enabled()` calls            |\n| Flipper      | Ruby                     | `Flipper[:flag]`, `enabled?()` calls           |\n| ENV-based    | Ruby, JS/TS, Python      | `ENV[\"FEATURE_*\"]`, `process.env.FEATURE_*`    |\n\nAdditional providers can be added via custom tree-sitter queries in your `omen.toml` configuration.\n\nFor each flag, Omen reports:\n\n- **Flag key** - The identifier used in code\n- **Provider** - Which SDK is being used\n- **References** - All locations where the flag is checked\n- **Staleness** - When the flag was first and last modified (with git history)\n\n**Custom providers:** For in-house feature flag systems, define custom tree-sitter queries in your `omen.toml`:\n\n```toml\n[[feature_flags.custom_providers]]\nname = \"feature\"\nlanguages = [\"ruby\"]\nquery = '''\n(call\n  receiver: (constant) @receiver\n  (#eq? @receiver \"Feature\")\n  method: (identifier) @method\n  (#match? @method \"^(enabled\\\\?|get_feature_flag)$\")\n  arguments: (argument_list\n    .\n    (simple_symbol) @flag_key))\n'''\n```\n\n**Why it matters:** [Meinicke et al. (2020)](https://dl.acm.org/doi/10.1145/3379597.3387463) studied feature flags across open-source projects and found that flag ownership (the developer who introduces a flag also removes it) correlates with shorter flag lifespans, helping keep technical debt in check. [Rahman et al. (2018)](https://link.springer.com/article/10.1007/s10664-018-9639-0) studied Google Chrome's 12,000+ feature toggles and found that while they enable rapid releases and flexible deployment, they also introduce technical debt and additional maintenance burden. Regular flag audits prevent your codebase from becoming a maze of unused toggles.\n\n\u003e [!TIP]\n\u003e Audit feature flags monthly. Remove flags older than 90 days for experiments, 14 days for release flags. Track flag staleness in your CI pipeline.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eRepository Score\u003c/strong\u003e - Composite health score (0-100)\u003c/summary\u003e\n\nOmen computes a composite repository health score (0-100) that combines multiple analysis dimensions. This provides a quick overview of codebase quality and enables quality gates in CI/CD.\n\n**Score Components:**\n\n| Component       | Weight | What it measures                                   |\n| --------------- | ------ | -------------------------------------------------- |\n| Complexity      | 25%    | % of functions exceeding complexity thresholds     |\n| Duplication     | 20%    | Code clone ratio with non-linear penalty curve     |\n| SATD            | 10%    | Severity-weighted TODO/FIXME density per 1K LOC    |\n| TDG             | 15%    | Technical Debt Gradient composite score            |\n| Coupling        | 10%    | Cyclic deps, SDP violations, and instability       |\n| Smells          | 5%     | Architectural smells relative to codebase size     |\n| Cohesion        | 15%    | Class cohesion (LCOM) for OO codebases             |\n\n**Normalization Philosophy:**\n\nEach component metric is normalized to a 0-100 scale where higher is always better. The normalization functions are designed to be:\n\n1. **Fair** - Different metrics with similar severity produce similar scores\n2. **Calibrated** - Based on industry benchmarks from SonarQube, CodeClimate, and CISQ\n3. **Non-linear** - Gentle penalties for minor issues, steep for severe ones\n4. **Severity-aware** - Weight items by impact, not just count\n\nFor example, SATD (Self-Admitted Technical Debt) uses severity-weighted scoring:\n- Critical (SECURITY, VULN): 4x weight\n- High (FIXME, BUG): 2x weight\n- Medium (HACK, REFACTOR): 1x weight\n- Low (TODO, NOTE): 0.25x weight\n\nThis prevents low-severity items (like documentation TODOs) from unfairly dragging down scores.\n\nTDG (Technical Debt Gradient) provides a complementary view by analyzing structural complexity, semantic complexity, duplication patterns, and coupling within each file.\n\n**Usage:**\n\n```bash\n# Compute repository score\nomen score\n\n# JSON output for CI integration\nomen -f json score\n```\n\n**Adjusting thresholds:**\n\nAchieving a score of 100 is nearly impossible for real-world codebases. Set realistic thresholds in `omen.toml` based on your codebase:\n\n```toml\n[score.thresholds]\nscore = 80        # Overall score minimum\ncomplexity = 85   # Function complexity\nduplication = 65  # Code clone ratio (often the hardest to improve)\ndefect = 80       # Defect probability\ndebt = 75         # Technical debt density\ncoupling = 70     # Module coupling\nsmells = 90       # Architectural smells\n```\n\nRun `omen score` to see your current scores, then set thresholds slightly below those values. Gradually increase them over time.\n\n**Enforcing on commit with [Lefthook](https://github.com/evilmartians/lefthook):**\n\nAdd to `lefthook.yml`:\n\n```yaml\npre-push:\n  commands:\n    omen-score:\n      run: omen score\n```\n\nThis prevents pushing code that fails your quality thresholds.\n\n**Why it matters:** A single health score enables quality gates, tracks trends over time, and provides quick codebase assessment. The weighted composite ensures that critical issues (defects, complexity) have more impact than cosmetic ones.\n\n\u003e [!TIP]\n\u003e Start with achievable thresholds and increase them as you improve your codebase. Duplication is often the hardest metric to improve in legacy code.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eSemantic Search\u003c/strong\u003e - Natural language code discovery\u003c/summary\u003e\n\nSearch your codebase by meaning, not just keywords. Omen uses vector embeddings to find semantically similar code based on natural language queries.\n\n```bash\n# Build the search index (first time)\nomen search index\n\n# Search for code\nomen search query \"database connection pooling\"\nomen search query \"error handling middleware\" --top-k 20\nomen search query \"authentication\" --files src/auth/,src/middleware/\n```\n\n**How it works:**\n\n1. **Symbol extraction** - Extracts functions from your codebase using tree-sitter\n2. **Embedding generation** - Generates 384-dimensional embeddings using all-MiniLM-L6-v2 via candle (local inference, no API keys)\n3. **Incremental indexing** - Only re-embeds files that changed since last index\n4. **Similarity search** - Ranks results by cosine similarity to your query\n\n**Performance:**\n\n- Index stored in `.omen/search.db` (SQLite)\n- Parallel file parsing with rayon\n- Batch embedding generation (64 symbols per batch)\n- Typical indexing: ~3.5 symbols/second on CPU\n\n**Why it matters:** Traditional grep/ripgrep finds exact matches. Semantic search finds code that *means* the same thing even with different naming. Ask \"how do we validate user input\" and find functions named `sanitize_params`, `check_request`, or `validate_form`.\n\n\u003e [!TIP]\n\u003e Run `omen search index` after major refactors or when onboarding to a new codebase. The index updates incrementally on subsequent runs.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMutation Testing\u003c/strong\u003e - Test suite effectiveness through code mutation\u003c/summary\u003e\n\nMutation testing measures how well your test suite catches bugs by introducing small changes (mutations) to your code and checking if tests fail. A \"killed\" mutant means tests caught the bug; a \"surviving\" mutant means a bug could slip through.\n\n**21 Mutation Operators:**\n\n| Category | Operators | What they mutate |\n|----------|-----------|------------------|\n| Core | CRR, ROR, AOR, COR, UOR | Literals, relational ops, arithmetic, conditionals, unary |\n| Advanced | SDL, RVR, BVO, BOR, ASR | Statement deletion, return values, boundaries, bitwise, assignment |\n| Rust | BorrowOperator, OptionOperator, ResultOperator | Borrow semantics, Option/Result handling |\n| Go | GoErrorOperator, GoNilOperator | Error handling, nil checks |\n| TypeScript | TSEqualityOperator, TSOptionalOperator | `===`/`==`, optional chaining |\n| Python | PythonIdentityOperator, PythonComprehensionOperator | `is`/`==`, list comprehensions |\n| Ruby | RubyNilOperator, RubySymbolOperator | nil handling, symbol/string conversion |\n\n**Features:**\n\n- **Parallel execution** - Async worker pool with work-stealing for efficient mutation testing\n- **Equivalent mutant detection** - ML-based scoring to identify semantically equivalent mutations\n- **Coverage integration** - Parse LLVM-cov, Istanbul, coverage.py, and Go coverage to skip untested code\n- **Incremental mode** - Only test mutations in changed files\n- **CI/CD integration** - Quality gates and GitHub integration\n\n**Usage:**\n\n```bash\n# Generate mutants (dry run) with default operators (CRR, ROR, AOR)\nomen mutation --dry-run\n\n# Run mutation testing with all operators\nomen mutation --mode thorough\n\n# Fast mode (excludes operators that produce more equivalent mutants)\nomen mutation --mode fast\n\n# Run with coverage data to skip untested code\nomen mutation --coverage coverage.json\n\n# Incremental mode for CI - only test changed files\nomen mutation --incremental\n\n# Control parallelism\nomen mutation --jobs 8\n\n# Output surviving mutants for investigation\nomen mutation --output-survivors survivors.json\n\n# Filter to specific files\nomen mutation --glob \"src/analyzers/*.rs\"\n```\n\n**ML-Based Prediction:**\n\nOmen includes an ML model that learns from your mutation testing history to predict which mutants will survive. This enables two optimizations:\n\n1. **Skip obvious kills** - Don't waste time testing mutants the model is confident will be caught\n2. **Better equivalent detection** - Learn which patterns in your codebase produce equivalent mutants\n\n```bash\n# Record results to history file for later training\nomen mutation --record\n\n# Train the model from accumulated history\nomen mutation train\n\n# Use trained model to skip high-confidence kills (saves time)\nomen mutation --skip-predicted 0.95\n\n# Use a custom model path\nomen mutation --model path/to/model.json\n```\n\n**Training Workflow:**\n\n1. **Collect data**: Run `omen mutation --record` on your codebase. Each mutant's outcome (killed/survived) is appended to `.omen/mutation-history.jsonl` along with:\n   - Mutant details (operator, location, original/mutated code)\n   - Source context (5 lines before/after the mutation)\n   - Execution time\n\n2. **Train model**: Run `omen mutation train` to train the predictor. The model learns:\n   - Operator-specific kill rates for your codebase\n   - Feature weights correlating code patterns with survival\n\n3. **Use predictions**: Future runs automatically load `.omen/mutation-model.json`. Use `--skip-predicted 0.9` to skip mutants with \u003e90% predicted kill probability.\n\n**Example CI workflow:**\n```bash\n# Weekly: full run with recording\nomen mutation --record --mode thorough\n\n# After accumulating history: train model\nomen mutation train\n\n# Daily CI: fast run using predictions\nomen mutation --incremental --skip-predicted 0.95\n```\n\n\u003e [!NOTE]\n\u003e The `.omen/` directory is gitignored by default. If you want to share the trained model across your team, remove `.omen/mutation-model.json` from your `.gitignore`.\n\n**Mutation Score:**\n\nThe mutation score measures test suite effectiveness:\n\n```\nmutation_score = killed_mutants / (total_mutants - equivalent_mutants)\n```\n\n| Score | Quality | Meaning |\n|-------|---------|---------|\n| \u003e 80% | Excellent | Strong test suite that catches most bugs |\n| 60-80% | Good | Reasonable coverage, some gaps to address |\n| 40-60% | Moderate | Significant testing gaps |\n| \u003c 40% | Poor | Tests miss many potential bugs |\n\n**Why it matters:** Code coverage tells you what code runs during tests, but not whether tests actually verify behavior. A function can have 100% coverage yet 0% mutation score if assertions are missing. [Jia and Harman (2011)](https://ieeexplore.ieee.org/document/5487526) showed that mutation testing correlates strongly with fault detection. [Papadakis et al. (2019)](https://ieeexplore.ieee.org/document/8532419) demonstrated it outperforms other test adequacy criteria.\n\n\u003e [!TIP]\n\u003e Start with `--mode fast` on CI for quick feedback, and run `--mode thorough` periodically for comprehensive analysis. Use `--coverage` to avoid wasting time on untested code.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMCP Server\u003c/strong\u003e - LLM tool integration via Model Context Protocol\u003c/summary\u003e\n\nOmen includes a Model Context Protocol (MCP) server that exposes all analyzers as tools for LLMs like Claude. This enables AI assistants to analyze codebases directly through standardized tool calls.\n\n**Available tools:**\n\n- `complexity` - Cyclomatic and cognitive complexity\n- `satd` - Self-admitted technical debt detection\n- `deadcode` - Unused functions and variables\n- `churn` - Git file change frequency\n- `clones` - Code clones detection\n- `defect` - File-level defect probability (PMAT)\n- `changes` - Commit-level change risk (JIT)\n- `diff` - Branch diff risk analysis\n- `tdg` - Technical Debt Gradient scores\n- `graph` - Dependency graph generation\n- `hotspot` - High churn + complexity files\n- `temporal` - Files that change together\n- `ownership` - Code ownership and bus factor\n- `cohesion` - CK OO metrics\n- `repomap` - PageRank-ranked symbol map\n- `smells` - Architectural smell detection\n- `flags` - Feature flag detection and staleness\n- `score` - Composite health score (0-100)\n- `semantic_search` - Natural language code search\n\nEach tool includes detailed descriptions with interpretation guidance, helping LLMs understand what metrics mean and when to use each analyzer.\n\nTool outputs default to [TOON (Token-Oriented Object Notation)](https://github.com/toon-format/toon) format, a compact serialization designed for LLM workflows that reduces token usage by 30-60% compared to JSON while maintaining high comprehension accuracy. JSON and Markdown formats are also available.\n\n**Why it matters:** LLMs work best when they have access to structured tools rather than parsing unstructured output. MCP is the emerging standard for LLM tool integration, supported by Claude Desktop and other AI assistants. TOON output maximizes the information density within context windows.\n\n\u003e [!TIP]\n\u003e Configure omen as an MCP server in your AI assistant to enable natural language queries like \"find the most complex functions\" or \"show me technical debt hotspots.\"\n\n\u003c/details\u003e\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"assets/omen-context.jpg\" alt=\"Code Only vs Omen Context\" width=\"100%\"\u003e\n\u003c/div\u003e\n\n## Supported Languages\n\nGo, Rust, Python, TypeScript, JavaScript, TSX/JSX, Java, C, C++, C#, Ruby, PHP, Bash (and other languages supported by tree-sitter)\n\n## Installation\n\n### Homebrew (macOS/Linux)\n\n```bash\nbrew install panbanda/omen/omen\n```\n\n### Cargo Install\n\n```bash\ncargo install omen-cli\n```\n\n### Docker\n\n```bash\n# Pull the latest image\ndocker pull ghcr.io/panbanda/omen:latest\n\n# Run analysis on current directory\ndocker run --rm -v \"$(pwd):/repo\" ghcr.io/panbanda/omen:latest analyze /repo\n\n# Run specific analyzer\ndocker run --rm -v \"$(pwd):/repo\" ghcr.io/panbanda/omen:latest complexity /repo\n\n# Get repository score\ndocker run --rm -v \"$(pwd):/repo\" ghcr.io/panbanda/omen:latest score /repo\n```\n\nMulti-arch images are available for `linux/amd64` and `linux/arm64`.\n\n### Download Binary\n\nDownload pre-built binaries from the [releases page](https://github.com/panbanda/omen/releases).\n\n### Build from Source\n\n```bash\ngit clone https://github.com/panbanda/omen.git\ncd omen\ncargo build --release\n# Binary at target/release/omen\n```\n\n## Quick Start\n\n```bash\n# Run all analyzers\nomen all\n\n# Check out the analyzers\nomen --help\n```\n\n## Remote Repository Scanning\n\nAnalyze any public GitHub repository without cloning it manually:\n\n```bash\n# GitHub shorthand\nomen -p facebook/react complexity\nomen -p kubernetes/kubernetes satd\n\n# With specific ref (branch, tag, or commit SHA)\nomen -p agentgateway/agentgateway --ref v0.1.0 all\nomen -p owner/repo --ref feature-branch all\n\n# Full URLs\nomen -p github.com/golang/go all\nomen -p https://github.com/vercel/next.js all\n\n# Shallow clone for faster analysis (static analyzers only)\nomen -p facebook/react --shallow all\n```\n\nOmen clones to a temp directory, runs analysis, and cleans up automatically. The `--shallow` flag uses `git clone --depth 1` for faster clones but disables git-history-based analyzers (churn, ownership, hotspot, temporal coupling, changes).\n\n## Configuration\n\nCreate `omen.toml` or `.omen/omen.toml` (supports `yaml`, `json` and `toml`):\n\n```bash\nomen init\n```\n\nSee [`omen.example.toml`](omen.example.toml) for all options.\n\n\u003e [!TIP]\n\u003e Using Claude Code? Run the `setup-config` skill to analyze your repository and generate an `omen.toml` with intelligent defaults for your tech stack, including detected feature flag providers and language-specific exclude patterns.\n\n## MCP Server\n\nOmen includes a Model Context Protocol (MCP) server that exposes all analyzers as tools for LLMs like Claude. This enables AI assistants to analyze codebases directly.\n\n### Claude Desktop\n\nAdd to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):\n\n```json\n{\n  \"mcpServers\": {\n    \"omen\": {\n      \"command\": \"omen\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\n### Claude Code\n\n```bash\nclaude mcp add omen -- omen mcp\n```\n\n### Example Usage\n\nOnce configured, you can ask Claude:\n\n- \"Analyze the complexity of this codebase\"\n- \"Find technical debt in the src directory\"\n- \"What are the hotspot files that need refactoring?\"\n- \"Show me the bus factor risk for this project\"\n- \"Find stale feature flags that should be removed\"\n\n## Claude Code Plugin\n\nOmen is available as a Claude Code plugin, providing analysis-driven skills that guide Claude through code analysis workflows.\n\n### Installation\n\n```bash\n/plugin install panbanda/omen\n```\n\nVerify installation with `/skills` to see available Omen skills.\n\n### Prerequisites\n\nSkills require the Omen MCP server to be configured (see MCP Server section above).\n\n## Real-World Repository Analysis Examples\n\nThe [`examples/repos/`](examples/repos/) directory contains comprehensive health reports for popular open-source projects, demonstrating Omen's capabilities across different languages and project types.\n\n### Analyzed Repositories\n\n| Repository | Language | Health Score | Key Insights |\n|------------|----------|--------------|--------------|\n| [gin-gonic/gin](examples/repos/gin-gonic-gin.md) | Go | 95/100 | Exceptionally healthy web framework with zero duplication and clean architecture |\n| [excalidraw/excalidraw](examples/repos/excalidraw-excalidraw.md) | TypeScript | 86/100 | Highest-scoring repo with 100% coupling score; App.tsx needs refactoring |\n| [BurntSushi/ripgrep](examples/repos/burntSushi-ripgrep.md) | Rust | 76/100 | Mature codebase with excellent architecture; duplication in tests is intentional |\n| [tiangolo/fastapi](examples/repos/tiangolo-fastapi.md) | Python | 74/100 | Great complexity scores (98/100); duplication from versioned examples in docs |\n| [discourse/discourse](examples/repos/discourse-discourse.md) | Ruby | 69/100 | Largest codebase (10K+ files); excellent defect management despite size |\n\n### What the Reports Demonstrate\n\n**1. Health Score Breakdown**\nEach report shows how the composite score is calculated from individual components (complexity, duplication, SATD, coupling, etc.) and explains why certain scores are what they are.\n\n**2. Hotspot Analysis**\nReports identify files with high churn AND high complexity - the most impactful refactoring targets. For example, gin's `tree.go` has a hotspot score of 0.54 due to its radix tree routing complexity.\n\n**3. Technical Debt Gradient (TDG)**\nFiles are graded A-F based on accumulated technical debt. The reports explain what drives low grades and prioritize cleanup efforts.\n\n**4. PR Risk Analysis**\nEach report includes a real PR analysis demonstrating `omen diff`:\n\n```bash\nomen diff --target main -f markdown\n```\n\nExample from gin-gonic/gin (#4420 - add escaped path option):\n```\nRisk Score: 0.31 (MEDIUM)\nLines Added:    63\nLines Deleted:  2\nFiles Modified: 2\n\nRisk Factors:\n  entropy:        0.084\n  lines_added:    0.118\n  num_files:      0.050\n```\n\n**Understanding Risk Factors:**\n- **Risk Score** - LOW (\u003c 0.2), MEDIUM (0.2-0.5), HIGH (\u003e 0.5)\n- **Entropy** - How scattered changes are (0 = concentrated, 1 = everywhere)\n- **Lines Added/Deleted Ratio** - Net code reduction is often a good sign\n- **Files Modified** - More files = more potential for cascading issues\n\n**5. CI/CD Integration**\nReports include GitHub Actions workflow examples for quality gates and PR risk assessment.\n\n### Generating Your Own Reports\n\nRun a comprehensive analysis on any repository:\n\n```bash\n# Local repository\nomen score\nomen hotspot\nomen tdg\n\n# Remote repository\nomen -p facebook/react score\nomen -p kubernetes/kubernetes hotspot\n\n# PR risk before merging\nomen diff --target main\n\n# Track score trends over time\nomen score trend --period monthly --since 6m\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -am 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Create a Pull Request\n\n## Acknowledgments\n\nOmen draws heavy inspiration from [paiml-mcp-agent-toolkit](https://github.com/paiml/paiml-mcp-agent-toolkit/) - a fantastic CLI and comprehensive suite of code analysis tools for LLM workflows. If you're doing serious AI-assisted development, it's worth checking out. Omen exists as a streamlined alternative for teams who want a focused subset of analyzers without the additional dependencies. If you're looking for a Rust-focused MCP/agent generator as an alternative to Python, it's definitely worth checking out.\n\n## License\n\nApache License 2.0 - see [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpanbanda%2Fomen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpanbanda%2Fomen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpanbanda%2Fomen/lists"}