Skip to content

Releases: smusali/checkOwners

v0.7.0

Choose a tag to compare

@smusali smusali released this 01 Nov 21:51
e39ae13

What's Changed

  • feat(B9): cache pip and analysis state between runs by @smusali in #168
  • feat(C2): compute concentration before owner truncation by @smusali in #169
  • feat(C3): report criticality-weighted knowledge risk by @smusali in #170
  • feat(C4): show knowledge loss after a departure by @smusali in #171
  • feat(C8): adapt recency half-life to path cadence by @smusali in #172
  • feat(D4): credit co-authors and report merge strategy by @smusali in #173
  • feat(E10): add composite knowledge-risk scoring by @smusali in #174
  • feat(E12): open a reconciliation pull request by default by @smusali in #175
  • chore(deps): bump the github-actions group with 2 updates by @dependabot[bot] in #176
  • feat(F4): let teams choose which findings block by @smusali in #177
  • feat(G2): stop treating commits as review load by @smusali in #178
  • chore(deps): bump the github-actions group with 4 updates by @dependabot[bot] in #179
  • fix(G3): separate historical activity from ownership score by @smusali in #180
  • chore(deps): bump the github-actions group with 3 updates by @dependabot[bot] in #181
  • docs: move planning from repository files to the issue tracker by @smusali in #191
  • feat(G6): sample ownership reviews by lookback days by @smusali in #192
  • ci(H6): run tests on macOS, Windows, and older Git by @smusali in #194
  • feat(J1): replay ownership from a stored baseline by @smusali in #195
  • feat(E5): keep manual blocks and print a dry fix plan by @smusali in #196
  • feat(report): add SARIF, checks, and diff-scoped review by @smusali in #198
  • ci(fuzz): score mutations and stabilize path globs by @smusali in #199
  • chore(deps): bump the github-actions group with 7 updates by @dependabot[bot] in #200
  • feat(identity): resolve owners and record contributor status by @smusali in #202
  • feat(graph): add ownership exports, Louvain, and onboarding by @smusali in #203
  • feat: add checkowners audit as the default command by @smusali in #204
  • feat(analyze): follow renames, cache blame, score survival by @smusali in #205
  • feat(validation): measure scores against later maintainers by @smusali in #206
  • ci(fuzz): skip coverage on the nightly pattern run by @smusali in #207
  • feat(library): add evidence replay and forge dialects by @smusali in #209
  • docs: add a versioned site and project governance by @smusali in #210
  • refactor: pre-v0.7.0 cleanup of the research layer, versioning, and layout by @smusali in #213
  • chore(release): pin 0.7.0 across package, Action, and changelog by @smusali in #214

Full Changelog: v0.6.0...v0.7.0

v0.6.0

Choose a tag to compare

@smusali smusali released this 24 Sep 12:03
a1eaa9f

What's Changed

  • feat(B7): collapse Action CI onto github-action by @smusali in #134
  • fix(C5): keep ownership scores comparable across modes by @smusali in #135
  • feat(C6): treat commit count as evidence not eligibility by @smusali in #136
  • fix(C7): pin recency to HEAD instead of wall clock by @smusali in #137
  • feat(D1): apply ignore-revs and standard blame flags by @smusali in #138
  • feat(D2): honor .mailmap as first identity stage by @smusali in #139
  • feat(D5): honor .gitattributes linguist exclusions by @smusali in #140
  • feat(E3): verify round-trip, size-guard, add explain-path by @smusali in #141
  • fix(E4): refuse lossy bracket-path wildcard consolidation by @smusali in #143
  • feat(E8): add explain and owners path interrogation by @smusali in #144
  • chore(deps): bump codecov/codecov-action from 5.5.5 to 7.1.1 in the github-actions group by @dependabot[bot] in #142
  • feat(E11): add ratchet and reason-required suppressions by @smusali in #145
  • feat(F1): version scoring models and config schema by @smusali in #146
  • feat(F2): publish schema 1.0 for command output by @smusali in #147
  • feat(F3): share one exit-code contract across commands by @smusali in #148
  • feat(F5): stop treating missing evidence as a complete run by @smusali in #149
  • feat(F6): add a staleness contract and atomic cache writes by @smusali in #150
  • refactor(G7): remove the drift webhook notifier by @smusali in #151
  • test(H1): catch ownership bugs mocks cannot see by @smusali in #152
  • test(H2): publish CODEOWNERS corpus and fuzz checks by @smusali in #153
  • test(H3): add golden tests for ownership beliefs by @smusali in #154
  • feat(I1): add report privacy modes and email tokens by @smusali in #155
  • feat(I2): publish the non-performance disclaimer by @smusali in #156
  • feat(I3): add Scorecard, audits, and release SBOM by @smusali in #157
  • chore(deps): bump the github-actions group with 3 updates by @dependabot[bot] in #158
  • feat(K1): expose checkowners as pre-commit hooks by @smusali in #159
  • docs(L1): lead with a real ownership drift example by @smusali in #160
  • docs(L3): publish limits and project principles by @smusali in #161
  • refactor(action): extract install script and rename drift output by @smusali in #162
  • refactor(versions)!: reset public contracts to v1 by @smusali in #163
  • refactor(analyze): publish helpers and drop duplicate tests by @smusali in #164
  • docs: add a glossary and shorten the landing copy by @smusali in #165
  • chore(release): pin 0.6.0 across package, Action, and changelog by @smusali in #166

