Skip to content

feat(ui): add finding acceptance-rate card to the analytics dashboard (#2197) - #4725

Merged
JSONbored merged 1 commit into
JSONbored:mainfrom
dhgoal:feat/ui-acceptance-rate-card
Jul 10, 2026
Merged

feat(ui): add finding acceptance-rate card to the analytics dashboard (#2197)#4725
JSONbored merged 1 commit into
JSONbored:mainfrom
dhgoal:feat/ui-acceptance-rate-card

Conversation

@dhgoal

@dhgoal dhgoal commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What

Adds the finding acceptance-rate card to the operator analytics dashboard (Closes #2197): the share of inline AI-review findings the contributor acted on (a finding was posted inline → the PR then merged), banded healthy / mixed / low with a window-days label.

Per the bounty, this is the display slice only — the backend acceptance computation is tracked separately in #1967. The card reads an optional acceptance shape off the operator-dashboard payload and degrades to a "not yet available" empty state while that field is absent, so it ships safely ahead of the backend and lights up automatically once the data lands. No src/** change.

Changes

  • acceptance-rate-card.tsx (new) — AcceptanceRateCard + FindingAcceptance type. Reuses the shared AnalyticsCardShell (feat(ui): shared analytics-card empty + loading skeleton states #2200) for the card/empty treatment and Stat / StatusPill primitives. Rate is rounded, guards total === 0 (rate: null, no divide-by-zero), and singular/plural counts are handled.
  • acceptance-rate-card.test.tsx (new) — 6 tests: populated (healthy), singular wording, mixed band, low band, empty-window (rate null), and absent-field empty state — covering both arms of every guard.
  • app.analytics.tsx — optional acceptance?: FindingAcceptance on the dashboard type + renders <AcceptanceRateCard acceptance={data.acceptance} /> after the cycle-time card.

Verification

ui:typecheck ✓ · ui:test (6/6) ✓ · ui:build ✓ · eslint 0 errors · prettier clean.

Screenshots

Net-new card — no acceptance-rate card existed on /app/analytics before. After state shown in both the live empty (field absent today) and populated (once #1967 lands) forms, across desktop + mobile, light + dark.

State Desktop (light) Desktop (dark) Mobile
After — empty (live today)
empty · light

empty · dark

empty · mobile
After — populated (#1967 data)
ready · light

ready · dark

ready · mobile

Closes #2197

…JSONbored#2197)

Render the finding acceptance-rate signal (inline findings the contributor
acted on: posted inline -> PR merged) as a single analytics card. Display
slice only per the bounty: the backend acceptance computation is tracked in
JSONbored#1967, so the card reads an optional acceptance shape off the operator
dashboard payload and degrades to a 'not yet available' empty state until it
lands. Rate is banded (healthy/mixed/low) with a window-days label, reusing
the shared AnalyticsCardShell + Stat/StatusPill primitives.
@dhgoal
dhgoal requested a review from JSONbored as a code owner July 10, 2026 21:00
@superagent-security superagent-security Bot added the contributor:flagged Contributor flagged for review by trust analysis. label Jul 10, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

🚨 Contributor flagged. Click here for more info: Superagent Dashboard

@superagent-security

Copy link
Copy Markdown
Contributor

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

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

loopover-orb Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ Gittensory review result - approve/merge recommended

Review updated: 2026-07-10 21:28:14 UTC

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

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This is a narrow, display-only addition of an AcceptanceRateCard that reads an optional `acceptance` field off the operator dashboard payload and renders either a graceful empty state (field absent) or the populated stat/band/window-pill layout; it correctly avoids any divide-by-zero by trusting a pre-computed nullable `rate` from upstream (tracked separately in #1967, no src/** touched here). The component reuses existing primitives (AnalyticsCardShell, Stat, StatusPill) consistent with the neighboring CycleTimeCard empty-state pattern, and the 6 new tests exercise both arms of the singular/plural, banding, and null-rate/absent-field guards. I don't see a reachable defect — the only real gaps are minor: duplicated magic-number thresholds and untested exact boundary values.

Nits — 5 non-blocking
  • acceptance-rate-card.tsx:19-27 — the 0.6/0.3 thresholds are duplicated verbatim between `acceptanceStatus` and `acceptanceBandLabel`; pull them into named constants (e.g. `HEALTHY_THRESHOLD = 0.6`, `MIXED_THRESHOLD = 0.3`) or a single function returning `{status, label}` so the two can't drift.
  • No test exercises the exact boundary values (`rate === 0.6` or `rate === 0.3`) to confirm the `>=` comparisons land on the intended side of the band edges.
  • app.analytics.tsx:217 renders `<AcceptanceRateCard acceptance={data.acceptance} />` unconditionally, unlike the neighboring `cycleTime` block which ternaries between `<CycleTimeCard>` and an inline `<AnalyticsCardShell state="empty">` — relying on the card's own internal empty-state branch is fine functionally but is a different pattern than its immediate neighbor; worth a one-line note on which convention is preferred going forward.
  • The JSDoc block comments on `FindingAcceptance`/`acceptanceStatus`/`acceptanceBandLabel` restate what the code already makes obvious (e.g. "higher acceptance = healthier signal") — could be trimmed per the repo's low-comment convention.
  • Merge `acceptanceStatus` and `acceptanceBandLabel` into one `getAcceptanceBand(rate): { status: Status; label: string }` to remove the duplicated threshold checks (acceptance-rate-card.tsx:18-28).
Flagged checks (non-blocking)
  • Contributor trust — Contributor flagged for review
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #2197
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: 94 registered-repo PR(s), 53 merged, 8 issue(s).
Contributor context ✅ Confirmed Gittensor contributor dhgoal; Gittensor profile; 94 PR(s), 8 issue(s).
Gate result ✅ Passing No configured blocker found.
Review context
  • Author: dhgoal
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 94 PR(s), 8 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.
Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/app/analytics desktop before /app/analytics after /app/analytics
/app/analytics mobile before /app/analytics (mobile) after /app/analytics (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

🟩 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 a7c6c41 into JSONbored:main Jul 10, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor:flagged Contributor flagged for review by trust analysis. 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(ui): finding acceptance-rate card (did the contributor act on it)

2 participants