Skip to content

feat(miner): expose manage-phase status as a read-only MCP tool - #5984

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
cleanjunc:feat/miner-mcp-manage-status
Jul 15, 2026
Merged

feat(miner): expose manage-phase status as a read-only MCP tool#5984
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
cleanjunc:feat/miner-mcp-manage-status

Conversation

@cleanjunc

Copy link
Copy Markdown
Contributor

Summary

  • Adds loopover_miner_get_manage_status to the miner's stdio MCP server (packages/loopover-miner/bin/loopover-miner-mcp.js), exposing the manage-phase status that loopover-miner manage status --json already prints. An MCP client can now ask "what is the live status of each PR this miner is managing, and what does that look like across the whole run?" without shelling out to the CLI.
  • No new join logic: the tool reuses the already-exported collectManageStatus({ portfolioQueue, eventLedger }) and collectRunPortfolio({ portfolioQueue, eventLedger, runStateStore }) from lib/manage-status.js unchanged, returning their identical additive { rows, runPortfolio } shape.
  • This is a genuinely distinct aggregation from what is already exposed: loopover_miner_get_portfolio_dashboard wraps status counts from the portfolio queue alone, and loopover_miner_get_run_state wraps run-state alone. Neither returns the per-managed-PR detail rows or the run-portfolio view that joining all three local stores produces.
  • Read-only by construction: never calls GitHub, never mutates local stores, takes no arguments.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • 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 (e.g. Closes #123) — a linked open issue is required for every contributor PR.

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck
  • npm run test:coverage locally; codecov/patch requires ≥99% coverage of the lines AND branches you changed (aim for 100% on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.
  • 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
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

Ran the full local gate via npm run test:ci — green, plus npm audit --audit-level=moderate. Note: packages/loopover-miner/bin/** is not in the Codecov coverage include glob (only packages/loopover-miner/lib/** is), so this file carries no strict patch-coverage obligation — tests were still written to full parity with the sibling loopover_miner_get_portfolio_dashboard / loopover_miner_get_run_state tools' coverage (populated case, empty case, store-ownership invariant), plus a new row in the shared miner-mcp-contract.test.ts invariant table.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests.
  • API/OpenAPI/MCP behavior is updated and tested where needed.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks.
  • Visible UI changes include a UI Evidence section below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

If any required check was skipped, explain why:

  • Auth/CORS and UI boxes are not applicable — this is a local, offline, read-only MCP tool with no auth/session/UI surface (the stdio server has no network listener).

UI Evidence

Not applicable — no visible UI/frontend/docs/extension change beyond the README's MCP tool list, which is covered by the existing miner MCP tool documentation parity test.

Notes

  • Store ownership mirrors runManageStatus's own three-way finally verbatim (ownsX = options.initX === undefined), so the tool closes only the stores it opened itself and leaves injected ones alone — the same convention loopover_miner_get_portfolio_dashboard and loopover_miner_get_run_state already use in this file.
  • Tests cover the populated managed-PR set (non-empty rows + runPortfolio), the empty case ({ rows: [], runPortfolio: [] }), a structural-identity invariant asserting the wrapper adds no drift versus calling the aggregators directly, a read-without-mutating invariant (no enqueue / appendEvent / setRunState), and the store-ownership invariant (injected stores are left open and still usable afterward).
  • The run-portfolio assertion deliberately includes a run-state-only repo with no PRs, pinning that the fold is not PR-scoped (feat(miner-manage-ui): manage-phase dashboard panel for run portfolio #4279).
  • Because this is the only miner MCP tool that opens three stores at once, its miner-mcp-contract.test.ts rows seed all three injection seams and vary only the one under test — an un-stubbed seam would otherwise fall through to a real on-disk store.

Closes #5822

@cleanjunc
cleanjunc requested a review from JSONbored as a code owner July 15, 2026 05:44
@superagent-security

Copy link
Copy Markdown
Contributor

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

@cleanjunc
cleanjunc marked this pull request as draft July 15, 2026 05:45
@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 15, 2026
@loopover-orb

loopover-orb Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-15 06:04:00 UTC

6 files · 1 AI reviewer · no blockers · readiness 98/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This adds a new read-only MCP tool `loopover_miner_get_manage_status` that wraps the existing `collectManageStatus`/`collectRunPortfolio` aggregators from `manage-status.js`, mirroring the pattern already used by `loopover_miner_get_portfolio_dashboard`. The tool correctly follows the ownership/close convention (only closes stores it opened itself), and the diff includes solid test coverage: registration, populated/empty payloads, structural-identity to the underlying collectors, no-mutation invariant, and store-ownership invariant. It also updates the d.ts doc comment, README, and the shared MCP contract test, keeping documentation and behavior in sync.

Nits — 4 non-blocking
  • packages/loopover-miner/bin/loopover-miner-mcp.js: the three `options.initX ?? initX` calls and the `ownsX`/`try/finally` close logic duplicate the pattern from the portfolio-dashboard tool almost exactly — consider a small helper to avoid repeating the three-store open/close boilerplate as more multi-store tools are added.
  • test/unit/miner-mcp-manage-status.test.ts: `connectedClient` opens a fresh server/client pair per call in `callManageStatus`, so tests that both list tools and call the tool (e.g. none currently do both) would connect twice — worth a comment noting this is intentional isolation, not an oversight.
  • Consider extracting the repeated `ownsX ? store.close() : undefined` finally-block pattern (now duplicated across at least two tools) into a small shared helper in the MCP server file.
  • In the README entry, consider explicitly noting (as the tool description does) that this is the first tool joining three local stores, to help future readers understand why it takes three optional injection seams.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #5822
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low 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: 49 registered-repo PR(s), 18 merged, 30 issue(s).
Contributor context ✅ Confirmed Gittensor contributor cleanjunc; Gittensor profile; 49 PR(s), 30 issue(s).
Gate result ✅ Passing No configured blocker found.
Improvement ✅ Minor risk: clean · value: minor · LLM: moderate
Review context
  • Author: cleanjunc
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, Cuda, JavaScript, Scala
  • Official Gittensor activity: 49 PR(s), 30 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
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

@cleanjunc
cleanjunc force-pushed the feat/miner-mcp-manage-status branch from f49a7cc to 5329817 Compare July 15, 2026 05:47
@cleanjunc
cleanjunc force-pushed the feat/miner-mcp-manage-status branch from 5329817 to 7dffe16 Compare July 15, 2026 05:50
@cleanjunc
cleanjunc marked this pull request as ready for review July 15, 2026 05:52

@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 63f74fb into JSONbored:main Jul 15, 2026
14 checks passed
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): expose miner manage-phase status/run-portfolio as a read-only MCP tool (loopover_miner_get_manage_status)

1 participant