Skip to content

feat(api): REST + CLI mirror for loopover_pr_outcome - #6965

Closed
lourincedaging0-commits wants to merge 1 commit into
JSONbored:mainfrom
lourincedaging0-commits:feat/rest-cli-pr-outcomes-6747
Closed

feat(api): REST + CLI mirror for loopover_pr_outcome#6965
lourincedaging0-commits wants to merge 1 commit into
JSONbored:mainfrom
lourincedaging0-commits:feat/rest-cli-pr-outcomes-6747

Conversation

@lourincedaging0-commits

Copy link
Copy Markdown
Contributor

What

The loopover_pr_outcome MCP tool returns a contributor's own merged-PR outcome
history (self-scoped via requireContributorAccess), but it was the only surface
for that data — no REST route, no CLI mirror — despite fitting the existing
/v1/contributors/:login/... route family alongside the open-PR monitor.

This adds the two missing surfaces and collapses all three onto one shared builder:

  • REST: GET /v1/contributors/:login/pr-outcomes — self-scoped, with ?limit=N
    mirroring the tool's 1..100 bound.
  • CLI: registers the loopover_pr_outcome stdio tool, which proxies that route.
  • Shared builder: the MCP tool, the route, and the CLI all delegate to one
    buildContributorPrOutcomes in src/signals/ (mirroring the
    buildContributorOpenPrMonitor sibling), so the three surfaces return a
    byte-identical payload and can't drift.

Also reconciles the stdio tool-count invariant to the true live count of 73 (base
was 71; #6942's get_maintainer_lane mirror took it to 72 without bumping the
invariant, leaving main red on validate-tests; this tool makes it 73).

