Skip to content

feat(enrichment): add churn-hotspot + bug-density scorer analyzer - #1750

Closed
Daedalus-Icarus wants to merge 1 commit into
JSONbored:mainfrom
Daedalus-Icarus:feat/enrichment-churn-hotspot-analyzer
Closed

feat(enrichment): add churn-hotspot + bug-density scorer analyzer#1750
Daedalus-Icarus wants to merge 1 commit into
JSONbored:mainfrom
Daedalus-Icarus:feat/enrichment-churn-hotspot-analyzer

Conversation

@Daedalus-Icarus

Copy link
Copy Markdown
Contributor

Summary

Adds a REES (review-enrichment service) analyzer that flags changed files which are statistical churn hotspots — high commit frequency AND a high fraction of fix/revert commits in the last 90 days. Defects cluster in such files, so the reviewer scrutinizes harder. This is heavy/historical git-log analysis the no-checkout headless claude --print reviewer cannot perform; the REES returns it as a brief block the engine splices into the review prompt.

The analyzer fetches up to 100 commits per changed file via the GitHub REST commits-by-path endpoint (GET /repos/{owner}/{repo}/commits?path=<file>&since=<90d>&per_page=100) and classifies each commit subject locally. A file is flagged when it carries ≥10 commits AND ≥30% fix/revert — the two together keep the signal high-precision (a busy file with few fixes is just active; a quiet file with two fixes is not a cluster).