Full Changelog: v0.5.1...v0.6.0

v0.5.1

Choose a tag to compare

@smusali smusali released this 15 Sep 11:19
ee0daae

What's Changed

  • docs: unified project state, problem, and solution register by @smusali in #9
  • fix(A1): point project URLs at smusali/checkowners by @smusali in #104
  • fix(A2): make README links absolute for PyPI by @smusali in #105
  • fix(A4): date changelog headings by PyPI day and guard tags by @smusali in #106
  • fix(B1): pass GITHUB_TOKEN to CLI steps in CI by @smusali in #107
  • fix(B2): pin package install to the Action tag by @smusali in #108
  • ci(B3): pin third-party uses to commit SHAs by @smusali in #109
  • chore(deps): bump the github-actions group with 5 updates by @dependabot[bot] in #110
  • fix(B4): fail-soft PR comments and always write job summary by @smusali in #111
  • fix(B5): bound GITHUB_OUTPUT summaries and upload artifacts by @smusali in #112
  • fix(B6): paginate PR comment lookup and escape Markdown by @smusali in #113
  • fix(B8): unify drift.mode default and Action state dir by @smusali in #114
  • fix(C1): name capped owner count as qualified-owners by @smusali in #115
  • ci(H5): enforce 85% floor, expand ruff, publish badge by @smusali in #116
  • chore(K2): compose extras, lock CI, and add Python 3.14 by @smusali in #117
  • docs(L2): drop first-claim and credit competitors honestly by @smusali in #118
  • docs(N1): add community on-ramp for outside contributors by @smusali in #129
  • chore(A3, v0.5.1): pin 0.5.1 and document the release cut by @smusali in #130
  • fix(action): fix the description length by @smusali in #131

New Contributors

Full Changelog: v0.5.0...v0.5.1

v0.5.0

Choose a tag to compare

@smusali smusali released this 04 Jul 04:36
4d50c17

[0.5.0] - 2026-07-03

Hardening release driven by testing every command against a real production monorepo (24k commits, 12k active files). Focus: correct CODEOWNERS semantics, analyze performance, per-repo state isolation, and identity resolution.

Added

  • CODEOWNERS pattern matching engine (checkowners/patterns.py) with GitHub's documented gitignore-style semantics: * stays within a path segment, ** crosses segments, leading or interior / anchors to the repo root, trailing / matches directory contents, dir/* matches direct children only, and the last matching rule wins.
  • generate consolidates per-file inference into directory-level rules when every inferred file under a directory shares one owner set (/src/ @alice instead of hundreds of per-file lines). New files under a consolidated directory now match a rule. Disable with output.consolidate: false.
  • generate and sync refuse to overwrite a hand-written CODEOWNERS (one without the machine-generated header) unless --force is passed.
  • --version flag; running bare checkowners now prints help instead of a usage error.
  • Progress bar (stderr, TTY-only) during the analyze blame pass.
  • Local GitHub-noreply email resolution: 12345+login@users.noreply.github.com and login@users.noreply.github.com map to @login with zero API calls and no token.
  • Persistent email-to-handle cache at <state-dir>/handles.json, including remembered misses, so the rate-limited user-search API is only queried once per new email.
  • Identity merging: when several commit emails resolve to one GitHub handle, their owner entries merge and per-path bus factor is recomputed over distinct people, so one person with two emails no longer reads as a bus factor of two. Decay warnings are remapped to the resolved handle.
  • Drift results carry notes explaining skipped comparisons (raw emails vs handles, team-owned rules) instead of emitting false drift.
  • balance reports fallback_reason when the GitHub API path was abandoned, and labels the load column "Commits (proxy)" when counting authorship.

