Skip to content

feat(notifications): add the pure maintainer-recap builder (#2239) - #4210

Merged
JSONbored merged 1 commit into
JSONbored:mainfrom
real-venus:feat/gittensory-maintainer-recap-builder
Jul 8, 2026
Merged

feat(notifications): add the pure maintainer-recap builder (#2239)#4210
JSONbored merged 1 commit into
JSONbored:mainfrom
real-venus:feat/gittensory-maintainer-recap-builder

Conversation

@real-venus

@real-venus real-venus commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

The foundation slice for the #1963 maintainer recap digest: a pure builder that folds a window of gittensory's own review-outcome data across repos into a single serializable RecapReport. No delivery, no scheduling, no I/O, no model call — just the data-shaping seam, exactly mirroring how src/services/weekly-value-report.ts:129 buildWeeklyValueReport takes injected inputs and returns a report.

Closes #2239

Design

  • src/services/maintainer-recap.ts (new): buildMaintainerRecap(inputs) folds each repo's already-computed GatePrecisionReport + OutcomeCalibration into per-repo counts (reviewed / merged / closed) plus top-line gate/reversal totals (gateFalsePositives = blocked-then-merged, gateOverrides, reversals) and an aggregate gateFalsePositiveRate (null when nothing was blocked). The two aggregators are injected by the caller — the same pair src/review/ops-wire.ts already loads together — so no new D1 queries are added here.
  • src/types.ts: adds RecapReport + MaintainerRecapRepo alongside WeeklyValueReport / ReviewRecap, per the deliverable.
  • Public-safe by construction: the only free-text input (repo name) is scrubbed through PUBLIC_LOCAL_PATH_SCRUB_PATTERN, and the window is clamped via the same 1–90-day / 7-default bounds review-recap.ts uses.

Why this is NOT a duplicate of review-recap.ts

services/review-recap.ts's buildReviewRecap / ReviewRecap is single-repo and sourced from gate merge-prediction precision (computeGateEval.mergePrecision). This buildMaintainerRecap / RecapReport is multi-repo and sourced from the realized gate-block + recommendation-outcome calibration ledgers (GatePrecisionReport.overall.blockedThenMerged / perGateType[].overridden, OutcomeCalibration.recommendations.negative) — it carries false-positive / override / reversal totals that ReviewRecap has no field for. They are complementary seams for the same parent epic (#1963), not the same builder.

Tests

test/unit/maintainer-recap.test.ts: empty-window (zeroed totals + null false-positive rate + default window), single-repo fold with the computed 20% false-positive rate, multi-repo aggregation (including a repo with no slop bands), window clamping (0 → min, 999 → max), and local-path scrubbing of the repo name. Covers both arms of every branch — the blocked > 0 rate computation vs the null-rate path, and the finite vs non-finite window normalization.

Validation

  • git diff --check — clean.
  • npm run typecheck — clean.
  • npm run test:coverage (full, unsharded) — no logic failures; codecov/patch = 100% of the changed src/** lines and branches (33/33). Only the known Windows spawn claude/codex/docker ENOENT env suites fail locally (green on Linux CI).

If any required check was skipped, explain why:

  • test:workers / build:mcp / ui:* / actionlint / npm audit were not run locally — this is a purely additive src/services builder + two src/types additions, imported by nothing yet, touching no worker entrypoint, MCP package, UI, workflow, or dependency; CI covers them.

Safety

  • No secrets/wallet/hotkey/trust-score/reward terms — the report carries repo full names + PR-derived counts + gate-type codes only; repo names are scrubbed public-safe; per the source aggregators' own privacy note (no actor logins, no trust/reward numbers).
  • Public GitHub text: N/A — this is an internal data shape (no comment posted).
  • No auth/cookie/CORS/GitHub App/session change.
  • No API/OpenAPI/MCP surface change (pure builder, no route/tool wiring — that's a separate Maintainer review recap digest (Discord / Slack) #1963 slice).
  • No UI change.
  • No docs/changelog change needed.

UI Evidence

N/A — pure backend data-shaping function; no visible UI, frontend, docs, or extension surface.

Notes

…#2239)

Foundation for the JSONbored#1963 recap digest: a pure, injected-inputs builder that folds
a window of gittensory's own review-outcome data across repos into a serializable
RecapReport — per-repo reviewed/merged/closed counts plus top-line gate false-
positive / override / recommendation-reversal totals and an aggregate false-
positive rate. No delivery, no scheduling, no I/O, no model call — just the data-
shaping seam, mirroring weekly-value-report.ts's buildWeeklyValueReport.

It reuses the already-computed GatePrecisionReport (services/gate-precision.ts)
and OutcomeCalibration (services/outcome-calibration.ts) aggregators the caller
injects, so no new D1 queries are added. Distinct from services/review-recap.ts's
buildReviewRecap, which is single-repo and sourced from gate merge-PREDICTION
precision; this is multi-repo and sourced from the realized gate-block +
recommendation-outcome calibration ledgers.

Closes JSONbored#2239
@real-venus
real-venus requested a review from JSONbored as a code owner July 8, 2026 12:42
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.76%. Comparing base (24d058a) to head (0717dfe).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4210   +/-   ##
=======================================
  Coverage   93.75%   93.76%           
=======================================
  Files         389      390    +1     
  Lines       36499    36531   +32     
  Branches    13376    13379    +3     
=======================================
+ Hits        34221    34253   +32     
  Misses       1621     1621           
  Partials      657      657           
Files with missing lines Coverage Δ
src/services/maintainer-recap.ts 100.00% <100.00%> (ø)
src/types.ts 100.00% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 8, 2026
@loopover-orb

loopover-orb Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Warning

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

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-08 17:39:46 UTC

3 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

⏸️ Suggested Action - Manual Review

  • Touches a guarded path — held for manual review: This PR changes guardrail-protected path(s): src/services/maintainer-recap.ts (matched src/services/**).

Review summary
This PR adds a pure, well-isolated builder (`buildMaintainerRecap`) that folds per-repo `GatePrecisionReport` + `OutcomeCalibration` aggregators into a serializable `RecapReport`, with no new I/O or D1 queries — the caller injects both aggregators, matching the existing `buildWeeklyValueReport` pattern. Logic checks out: window-day clamping mirrors `review-recap.ts`'s bounds, the false-positive rate correctly guards the zero-`blocked` divide-by-zero case with a null, and `sanitizeRecapText` is applied to the only free-text input (repo name) plus the summary lines before they leave the function. Test coverage is genuine and exercises the real code paths (empty window, single repo, multi-repo aggregation with an empty-bands repo, window clamping at both ends, and the path-scrub case), and the PR closes the linked issue #2239 as required.

Nits — 6 non-blocking
  • The `240` truncation length in `sanitizeRecapText` (src/services/maintainer-recap.ts:33) is an unexplained magic number — pull it into a named constant like `MAX_RECAP_TEXT_LENGTH` for clarity and reuse.
  • `MaintainerRecapRepoInput` assumes `gatePrecision.repoFullName === calibration.repoFullName` but never asserts or tests that invariant — a caller passing mismatched pairs would silently produce a wrong repo label with the calibration's counts.
  • No comment/test documents why `gatePrecision.signals` and `calibration.signals` are ignored by the fold — worth a one-line note since a future reader may wonder if that's an oversight.
  • Extract the `240` literal into a shared constant (maintainer-recap.ts:33) alongside `DEFAULT_WINDOW_DAYS`/`MIN_WINDOW_DAYS`/`MAX_WINDOW_DAYS`.
  • Consider a dev-time assertion (or at least a comment) enforcing that `gatePrecision.repoFullName` and `calibration.repoFullName` match for each input pair, since repo identity is currently taken from `gatePrecision` alone.
  • Touches a guarded path — held for manual review — A maintainer must review and merge this change.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #2239
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 114 registered-repo PR(s), 66 merged, 3 issue(s).
Contributor context ✅ Confirmed Gittensor contributor real-venus; Gittensor profile; 114 PR(s), 3 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Linked issue satisfaction

Addressed
The PR adds src/services/maintainer-recap.ts with a pure buildMaintainerRecap(inputs) function sourced from the injected GatePrecisionReport/OutcomeCalibration aggregators, adds RecapReport/MaintainerRecapRepo to src/types.ts, and includes a unit test covering empty-window, single-repo, multi-repo, and both branches of the optional/?? fields, matching all stated deliverables.

Review context
  • Author: real-venus
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: TypeScript, JavaScript, MDX, Rust, Svelte, Swift
  • Official Gittensor activity: 114 PR(s), 3 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
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

@JSONbored
JSONbored merged commit 554373f into JSONbored:main Jul 8, 2026
8 checks passed
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. manual-review Gittensor contributor context

Development

Successfully merging this pull request may close these issues.

feat(notifications): pure maintainer-recap builder — aggregate review activity into a RecapReport

2 participants