Closes #1513.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked an issue, or this is small enough that the summary explains why an issue is not needed.

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck
  • npm run test:coverage locally; codecov/patch requires ≥97% coverage of the lines AND branches you changed (aim for 98%+ on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.
  • npm run test:workers
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run ui:openapi:check
  • npm run ui:lint
  • npm run ui:typecheck
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests.
  • API/OpenAPI/MCP behavior is updated and tested where needed.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks.
  • Visible UI changes include a UI Evidence section below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

Notes

  • The analyzer is fail-safe by construction (mirrors the codeowners.ts precedent): any network error or non-ok response yields []; one file's failure does not abort the rest; only an abort signal propagates as analyzer_aborted so the orchestrator marks the brief partial.
  • The finding is public-safe by construction: it carries only a file path + integer commit counts + a rate. No commit messages, authors, or dates ever leave the analyzer. The render block routes the file path through safeCodeSpan (the same path-forgery guard the other render blocks use).
  • Thresholds (MIN_COMMITS=10, MIN_FIX_REVERT_RATE=0.3, MAX_FILES_SCANNED=15, LOOKBACK_DAYS=90) are committed as named constants at the top of the analyzer, matching how every other analyzer exposes its tuning knobs.
  • The commit-subject classifier is a flat anchored regex requiring a Conventional Commit colon (fix: / revert: / bugfix: / hotfix:) or git's Revert " prefix — linear-time, no backtracking risk on adversarial input (the same ReDoS discipline secret-log.ts documents).

@dosubot dosubot Bot added the size:L label Jun 29, 2026
@loopover-orb

loopover-orb Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-06-29 21:48:50 UTC

5 files · 1 AI reviewer · 1 blocker · readiness 55/100 · CI green · dirty

⏸️ Suggested Action - Manual Review

  • The AI review flagged a possible must-fix defect below the automatic close-confidence floor, so the gate is held for a human reviewer instead of passed automatically.

Review summary
This adds a new review-enrichment analyzer for recent per-file churn and fix/revert density, wires it into the brief registry, and renders a concise prompt block. The implementation is mostly consistent with the existing analyzer fail-safe pattern and the tests cover the core classifier, scan cap, rendering, and orchestration paths. The main correctness gap is that path-scoped commit history is queried only for the current filename, so renamed files lose the history this analyzer is meant to surface.

Blockers

  • review-enrichment/src/analyzers/churn-hotspot.ts:112 only queries `file.path`, so a renamed changed file with `previousPath` will be treated as quiet even when all recent fix/revert history is under the old path; query `previousPath` as well for renamed files, merge/dedupe the returned commits, or explain why renamed hotspots are intentionally excluded.
Nits — 7 non-blocking
  • nit: review-enrichment/src/analyzers/churn-hotspot.ts:103 uses `Date.now()` directly, which makes the generated `since` parameter awkward to assert deterministically compared with the existing test fixture clock.
  • nit: review-enrichment/src/analyzers/churn-hotspot.ts:121 treats malformed JSON from an otherwise `ok` response as a per-file network skip via the outer catch; that is fine operationally, but the helper comment says non-array bodies degrade to `[]`, so add a small test for thrown `json()` if you want that fail-safe contract pinned down.
  • nit: review-enrichment/src/render.ts:257 renders the brief with a fixed “last 90 days” string while the analyzer owns `LOOKBACK_DAYS`; if that constant changes later, the prompt can drift from the actual query window.
  • review-enrichment/src/analyzers/churn-hotspot.ts:112 should include `file.previousPath` for renamed files and avoid double-counting the same commit if both paths return overlapping results.
  • review-enrichment/test/enrichment.test.ts should add a renamed-file case that drives `previousPath` through `scanChurnHotspots`, because that is the real path currently missed.
  • Readiness score is below the configured threshold — Use the readiness panel as advisory maintainer context; the score does not block this PR.
  • AI reviewers agree on a likely critical defect: review-enrichment/src/analyzers/churn-hotspot.ts:112 only queries `file.path`, so a renamed changed file with `previousPath` will be treated as quiet even when all recent fix/revert history is under the old path; query `previousPath` as well for renamed files, merge/dedupe the returned commits, or explain why renamed hotspots are intentionally excluded. — Resolve the flagged defect, or override if the AI reviewers are mistaken, then re-run the gate.

Concerns raised — review before merging

  • review-enrichment/src/analyzers/churn-hotspot.ts:112 only queries `file.path`, so a renamed changed file with `previousPath` will be treated as quiet even when all recent fix/revert history is under the old path; query `previousPath` as well for renamed files, merge/dedupe the returned commits, or explain why renamed hotspots are intentionally excluded.
Signal Result Evidence
Code review ❌ 1 blocker 1 reviewer
Linked issue ✅ Linked #1513
Related work ⚠️ 3 scoped overlaps Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (size label size:L; 1 linked issue).
Validation posture ❌ 5/25 Preflight is holding this PR; address the blocker before review.
Contributor workload ✅ 10/10 Author activity: 42 registered-repo PR(s), 15 merged, 4 issue(s).
Contributor context ✅ Confirmed Gittensor contributor EtoileAI; Gittensor profile; 42 PR(s), 4 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Review context
Contributor next steps
  • Review top overlaps.
  • Add a concise scope and risk note.
  • Fix the blocker.
  • Triage stale or unlinked PRs.
  • Refresh registry data or choose a registered active repo.
  • Check active issues and PRs before submitting.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@loopover-orb loopover-orb Bot added gittensor gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. labels Jun 29, 2026

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are multiple merge conflicts (a PR submitted before yours updated the same files), and also, the gittensory orb review agent identified a few blockers that should be fixed before resubmitting.

This branch has conflicts that must be resolved
Use the [web editor](https://github.com/JSONbored/gittensory/pull/1750/conflicts) or the command line to resolve conflicts before continuing.

review-enrichment/src/brief.ts
review-enrichment/src/render.ts
review-enrichment/src/types.ts
review-enrichment/test/enrichment.test.ts

Closing, feel free to resubmit. I really suggest submitting only one of these, when you see no other feat(enrichment) PRs are open ahead of yours, otherwise it's likely there will be more merge conflicts/churn.

@JSONbored JSONbored closed this Jun 29, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in gittensory - v1 roadmap Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

feat(enrichment): Churn-hotspot + bug-density scorer

2 participants