feat(enrichment): history analyzer — author record, similar PRs, issue alignment (#1478) - #1771
Conversation
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-06-29 23:12:30 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 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.
|
|
Please don't close this PR |
That's fine for now, but please note later today automated one-shot reviews should be fully activated, which will mean PRs will either be merged or closed upon first review. You'll have to ensure things are perfect locally before submitting, moving forward, otherwise you'll end up with a lot of closures. |
…' into feat/enrichment-history-analyzer
Summary
Adds the history analyzer to the review-enrichment service (REES), resolving #1478. It surfaces public-safe historical context the no-checkout in-prompt reviewer is blind to and the engine deliberately does not compute:
firstTimeContributorflag.mergedorreverted(a revert commit referencing a PR marks it reverted), with the overlapping paths — surfacing revert/regression history.full | partial | none), computed from thelinkedIssuecarried in the request envelope (no extra fetch).It carries only public GitHub facts — never internal submitter reputation, trust, reward, or score (those stay private; this analyzer never reads or emits them).
Self-contained and fail-safe, matching the
codeowners(#1515) /asset-weight(#1621) precedent: it reads the optional short-livedgithubToken+author+linkedIssuefrom the request envelope and degrades gracefully when any is absent or a GitHub call rate-limits/errors — the block is returned withpartial: true(or[]when there is nothing to report), and the rest of the brief still ships. No engine /src/**change; entirely withinreview-enrichment/(its ownnode:testsuite, outside the main tsc/vitest/Codecov scope).Wired per the issue:
HistoryFindingtype +historykey intypes.ts, thelinkedIssueenvelope field,scanHistoryregistered in thebrief.tsanalyzer registry, and a public-safe block inrender.ts. 17node:testunits cover author context, the first-timer flag, similar-PR detection + revert classification, current-PR exclusion, alignment full/partial/none, the no-token / rate-limit / thrown-fetch degrade paths, the SSRF repo guard, the pure helpers, and rendering.Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coverage— 5113 passed / 8 skipped. Nosrc/**changed, so there is nocodecov/patchobligation (the analyzer lives inreview-enrichment/, which Codecov ignores).npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderate— 0 vulnerabilitiesreview-enrichmentsuite green (199 pass, 17 new), covering every branch / fallback / degrade path.If any required check was skipped, explain why:
npm run test:cichain is green on this branch (rebased current withmain);npm run rees:test(build + sourcemap validation +node:test) also run directly.Safety
safeCodeSpan/promptTextescapers and is re-sanitized + defanged by the engine before it is spliced.EnrichRequest.linkedIssue,BriefFindings.history) is extended and unit-tested; no main-repo OpenAPI/MCP surface is touched.UI Evidencesection. — N/A: backend-only (review-enrichment service); no visible UI / frontend / docs / extension change.UI Evidence
N/A — backend-only change to the review-enrichment service; no visible UI, frontend, docs, or extension surface.
Notes
enrichment-wire.tsdoes not yet populateauthor/githubToken/linkedIssueon the envelope), exactly likecodeowners(feat(enrichment): CODEOWNERS + blast-radius mapper #1515) andasset-weight(feat(enrichment): image/binary asset weight-delta analyzer #1621) shipped — it degrades to[]until those fields arrive, keeping this a clean, zero-engine-conflict drop entirely withinreview-enrichment/.main; no base conflict.