Skip to content

feat(mcp): compute loopover_check_slop_risk in-process from the shared engine - #6329

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
nghetienhiep:fix/issue-6267
Jul 16, 2026
Merged

feat(mcp): compute loopover_check_slop_risk in-process from the shared engine#6329
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
nghetienhiep:fix/issue-6267

Conversation

@nghetienhiep

Copy link
Copy Markdown
Contributor

Summary

Make the local MCP server's loopover_check_slop_risk tool compute its result in-process from
@loopover/engine, matching the remote server's existing in-process behavior, so slop-risk
self-checks work fully offline instead of proxying over HTTP (apiPost("/v1/lint/slop-risk", …)).

buildSlopAssessment's canonical logic already lives in
packages/loopover-engine/src/signals/slop.ts, and both the remote MCP server
(src/mcp/server.ts checkSlopRisk) and the API route (src/api/routes.ts /v1/lint/slop-risk)
already call it directly. The only blocker for the local CLI was that @loopover/engine's
exports map did not expose ./signals/slop, so the local package could not import the function
and fell back to an HTTP proxy — even though it already depends on @loopover/engine.

  • Added a ./signals/slop entry to packages/loopover-engine/package.json's exports map,
    pointing at the same built module (dist/signals/slop.{js,d.ts}) the barrel and the src/
    re-export shim already consume.
  • Updated packages/loopover-mcp/bin/loopover-mcp.js's loopover_check_slop_risk handler to call
    buildSlopAssessment(input) directly and wrap it as { ...assessment, rubric: SLOP_RUBRIC_MARKDOWN }
    — byte-for-byte the shape the /v1/lint/slop-risk route returned, so the tool's documented output
    (slopRisk, band, findings, rubric) is unchanged, only computed locally. Refreshed its description
    ("Computed in-process; no repo data and no API round-trip").
  • Left the remote server (src/mcp/server.ts), the API route, the slop-risk CLI subcommand, and
    the review-pr composition untouched — this mirrors feat(mcp): compute loopover_lint_pr_text in-process from the shared engine #6308's identical change for
    loopover_lint_pr_text, which converted only the stdio tool handler.

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 #6267).

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck
  • npm run test:coverage locally — full suite green except 3 files that shell out to the
    sqlite3 CLI (absent in my sandbox, present in CI); none import any file this PR changes. The
    diff touches no src/** line, so codecov/patch has no changed lines to measure.
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run engine-parity:drift-check
  • npm run manifest:drift-check
  • npm run docs:drift-check
  • npm run command-reference:check
  • npm audit --audit-level=moderate
  • New regression test drives the real stdio server with an unreachable LOOPOVER_API_URL +
    tight timeout, proving the tool runs fully offline (test/unit/mcp-local-check-slop-risk.test.ts).

If any required check was skipped, explain why:

  • test:workers / ui:* were not run: this change touches no Cloudflare-worker code and no
    apps/loopover-ui/** file, so those jobs cover nothing in this diff.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, PATs, private keys, raw trust scores, private
    rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized and low-noise; the offline response is asserted to never
    leak private financial terminology.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests — n/a (no such change).
  • API/OpenAPI/MCP behavior is updated and tested where needed.
  • UI changes use live API data or real empty/error/loading states — n/a (no UI change).
  • Visible UI changes include a UI Evidence section — n/a (no visible UI change).
  • Public docs/changelogs are updated where needed; no changelog edit in this PR.

Notes

Closes #6267

…d engine

Make the local MCP server's loopover_check_slop_risk tool compute its result in-process from
@loopover/engine, matching the remote server's existing in-process behavior, so slop-risk
self-checks work fully offline instead of proxying over HTTP (apiPost("/v1/lint/slop-risk", …)).

buildSlopAssessment's canonical logic already lives in packages/loopover-engine/src/signals/slop.ts,
and both the remote MCP server (src/mcp/server.ts checkSlopRisk) and the API route
(/v1/lint/slop-risk) call it directly. The only blocker for the local CLI was that
@loopover/engine's exports map did not expose ./signals/slop.

- Add a ./signals/slop entry to packages/loopover-engine/package.json's exports map, pointing at
  the same built module the barrel and the src/ re-export shim already consume.
- Update loopover_check_slop_risk's handler to call buildSlopAssessment(input) directly and wrap
  it as { ...assessment, rubric: SLOP_RUBRIC_MARKDOWN } — byte-for-byte the shape the
  /v1/lint/slop-risk route returned, so the tool's documented output (slopRisk, band, findings,
  rubric) is unchanged, only computed locally. Refresh its description accordingly.
- Leave the remote server, the API route, the slop-risk CLI subcommand, and the review-pr
  composition untouched, mirroring JSONbored#6308's identical change for loopover_lint_pr_text.

Closes JSONbored#6267
@nghetienhiep
nghetienhiep requested a review from JSONbored as a code owner July 16, 2026 02:05
@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 the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 16, 2026
@loopover-orb

loopover-orb Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-16 02:14:35 UTC

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

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This PR extends the same in-process pattern from #6308 to the loopover_check_slop_risk tool: it exposes packages/loopover-engine's ./signals/slop subpath in the exports map and swaps the stdio handler's apiPost proxy call for a direct buildSlopAssessment(input) call, preserving the exact `{ ...assessment, rubric }` shape the route already returns. The added test suite exercises the tool via a real stdio client against an unreachable API endpoint, which correctly proves the offline/in-process behavior rather than mocking it. The change is narrow, consistent with the established convention, and the description update accurately reflects the new behavior.

Nits — 3 non-blocking
  • packages/loopover-mcp/bin/loopover-mcp.js:834-836 — the added comment is fairly verbose for a one-line call; consider trimming to match the terser style used elsewhere in this file (e.g. the lint-pr-text handler).
  • test/unit/mcp-local-check-slop-risk.test.ts — the three test cases rely on hard-coded scoring internals (30, 0, band strings) that couple the test tightly to slop.ts's exact weights; a change to the rubric's point values would break this test even though the wiring is still correct.
  • Consider asserting `result.structuredContent` typing against the actual buildSlopAssessment return type (e.g. via a shared type import) instead of an inline cast, to catch future shape drift at compile time.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #6267
Related work ⚠️ 2 scoped overlaps Top overlaps are listed below; lower-confidence bulk is hidden.
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: 112 registered-repo PR(s), 64 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor nghetienhiep; Gittensor profile; 112 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: minor
Linked issue satisfaction

Addressed
The diff adds the ./signals/slop export to @​loopover/engine's package.json and switches the local loopover_check_slop_risk handler to call buildSlopAssessment directly with the same {...assessment, rubric} shape, matching the remote server's in-process behavior while leaving remote server/API/CLI code untouched, plus a regression test that exercises the tool against an unreachable API URL to prove

Review context
  • Author: nghetienhiep
  • 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: 112 PR(s), 0 issue(s).
  • Related work: Titles/paths share 7 meaningful terms. (issue #6267, issue #6301)
  • Related work: Titles/paths share 10 meaningful terms. (issue #6267, issue #6269)
Contributor next steps
  • Start here: Review top overlaps.
  • Then work through the remaining 2 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 <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> 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://gittensory.aethereal.dev/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 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LoopOver approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit c23639b into JSONbored:main Jul 16, 2026
14 checks passed
@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.60%. Comparing base (44570d0) to head (0d7cc0b).
⚠️ Report is 42 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6329   +/-   ##
=======================================
  Coverage   95.60%   95.60%           
=======================================
  Files         596      596           
  Lines       47121    47121           
  Branches    14999    14999           
=======================================
  Hits        45049    45049           
  Misses       1290     1290           
  Partials      782      782           
Flag Coverage Δ
shard-1 44.13% <ø> (ø)
shard-2 36.57% <ø> (+0.06%) ⬆️
shard-3 32.40% <ø> (ø)
shard-4 34.46% <ø> (+0.06%) ⬆️
shard-5 31.68% <ø> (-0.21%) ⬇️
shard-6 44.78% <ø> (ø)

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

@github-actions github-actions Bot mentioned this pull request Jul 16, 2026
12 tasks
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.

feat(mcp): make loopover_check_slop_risk work offline in the local CLI by exposing @loopover/engine's ./signals/slop export

1 participant