Skip to content

feat(api): surface computeRuleGateEval's per-(project, ruleCode) rows - #8929

Closed
hurryup52 wants to merge 1 commit into
JSONbored:mainfrom
hurryup52:feat/8906-rule-gate-eval-route
Closed

feat(api): surface computeRuleGateEval's per-(project, ruleCode) rows#8929
hurryup52 wants to merge 1 commit into
JSONbored:mainfrom
hurryup52:feat/8906-rule-gate-eval-route

Conversation

@hurryup52

Copy link
Copy Markdown
Contributor

Summary

  • computeRuleGateEval (src/review/rule-gate-eval.ts) is the finer-grained "which rule is broken on which repo" sibling of computeBlendedRuleGateEval, but had zero consumers outside its own unit test. Adds GET /v1/internal/rule-gate-eval so an operator can actually reach the per-(project, ruleCode) breakdown.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format.
  • 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 a currently open issue this PR resolves — Closes #8906.

Validation

  • git diff --check
  • npm run actionlint — not run (no workflow files touched).
  • npm run typecheck — clean.
  • npm run test:coverage locally — ran the full suite; see notes below.
  • 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 — not run; this change touches only src/api/routes.ts (a backend route) and a backend integration test, no UI/worker/MCP/OpenAPI-spec surface (confirmed no /v1/internal/* route appears in src/openapi/spec.ts — internal routes aren't documented there, matching the existing sibling routes this PR mirrors).
  • npm audit --audit-level=moderate — no new dependencies added.
  • New behavior has tests for the new branches (?days= present/absent, per-project vs. pooled response shape, 401 without the bearer token).

If any required check was skipped, explain why:

  • UI/worker/MCP/OpenAPI checks skipped: this PR's diff is src/api/routes.ts (new route only) + test/integration/api.test.ts (new tests only) — no UI, Worker entrypoint, MCP package, or OpenAPI spec files changed.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed. (ruleCode is not sensitive — unlike a contributor login, which is why the fairness/contributors routes need a detail+summary split and this doesn't.)
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth changes include negative-path tests — new test asserts 401 without the internal bearer token (the route rides the existing shared /v1/internal/* middleware; no new auth logic was written).
  • API/OpenAPI/MCP behavior is updated and tested where needed — new route has a dedicated test; no OpenAPI registration needed (see above).
  • UI changes use live API data or real empty/error/loading states — N/A, no UI changes.
  • UI Evidence — N/A, no visible UI change (backend-only route).

UI Evidence

N/A — backend-only change, no UI surface touched.

Notes

  • Design choice: the issue's own text offers "a route (or a new operator-dashboard field), following the existing pattern used for the blended view." The blended view's actual pattern in operator-dashboard.ts only ever surfaces a derived count (rulesBelowClosePrecisionFloor(...).length), never raw rows — matching that literally would not satisfy the issue's stated goal ("operator can see which specific rule is broken on which specific repo"), since a count alone doesn't identify project/rule pairs. rule-gate-eval.ts's own module header says it "mirrors contributor-gate-eval.ts EXACTLY" — and that sibling module's finer-grained view is already exposed via a dedicated route (/v1/internal/fairness/contributors/:login) rather than a dashboard field, precisely because raw per-entity rows need their own reachable endpoint. Since ruleCode (unlike a contributor login) carries no privacy concern, the closer and simpler precedent is the unflagged GET /v1/internal/fleet/analytics (single route, ?days=, no detail/summary split) — that's what this PR mirrors.

computeRuleGateEval (rule-gate-eval.ts) is the finer-grained "which rule
is broken on which repo" sibling of computeBlendedRuleGateEval, but had
zero consumers outside its own unit test — the blended, pooled-across-
projects view is the only one wired into the auto-tune breaker cache
(outcomes-wire.ts) and the operator-dashboard tile.

Add GET /v1/internal/rule-gate-eval, mirroring the existing unflagged
/v1/internal/fleet/analytics route (bearer-gated by the shared
/v1/internal/* middleware, ?days= window defaulting to 90). ruleCode
carries no privacy concern (unlike a contributor login), so unlike the
fairness/contributors detail-route-plus-summary-tile split, this
returns the full per-project report directly.

Test seeds two different projects sharing the same ruleCode via real
review_audit gate_decision/pr_outcome pairs and asserts the response
contains two distinct per-project rows (not one pooled row), plus the
?days= default/override and 401-without-token cases.

Closes JSONbored#8906
@hurryup52
hurryup52 requested a review from JSONbored as a code owner July 26, 2026 13: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 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.01%. Comparing base (8a3d2c9) to head (3598872).
⚠️ Report is 12 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8929      +/-   ##
==========================================
- Coverage   93.84%   91.01%   -2.84%     
==========================================
  Files         803       97     -706     
  Lines       80084    24932   -55152     
  Branches    24277     4672   -19605     
==========================================
- Hits        75157    22692   -52465     
+ Misses       3562     1975    -1587     
+ Partials     1365      265    -1100     
Flag Coverage Δ
backend 95.20% <100.00%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/api/routes.ts 95.20% <100.00%> (+<0.01%) ⬆️

... and 706 files with indirect coverage changes

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 26, 2026
@loopover-orb

loopover-orb Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - reject/close recommended

Review updated: 2026-07-26 13:50:24 UTC

2 files · 1 AI reviewer · 1 blocker · CI green · clean

🛑 Suggested Action - Reject/Close

Review summary
This adds a single GET /v1/internal/rule-gate-eval route wiring the existing, previously-unused computeRuleGateEval into the API, mirroring the sibling contributor/fleet-analytics internal routes in file:line style, auth gating, and the ?days= convention (default 90). The tests cover the three meaningful branches (per-project vs pooled shape, days present/default, 401 without bearer token) and assert against real DB-seeded review_audit rows rather than fabricated payloads, so the tests exercise the real code path through computeRuleGateEval. The change is narrow, closes #8906 as required, and does not touch OpenAPI spec/UI/worker surfaces, consistent with this being an internal-only route.

Nits — 3 non-blocking
  • src/api/routes.ts:4416 — the `90` default lookback window is a repeated magic number across this file (fleet analytics, fairness routes, this route); consider a shared constant (e.g. mirroring BREAKER_EVAL_WINDOW_DAYS) instead of re-hardcoding it at each call site.
  • The long comment block above the new route (src/api/routes.ts:4405-4413) is dense; could be trimmed to the load-bearing facts (bearer-gated, default window, no privacy concern) without the full cross-reference to other modules.
  • Consider importing/reusing BREAKER_EVAL_WINDOW_DAYS (or an equivalent named constant) for the `90` default in src/api/routes.ts:4416 instead of a bare literal, matching the pattern already used for GATE_OUTCOME_BREAKDOWN_WINDOW_DAYS elsewhere in this file.

Why this is blocked

  • No linked issue detected: No closing reference or linked issue number was found in the PR metadata/body. — If this PR is intended to solve an issue, link it explicitly in the PR body.
📋 Copy for AI agents — paste into your coding agent
Fix the following blocker(s) from this PR review:

1. No linked issue detected: No closing reference or linked issue number was found in the PR metadata/body. — If this PR is intended to solve an issue, link it explicitly in the PR body.

Decision drivers

  • ❌ Code review — 1 blocker (1 reviewer)
  • ❌ Gate result — Blocking (Repo-configured hard blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ No-issue rationale PR body explains why no issue is linked.
Related work ⚠️ 1 scoped overlap Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (no linked issue context).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 21 registered-repo PR(s), 7 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor hurryup52; Gittensor profile; 21 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Review context
  • Author: hurryup52
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: JavaScript, TypeScript, Dart, MDX, Rust
  • Official Gittensor activity: 21 PR(s), 0 issue(s).
  • Related work: Titles/paths share 6 meaningful terms. (PR #8928)
Contributor next steps
  • Start here: Review top overlaps.
  • Then work through the remaining 3 steps in the Signals table above.
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.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Decision record
  • action: hold · clause: missing_linked_issue
  • config: 03a7f8b529a9 · pack: oss-anti-slop
  • record: ec286ed375dd (schema v2, head 3598872)

🟩 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 LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb

loopover-orb Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

LoopOver is closing this pull request on the maintainer's behalf (No linked issue detected). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant