fix(selfhost): source an open PR's Grafana verdict from review_audit, not dead advisories#3535
Conversation
… not dead advisories The exporter's still-open-PR verdict was joined against advisories, which only ever holds a PRE-gate rules-severity summary (always neutral/action_required in practice) -- never the gate's own actual merge/close/hold decision. That decision already has a live, correct, continuously-populated home: review_audit's gittensory-native gate_decision rows (written unconditionally on self-host by recordNativeGateDecision). Point the exporter there instead so a still-open PR's verdict reflects the gate's real, current state instead of an eternal placeholder. Verified against live production Postgres: a still-open PR now shows its actual hold/merge/close decision instead of always 'manual', while merged/closed PRs (the majority, from PR #3512) are unaffected. Closes #3511
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3535 +/- ##
=======================================
Coverage 93.09% 93.09%
=======================================
Files 301 301
Lines 31450 31450
Branches 11483 11483
=======================================
Hits 29279 29279
Misses 1517 1517
Partials 654 654 🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-05 16:19:36 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.
|
…les guard (#3546) The "does this database have any reporting signal at all" fail-safe guard still listed only pull_requests/advisories/review_targets/ ai_usage_events -- stale since #3535 made review_audit a genuine dependency of the verdict computation. In practice pull_requests already dominates the check on any real deployment, so this was cosmetic, not a live bug, but a database with only review_audit present would have been misclassified as empty. Add it to both the Postgres and SQLite variants of the guard. Flagged as a non-blocking nit on #3535's own review.
Closes #3511
Summary
Follow-up to fix(selfhost): give verdict the same state/merged_at precedence status has #3512. That PR fixed the verdict shown for merged/closed PRs (the vast majority). This closes the remaining gap it flagged: a still-open PR's verdict.
Root cause (corrected after deeper investigation): the exporter joined a still-open PR's verdict against
advisories.conclusion— but that column only ever holds a PRE-gate rules-severity summary (buildPullRequestAdvisory), which readsneutral/action_requiredfor essentially every PR by construction. It was never the gate's own final merge/close/hold decision, so a still-open PR's verdict was an eternalmanualplaceholder regardless of what the gate actually decided.(Initial investigation assumed
persistAdvisorywas simply uncalled dead code — agrepwithout-asilently missed every match insrc/queue/processors.tsdue to a NUL byte earlier in that file. It has 3 live callers; they just persist the wrong kind of conclusion for this purpose. No app code needed to change once this was understood.)The real signal already exists and is live:
review_audit'sgittensory-nativegate_decisionrows, written unconditionally on every self-host instance byrecordNativeGateDecision(src/review/parity-wire.ts) on every finalized gate evaluation. Verified directly against production Postgres: 1854/1854 recent rows have ahead_sha, the newest is seconds old, and it already includes liveholddecisions for currently-open PRs.Fix: point the exporter's still-open-PR verdict join at
review_audit(source='gittensory-native', latest row per PR bytarget_id) instead ofadvisories.merge→merge,close→close,hold→manual. The terminal-state precedence from fix(selfhost): give verdict the same state/merged_at precedence status has #3512 (state/merged_atwins first) is unchanged.Verified against live production Postgres: still-open PRs now show real, varied verdicts (12
manualfrom live holds, 3commented/mergefrom live merge decisions, 5 with no decision yet) instead of 100%manual; the merged/closed majority (2794 rows) is unaffected.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 typecheck(clean — no TypeScript files changed)shellcheck scripts/export-grafana-reporting-db.sh(clean; caught and fixed a real bug during review — a backtick-quoted term in a new SQL comment would have triggered shell command substitution inside the double-quoted query string)npx vitest run test/unit/selfhost-grafana-reporting.test.ts— 13/13 passing (2 existing tests rewritten aroundreview_auditfixtures instead ofadvisories, 2 new tests added: still-open PR with a live merge/close decision, and areviewbot-source row correctly ignored so a shadow-parity comparison row never masquerades as the live verdict)npm run test:workers/npm run build:mcp/npm run test:mcp-pack/npm run ui:openapi:check/npm run ui:build— not run individually; no worker/MCP/OpenAPI/UI surface touched.Safety
UI Evidencesection below. — N/A, not anapps/gittensory-uichange.