Changed

  • Drift detection is now pattern-aware. Inferred files are matched against CODEOWNERS rules with real matching semantics; previously the comparison was literal string equality, so directory rules like frontend/ never matched inferred file paths and real-world files produced near-100% false "missing"/"stale" reports. New categories: missing = file no rule covers, stale = rule matching no tracked file (via git ls-files), changed = per-rule owner divergence, aggregated and ranked by worst per-file delta. Owner comparison is case-insensitive.
  • State is keyed per repo (schema v3) at ~/.checkowners/state/<repo-hash>.json with the absolute repo path embedded and verified on load. Previously a single global state.json meant analyzing repo A then running decay in repo B silently reused repo A's data.
  • Analyze is parallel and skips unowned files. git blame now runs on a thread pool sized to the CPU count and only on paths where at least one author reaches min_commits (4-5x fewer files on a real monorepo). Combined effect on a 24k-commit production repo: 80+ minutes to under 3 minutes.
  • validate follows GitHub's actual CODEOWNERS rules: relative patterns (docs/, apps/*, frontend/package.json) are valid, owner-less rules (GitHub's documented exemption mechanism) are valid, escaped spaces are parsed, and ! negation / [...] character ranges are correctly rejected. It previously demanded every pattern start with / or *, failing perfectly valid real-world files. Handle validation now matches GitHub's login rules (no dots, max 39 chars).
  • validate --json exits non-zero on an invalid file, matching the human-readable mode.
  • sync is a no-op success when the generated file matches the committed one ("already in sync"); it previously failed with an empty error because git prints "nothing to commit" on stdout.
  • Downstream commands print a stderr hint when reusing cached state.
  • notifications.include_unchanged now means "also notify when no drift was detected"; without it, no-drift runs no longer fire webhooks.
  • Severity's critical signal honors bus_factor.critical_threshold instead of a hardcoded 1.
  • Review-coverage and balance GitHub scans are bounded to the 200 most recently updated closed PRs and scoped to GITHUB_REPOSITORY; previously unbounded scans exhausted the API rate limit on mature repos.
  • trends counts distinct commits per period; a commit touching 12 files previously counted 12 times.
  • bus-factor, expertise, and onboard share one glob semantic (previously the same pattern matched different path sets per command).
  • Backup-reviewer suggestions fall back to repo-wide top owners for root-level files.
  • Onboarding steps never label a bus_factor<=1 path "easy".
  • Default exclusions now also cover package-lock.json, pnpm-lock.yaml, *.min.js, *.min.css, *.map, and the CODEOWNERS file itself (a sync commit would otherwise make whoever runs the tool its inferred owner, perturbing every subsequent run).
  • Composite Action: fails fast with a clear error on shallow clones (fetch-depth: 0 guidance), installs the github extra so handle resolution works in CI, and the PR comment is updated in place (one managed comment per PR, marked resolved when drift clears) instead of posting a new comment on every push.
  • PyGithub moved from a hard dependency to the github extra (with an all convenience extra); core inference is pure git. Unused GitPython dependency dropped.
  • graph DOT export escapes quotes and backslashes in node IDs and labels.

Removed

  • drift.compare_to config option: it was parsed and documented but never read by any logic. Configs still containing it are ignored, not rejected.
  • Dead internal API surface orphaned by the identity-merge rework: OwnershipMap.handles_only() and github.map_owners().

Fixed

  • Generated CODEOWNERS never emits [...] character ranges: bracket-bearing path segments (Next.js dynamic routes like [companyId]) become the valid * wildcard, colliding patterns merge their owners, and literal spaces in patterns are backslash-escaped. GitHub ignores lines with [...], which silently un-owned those paths. Found by dogfooding against a production Next.js monorepo.
  • Terminal output renders paths like [companyId] verbatim: user-derived text (paths, reasons, handles) is markup-escaped so Rich no longer swallows bracket segments as style tags.
  • Webhook notifications no longer crash the CLI on HTTP or network errors; failures log a warning and notify reports sent: false.
  • Rebalance suggestions can no longer propose shifting reviews onto another overloaded reviewer.
  • Topology reports one mismatch line per overlapping declared team instead of only the first.
  • Tests never touch the developer's real ~/.checkowners (isolated state dir fixture).

v0.4.0

Choose a tag to compare

@smusali smusali released this 14 Jun 23:40
f6492dd

What's Changed

  • Release 0.4.0: trends + github-action, review scoring, graph cache, security hardening, org transfer by @smusali in #5

Full Changelog: v0.3.0...v0.4.0

v0.3.0

Choose a tag to compare

@smusali smusali released this 06 Jun 23:20

Full Changelog: v0.2.0...v0.3.0

v0.2.0

Choose a tag to compare

@smusali smusali released this 26 May 21:26
6fea5c2

What's Changed

Full Changelog: v0.1.1...v0.2.0

v0.1.1

Choose a tag to compare

@smusali smusali released this 26 May 20:39
ac7172a

What's Changed

  • fix: filter deleted files, remove planning docs, dogfood CODEOWNERS by @smusali in #1
  • chore: bump version to 0.1.1 by @smusali in #2

New Contributors

Full Changelog: v0.1.0...v0.1.1

Initial Release: CODEOWNERS inference from git history

Choose a tag to compare

@smusali smusali released this 26 May 20:25

Full Changelog: v0.1.0...v0.1.0