Skip to content

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

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#6968
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

Closes #6747

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 (malformed ?limit → 400, not clamped).
  • 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 (bumped as new
CLI mirrors landed on main during review).

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.

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.
@superagent-security

Copy link
Copy Markdown
Contributor

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

@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 (4966070) to head (ebca598).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6968   +/-   ##
=======================================
  Coverage   93.71%   93.71%           
=======================================
  Files         686      687    +1     
  Lines       68392    68406   +14     
  Branches    18730    18733    +3     
=======================================
+ Hits        64093    64107   +14     
  Misses       3302     3302           
  Partials      997      997           
Flag Coverage Δ
shard-1 43.74% <12.50%> (-0.01%) ⬇️
shard-2 36.99% <43.75%> (+0.06%) ⬆️
shard-3 32.91% <12.50%> (+0.10%) ⬆️
shard-4 33.76% <93.75%> (-0.10%) ⬇️
shard-5 32.12% <12.50%> (-0.01%) ⬇️
shard-6 45.75% <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.84% <100.00%> (+0.02%) ⬆️
src/mcp/server.ts 96.26% <100.00%> (-0.01%) ⬇️
src/signals/contributor-pr-outcomes.ts 100.00% <100.00%> (ø)

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x 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:36:46 UTC

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

🛑 Suggested Action - Reject/Close

Review summary
This PR closes #6747 by extracting the existing loopover_pr_outcome MCP tool logic into a shared buildContributorPrOutcomes builder, then wiring a REST route and CLI mirror to it, following the established pattern from buildContributorOpenPrMonitor. The refactor is clean — the MCP tool's behavior is preserved byte-for-byte, the REST route correctly reuses requireContributorAccess for self-scoping and rejects malformed ?limit with 400 rather than clamping (matching the description), and the CLI proxy correctly forwards login/limit. Tests cover self-scoping, operator override, limit validation edge cases, empty history, and payload parity across all three surfaces, and the stdio tool-count invariant was correctly bumped to 77.

Nits — 7 non-blocking
  • src/api/routes.ts:3326 — the `400` status code and the `1..100` bound are inline magic numbers; consider a named constant shared with contributor-pr-outcomes.ts's DEFAULT_OUTCOME_LIMIT pattern for discoverability.
  • packages/loopover-mcp/bin/loopover-mcp.js and src/api/routes.ts continue growing as large monolithic files (5452 and 3334 lines respectively) — not this PR's fault, but each new mirrored surface adds to the maintenance burden of a single file.
  • test/unit/routes-pr-outcomes.test.ts's malformed-limit test includes an empty-string case (`limit=`) which becomes `Number('')` = 0 — worth a one-line comment clarifying that's intentionally covered by the `< 1` arm rather than a separate NaN path.
  • Consider extracting the `1..100` limit validation (parse + range-check + 400 response) into a small shared helper since this is the second `/v1/contributors/:login/...` route to need it, per the DRY pattern the PR already follows for the builder itself.
  • The JSDoc comment on buildContributorPrOutcomes in src/signals/contributor-pr-outcomes.ts is good practice — consider the same one-line reminder on the REST route and CLI proxy functions for symmetry with contributor-open-pr-monitor.ts if that sibling has one.
  • Pull request duplicates other open work — Check for an existing pull request or issue covering this change and coordinate or consolidate before continuing.
  • 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

  • Linked issue overlaps another open PR — Review the related PRs before spending reviewer time on duplicate work.
📋 Copy for AI agents — paste into your coding agent
Fix the following blocker(s) from this PR review:

1. Linked issue overlaps another open PR — Review the related PRs before spending reviewer time on duplicate work.

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 ✅ Linked #6747
Related work ⚠️ Same linked issue: #6963 Another open PR references the same linked issue.
Change scope ❌ 8/20 High 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: 122 registered-repo PR(s), 60 merged, 5 issue(s).
Contributor context ✅ Confirmed Gittensor contributor lourincedaging0-commits; Gittensor profile; 122 PR(s), 5 issue(s).
Improvement ✅ Minor risk: low · value: minor · LLM: moderate
Linked issue satisfaction

Addressed
The PR adds the GET /v1/contributors/:login/pr-outcomes route with requireContributorAccess reusing listNotificationDeliveriesForRecipient (via the new shared buildContributorPrOutcomes), registers a loopover_pr_outcome CLI stdio tool that proxies the route, and includes unit tests covering both surfaces plus a parity assertion between MCP/REST/CLI outputs.

Review context
Contributor next steps
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 (Linked issue overlaps another open PR; duplicate of open PR #6963). 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:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

REST + CLI mirror for loopover_pr_outcome

1 participant