Tests

  • routes-pr-outcomes.test.ts (7) — own-history happy path, self-scoping (a session
    can't read another login), operator-token override, ?limit applied + malformed
    ?limit rejected with 400 (not clamped), empty-history returns [] not an error,
    and no wallet/hotkey/trust-score/reward terms leak.
  • mcp-cli-pr-outcome-tool.test.ts (3) — tool is registered on the stdio server,
    proxies to GET /v1/contributors/:login/pr-outcomes returning the route payload
    verbatim (parity), and forwards the optional limit as a query param.
  • Extends the shared mcp-cli-harness with the /pr-outcomes fixture route and an
    onApiRequest hook.

@superagent-security

Copy link
Copy Markdown
Contributor

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

The loopover_pr_outcome MCP tool (src/mcp/server.ts) returns a contributor's own
merged-PR outcome history, self-scoped via requireContributorAccess, but had no
REST route or CLI mirror despite fitting the existing /v1/contributors/:login/...
route family.

Add GET /v1/contributors/:login/pr-outcomes (self-scoped, ?limit=N mirroring the
tool's 1..100 bound) and register the loopover_pr_outcome CLI stdio tool. Both, and
the existing MCP tool, now delegate to one shared buildContributorPrOutcomes builder
in src/signals/ (mirroring the buildContributorOpenPrMonitor sibling), so all three
surfaces return one byte-identical payload and can never drift.

Reconcile the stdio tool-count invariant to the true live count of 73: the base was
71, JSONbored#6942's get_maintainer_lane mirror brought it to 72 without updating the
invariant (leaving main red on validate-tests), and this tool takes it to 73.

Tests: routes-pr-outcomes (self-scoping, operator override, ?limit validation,
empty-history, no wallet/hotkey/reward leakage) and mcp-cli-pr-outcome-tool (stdio
registration, route-proxy payload parity, limit forwarding), plus the shared
mcp-cli-harness fixture route.
@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.71%. Comparing base (244988b) to head (5b5fba9).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6965   +/-   ##
=======================================
  Coverage   93.71%   93.71%           
=======================================
  Files         685      686    +1     
  Lines       68379    68393   +14     
  Branches    18730    18733    +3     
=======================================
+ Hits        64080    64094   +14     
  Misses       3302     3302           
  Partials      997      997           
Flag Coverage Δ
shard-1 43.74% <12.50%> (-0.01%) ⬇️
shard-2 36.93% <43.75%> (+0.12%) ⬆️
shard-3 32.89% <12.50%> (+0.09%) ⬆️
shard-4 33.73% <93.75%> (-0.72%) ⬇️
shard-5 32.16% <12.50%> (-0.01%) ⬇️
shard-6 45.74% <12.50%> (-0.01%) ⬇️

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

Files with missing lines Coverage Δ
src/api/routes.ts 94.83% <100.00%> (+0.02%) ⬆️
src/mcp/server.ts 96.30% <100.00%> (-0.01%) ⬇️
src/signals/contributor-pr-outcomes.ts 100.00% <100.00%> (ø)

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

loopover-orb Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - reject/close recommended

Review updated: 2026-07-17 16:20:41 UTC

8 files · 1 AI reviewer · 2 blockers · CI green · dirty

🛑 Suggested Action - Reject/Close

Review summary
This PR adds a REST route and CLI mirror for the existing `loopover_pr_outcome` MCP tool, extracting the shared logic into `buildContributorPrOutcomes` so all three surfaces stay in sync — the same established pattern as the sibling `open-pr-monitor` feature. The refactor of `src/mcp/server.ts` correctly delegates to the new builder without behavior change, the REST route properly self-scopes via `requireContributorAccess` and rejects malformed `?limit` with 400 rather than clamping, and the stdio tool-count invariant is correctly bumped to 76. Tests cover self-scoping, operator override, limit validation, empty-history, and CLI/route parity — this looks like a well-targeted, low-risk mirror PR.

Nits — 5 non-blocking
  • src/api/routes.ts:3313 uses the bare literal `400` for the limit's upper bound and duplicates the `1..100` range check already encoded in `prOutcomeShape` in the CLI file — consider a shared constant if this pattern repeats again.
  • The PR description doesn't link to a specific open GitHub issue number (only `REST + CLI mirror for loopover_pr_outcome #6747` as a tracking reference) — worth confirming this maps to an actual open, maintainer-eligible issue rather than being self-initiated scope.
  • Consider extracting the `1..100` limit-validation logic (route) and `z.number().int().positive().max(100)` (CLI schema) into one shared validator if a fourth such route is added, to avoid three separate places encoding the same bound.
  • The JSDoc-style comment in contributor-pr-outcomes.ts:24-25 is a two-line comment block; per repo convention prefer a single short line unless the extra context is essential.
  • Readiness score is below the configured threshold — Use the readiness panel as advisory maintainer context; the score does not block this PR.

Why this is blocked

  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
  • Maintainer requires a linked issue — Link the relevant issue (for example Closes #123) before opening the PR.
📋 Copy for AI agents — paste into your coding agent
Fix the following blocker(s) from this PR review:

1. No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.

2. Maintainer requires a linked issue — Link the relevant issue (for example `Closes #123`) before opening the PR.

Decision drivers

  • ❌ Code review — 2 blockers (1 reviewer)
  • ❌ Gate result — Blocking (Repo-configured hard blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ⚠️ Missing No linked issue or no-issue rationale found.
Related work ⚠️ 3 scoped overlaps 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: 116 registered-repo PR(s), 58 merged, 5 issue(s).
Contributor context ✅ Confirmed Gittensor contributor lourincedaging0-commits; Gittensor profile; 116 PR(s), 5 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Review context
  • Author: lourincedaging0-commits
  • 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: 116 PR(s), 5 issue(s).
  • Related work: Titles/paths share 6 meaningful terms. (PR #6963)
  • Related work: Titles/paths share 5 meaningful terms. (issue #6747)
  • Related work: Titles/paths share 8 meaningful terms. (issue #6744, issue #6743)
  • Additional title-only matches omitted; title-only overlap does not block.
Contributor next steps
  • Start here: Explain no-issue PR.
  • Then work through the remaining 4 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.

🟩 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 17, 2026

Copy link
Copy Markdown
Contributor

LoopOver is closing this pull request on the maintainer's behalf (conflicts with the base branch — resolve and open a fresh PR; No linked issue detected; Maintainer requires a linked issue). 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.

@loopover-orb loopover-orb Bot closed this Jul 17, 2026
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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant