Skip to content

feat(mcp): add repo-agnostic AI issue-planning tool#7476

Merged
JSONbored merged 1 commit into
mainfrom
claude/orb-github-issue-automation-080318
Jul 20, 2026
Merged

feat(mcp): add repo-agnostic AI issue-planning tool#7476
JSONbored merged 1 commit into
mainfrom
claude/orb-github-issue-automation-080318

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • Adds loopover_plan_repo_issues, a new MCP tool: given a maintainer-supplied free-form planning goal, AI-generates a small set of structured GitHub issue drafts (title/body/labels) for any repo the caller's App/Orb-brokered install is actually installed on.
  • This is genuinely generative — unlike generateContributorIssueDrafts (src/services/contributor-issue-draft.ts), which derives candidates purely from loopover-specific static signals (policy readiness, upstream drift, focus-manifest wanted paths) at zero LLM cost, the new src/services/issue-plan-draft.ts calls the configured AI reviewer, mirroring src/review/planner.ts's @loopover plan model-call/retry/budget shape closely (same primary+fallback model, same rate-limit short-circuit, same AI_DAILY_NEURON_BUDGET accounting).
  • Dry-run by default; an explicit {create:true, dryRun:false} is required to write, and creation goes exclusively through the installation-token/Orb-broker path added in #7425/#7467 — never a flat PAT — so it only works on a repo the caller's own App/Orb actually covers.
  • The MCP response includes each draft's full title/body/labels (unlike generateContributorIssueDrafts's deliberate scrub of that field): the content here is generated fresh from the caller's own goal for their own repo, so there is no loopover-internal signal to hide, and the whole point of the dry-run-by-default posture is letting a maintainer actually read the proposal before deciding to create it.
  • Reuses the dedup/decline machinery's shape (marker/fingerprint/wontfix/cooldown) from contributor-issue-draft.ts but with its own marker prefix (loopover-issue-plan-draft) — that module's own marker functions are hardcoded to its own prefix, so directly reusing them would mistag these drafts.
  • Deliberate scope decision, documented for future reference: no dedicated per-repo .loopover.yml settings.advisoryAiRouting.issuePlanning-style enable flag was added, unlike the other 4 advisory-tier AI capabilities (slop, e2eTestGen, planner, summaries). This capability is opt-in simply by a maintainer calling the tool (gated by requireRepoManageAccess), and additionally respects the existing fleet-wide AI_SUMMARIES_ENABLED/AI_PUBLIC_COMMENTS_ENABLED kill switches — a reasonable substitute given the primary safety layer here is access control, not automatic/webhook-triggered firing. A dedicated advisory-routing flag (full config-as-code wiring: schema + resolver + .loopover.yml schema + docs) is a good candidate for a fast-follow if a self-hoster asks for cost-conscious local-model routing on this specific capability.
  • Sub-issue of #7424 (Epic: ORB self-hoster issue & milestone planning routine). Milestone assignment is out of scope here — tracked separately as #7427.

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 typecheck
  • npm run test:coverage locally — full unsharded suite: 1011 files / 19224 tests passed, 2 skipped. The same 9 pre-existing failures in 3 unrelated miner test files (local-branch.test.ts, miner-init-verify-token.test.ts, miner-self-review-context.test.ts) reproduce identically on a clean checkout with this branch's changes stashed out (confirmed separately, tracked independently, unrelated to this PR). New code (src/services/issue-plan-draft.ts, the new MCP wiring in src/mcp/server.ts) is 100% branch-covered.
  • npm run selfhost:env-reference:check / npm run ui:openapi:check / npm run docs:drift-check / npm run manifest:drift-check — all clean; no new env vars introduced (reuses the already-documented AI_SUMMARIES_ENABLED/AI_PUBLIC_COMMENTS_ENABLED/AI_DAILY_NEURON_BUDGET/AI_GATEWAY_ID), no OpenAPI/manifest surface touched (MCP-only).
  • npm run ui:lint / npm run ui:typecheck / npm run ui:build — not run; this PR touches no files under apps/loopover-ui/**.
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries — test/unit/issue-plan-draft.test.ts (29 tests, 100% branch coverage of the new service) and test/unit/mcp-plan-repo-issues.test.ts (7 tests: access control, the explicit_create_requires_dry_run_false guard, goal validation, and surface parity with the underlying service).

If any required check was skipped, explain why:

  • ui:lint/ui:typecheck/ui:build: no apps/loopover-ui/** files changed.

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 — every generated draft's title/body is checked with isFocusManifestPublicSafe before ever being proposed or created, matching contributor-issue-draft.ts's own contract.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests — MCP access-control denial, missing installation, non-2xx GitHub response, and global agent pause/freeze overlay are all covered.
  • API/OpenAPI/MCP behavior is updated and tested where needed — new MCP tool fully tested; no HTTP/OpenAPI surface added.
  • UI changes use live API data or real empty/error/loading states. (N/A — no UI.)
  • Visible UI changes include a UI Evidence section. (N/A — backend/MCP-only change.)
  • Public docs/changelogs are updated where needed. (N/A — no user-facing docs surface for MCP tool additions in this repo beyond the tool's own description string, which is included in this diff.)

UI Evidence

N/A — this is a backend/MCP-only change with no visible UI, frontend, or docs surface.

Notes

  • Sub-issue of #7424. Builds directly on #7425's installation-token/Orb-broker issue-write path (already merged, #7467).

Closes #7426

Adds loopover_plan_repo_issues: given a maintainer-supplied free-form
goal, AI-generates a small set of structured GitHub issue drafts
(title/body/labels) for any repo the caller's App/Orb is installed on.

Unlike generateContributorIssueDrafts (loopover-specific static
signals, zero LLM cost), this genuinely generates from the goal text,
mirroring review/planner.ts's model-call/retry/budget shape. Dry-run
by default; creates only via the installation-token/Orb-broker path
(#7425), never a flat PAT. Response includes full draft title/body,
unlike the scrubbed contributor-drafts tool, since there is no
loopover-internal signal to hide here.

No dedicated per-repo enable flag: gated by the existing fleet-wide
AI_SUMMARIES_ENABLED/AI_PUBLIC_COMMENTS_ENABLED switches and MCP
access control (requireRepoManageAccess) rather than a new
config-as-code surface, since this is opt-in simply by a maintainer
calling the tool.

Closes #7426
@JSONbored JSONbored self-assigned this Jul 20, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

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

@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.37%. Comparing base (582fc3a) to head (495c91e).
⚠️ Report is 4 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #7476    +/-   ##
========================================
  Coverage   91.36%   91.37%            
========================================
  Files         717      718     +1     
  Lines       73016    73178   +162     
  Branches    21631    21678    +47     
========================================
+ Hits        66713    66864   +151     
- Misses       5265     5272     +7     
- Partials     1038     1042     +4     
Flag Coverage Δ
shard-1 35.26% <93.20%> (+1.10%) ⬆️
shard-2 41.22% <9.87%> (+1.91%) ⬆️
shard-3 37.29% <9.87%> (+4.69%) ⬆️
shard-4 40.94% <9.87%> (+1.41%) ⬆️
shard-5 27.47% <9.87%> (-9.12%) ⬇️
shard-6 29.78% <59.87%> (-4.55%) ⬇️

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

Files with missing lines Coverage Δ
src/mcp/server.ts 96.45% <100.00%> (+0.05%) ⬆️
src/services/issue-plan-draft.ts 100.00% <100.00%> (ø)

... and 2 files with indirect coverage changes

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 20, 2026
@loopover-orb

loopover-orb Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-20 13:56:55 UTC

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

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
Adds a new MCP tool `loopover_plan_repo_issues` that AI-generates GitHub issue drafts from a free-form maintainer goal, for any repo the caller's App/Orb install covers. It closely mirrors the existing `review/planner.ts` model-call/retry/budget shape and `contributor-issue-draft.ts`'s dedup/decline machinery (with its own marker prefix to avoid tag collisions), defaults to dry-run, and gates real writes behind an explicit `{create:true, dryRun:false}` plus the existing installation-token/Orb-broker path (never a flat PAT). The dry-run guard, global agent pause/freeze override, budget check before the model call, and per-candidate malformed-output tolerance are all traced correctly and covered by extensive unit and MCP-layer tests, including a regression test for the rate-limit short-circuit behavior.

Nits — 6 non-blocking
  • src/services/issue-plan-draft.ts:179-215 nests to depth 5 in the main draft loop (model call → per-candidate normalize → safety/duplicate/declined/create branches); consider extracting the per-candidate classification into a small helper for readability.
  • runIssuePlanModel (src/services/issue-plan-draft.ts) retries the SAME model on a legitimate `{"issues":[]}` response (e.g. an intentionally too-vague goal) exactly like a parse failure, burning an extra call/budget before falling back — worth special-casing an explicit empty-array response as 'no issues' rather than 'retry'.
  • recordIssuePlanUsage always logs `model` as the combined 'primary+fallback' string even when only the primary succeeded, so usage telemetry can't tell which model actually produced the output.
  • Several new magic numbers (2000/5/429/0.2/200/7425) could be named constants for consistency with the module's existing MAX_* constants.
  • src/mcp/server.ts and issue-plan-draft.ts are both large files; the new tool adds a reasonable, self-contained chunk but keep an eye on server.ts's growth as more tools land there.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.

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 #7426
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: 28 registered-repo PR(s), 21 merged, 427 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 28 PR(s), 427 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, Ruby, Go, JavaScript, MDX, Shell, Solidity
  • Official Gittensor activity: 28 PR(s), 427 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
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 added the manual-review Gittensor contributor context label Jul 20, 2026
@JSONbored
JSONbored merged commit e03a256 into main Jul 20, 2026
17 checks passed
@JSONbored
JSONbored deleted the claude/orb-github-issue-automation-080318 branch July 20, 2026 17:48
@github-actions github-actions Bot mentioned this pull request Jul 20, 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. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spec: repo-agnostic issue-planning MCP tool (draft-by-default, explicit create)

1 participant