<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Samir Musali</title>
    <description>The latest articles on DEV Community by Samir Musali (@smusali).</description>
    <link>https://dev.to/smusali</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F392103%2F86fe09ca-c6f3-415e-8781-7e4a52d4c30a.jpeg</url>
      <title>DEV Community: Samir Musali</title>
      <link>https://dev.to/smusali</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/smusali"/>
    <language>en</language>
    <item>
      <title>Meet checkOwners: confidence-scored CODEOWNERS from your git history</title>
      <dc:creator>Samir Musali</dc:creator>
      <pubDate>Sat, 04 Jul 2026 23:00:23 +0000</pubDate>
      <link>https://dev.to/smusali/meet-checkowners-confidence-scored-codeowners-from-your-git-history-4280</link>
      <guid>https://dev.to/smusali/meet-checkowners-confidence-scored-codeowners-from-your-git-history-4280</guid>
      <description>&lt;p&gt;"Who owns this code?" is a question most teams answer with folklore. GitHub's CODEOWNERS file is supposed to answer it, but it gets written once, rots quietly, and keeps routing reviews to people who changed teams a year ago.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/fortyOneTech/checkOwners" rel="noopener noreferrer"&gt;checkOwners&lt;/a&gt; answers it from evidence instead. It's an open-source CLI that reads your git history and writes your CODEOWNERS file for you. Pure git, no LLMs.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/fortyOneTech" rel="noopener noreferrer"&gt;
        fortyOneTech
      &lt;/a&gt; / &lt;a href="https://github.com/fortyOneTech/checkOwners" rel="noopener noreferrer"&gt;
        checkOwners
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Infer CODEOWNERS from git history with confidence scoring, bus factor, expertise decay, team topology, and review-load balancing. Pure git, no LLMs. Drift detection, CI-native JSON, and a composite GitHub Action.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;checkowners&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/fortyOneTech/checkowners/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/fortyOneTech/checkowners/actions/workflows/ci.yml/badge.svg" alt="CI"&gt;&lt;/a&gt;
&lt;a href="https://pypi.org/project/checkowners/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/3ee751688b45b471480eb0cf64d97f306013e191dec507b2e16fdd668e3d8e45/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f636865636b6f776e6572732e737667" alt="PyPI"&gt;&lt;/a&gt;
&lt;a href="https://pypi.org/project/checkowners/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fed3a8a91a678741268ff07a891bb3e81c3b61beb91656ac879b89a535076650/68747470733a2f2f696d672e736869656c64732e696f2f707970692f646d2f636865636b6f776e6572732e737667" alt="PyPI downloads"&gt;&lt;/a&gt;
&lt;a href="https://pypi.org/project/checkowners/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/be4eb27d726a29addd7bf1bcac50dc9d94cdc0b6f75d991cf845468af413b1d6/68747470733a2f2f696d672e736869656c64732e696f2f707970692f707976657273696f6e732f636865636b6f776e6572732e737667" alt="Python versions"&gt;&lt;/a&gt;
&lt;a href="https://github.com/fortyOneTech/checkOwners/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667" alt="License: MIT"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Infer CODEOWNERS from git history with confidence scoring, a knowledge graph, expertise decay detection, bus factor analysis, team topology inference, review load balancing, and onboarding paths. Pure git, no LLMs. CI-native: structured JSON output, GITHUB_OUTPUT integration, composite GitHub Action.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ownership is not binary. checkOwners is the first CODEOWNERS tool that treats it as a confidence-scored spectrum and surfaces the second-order risks (bus factor, expertise decay, team topology) that come with it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;checkowners analyze&lt;/code&gt; reads &lt;code&gt;git log&lt;/code&gt; and &lt;code&gt;git blame&lt;/code&gt; (in parallel, only over paths that can actually produce owners; a 24k-commit monorepo analyzes in under two minutes) into a confidence-scored ownership map cached per repo under &lt;code&gt;~/.checkowners/&lt;/code&gt;. Commit emails resolve to GitHub &lt;code&gt;@handles&lt;/code&gt; (noreply emails locally with no token, the rest via the GitHub API), and same-person identities merge so bus factors count people, not email addresses. From that map, &lt;code&gt;generate&lt;/code&gt; writes a CODEOWNERS file…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/fortyOneTech/checkOwners" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Ownership isn't binary
&lt;/h3&gt;

&lt;p&gt;Nobody owns a path absolutely; they own it with some confidence. checkOwners scores every path and owner pair between 0.0 and 1.0 from four signals: commit recency (exponential decay, 90-day half-life by default), commit frequency, blame coverage, and PR review activity (optional, via the GitHub API). The generated file ranks owners by that score, and uniform directories consolidate into single rules like &lt;code&gt;/src/ @alice&lt;/code&gt; instead of hundreds of per-file lines.&lt;/p&gt;

&lt;p&gt;Commit emails resolve to GitHub handles (noreply addresses parse locally, zero API calls), and same-person identities merge, so one human committing from two addresses is one owner, not two.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beyond generation
&lt;/h3&gt;

&lt;p&gt;Because the ownership map is confidence-scored, it can answer second-order questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bus-factor&lt;/code&gt;: which paths does exactly one person understand, and who should back them up&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;decay&lt;/code&gt;: which owners quietly stopped touching what they own, and where to transfer knowledge&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;drift&lt;/code&gt;: where the committed CODEOWNERS disagrees with inferred reality, using GitHub's real pattern-matching semantics (segment-bounded globs, root anchoring, last match wins)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;topology&lt;/code&gt;: team boundaries inferred from commit co-occurrence&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;balance&lt;/code&gt;: overloaded reviewers and suggested redistribution&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onboard&lt;/code&gt;: a learning path for new hires, from broad-ownership files to deep-expertise ones&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;trends&lt;/code&gt;: how ownership confidence and bus factor evolve over time&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick start
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;checkowners

checkowners analyze     &lt;span class="c"&gt;# confidence-scored inference&lt;/span&gt;
checkowners generate    &lt;span class="c"&gt;# write CODEOWNERS&lt;/span&gt;
checkowners drift       &lt;span class="c"&gt;# committed file vs reality&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every command supports &lt;code&gt;--json&lt;/code&gt;. In CI, the &lt;a href="https://github.com/marketplace/actions/checkowners" rel="noopener noreferrer"&gt;GitHub Action&lt;/a&gt; runs the whole flow on pull requests, maintains one continuously updated drift comment per PR, and can fail the build on drift.&lt;/p&gt;

&lt;h3&gt;
  
  
  One PSA, even if you never install it
&lt;/h3&gt;

&lt;p&gt;GitHub silently ignores CODEOWNERS lines containing character ranges like &lt;code&gt;[...]&lt;/code&gt;. No error, no warning, anywhere. If your hand-written file covers Next.js dynamic routes such as &lt;code&gt;app/[companyId]/&lt;/code&gt;, those paths may have no owner right now. checkOwners always emits GitHub-valid patterns, but either way: go check your file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trust notes
&lt;/h3&gt;

&lt;p&gt;Tested against a production monorepo (24k commits, 12k active files); a full analysis takes under 3 minutes. It refuses to overwrite a hand-written CODEOWNERS without &lt;code&gt;--force&lt;/code&gt;, all state stays local under &lt;code&gt;~/.checkowners/&lt;/code&gt;, and GitHub API access is strictly opt-in.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install checkowners&lt;/code&gt; (&lt;a href="https://github.com/fortyOneTech/checkOwners" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;). If it misbehaves on your monorepo, open an issue.&lt;/p&gt;

</description>
      <category>python</category>
      <category>git</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
