Skip to content

getMaintainerNoise/getAmsMinerCohort/getActivationPreview use a stricter MCP gate than their documented REST mirror #8338

Description

@JSONbored

Context

src/mcp/server.ts exposes three read-only maintainer-report MCP tools that each claim in their own
code comment to mirror a specific REST route's access gate, but actually use a stricter gate than the
route they claim to mirror:

  • getMaintainerNoise (src/mcp/server.ts:3458-3466)
  • getAmsMinerCohort (src/mcp/server.ts:3468-3480)
  • getActivationPreview (src/mcp/server.ts:3495-3518)

All three call await this.requireRepoApprovalQueueAccess(fullName) (defined at
src/mcp/server.ts:3383-3411), which additionally performs a live GitHub collaborator-permission
lookup
via getRepositoryCollaboratorPermission on top of the cached role/scope check.

But the REST routes these three tools' own comments say they mirror —
src/api/routes.ts:3262-3278 (maintainer-noise, ams-miner-cohort) and src/api/routes.ts:3202-3220
(activation-preview) — actually use the weaker requireRepoMaintainer (cached role + scope check
only, no live GitHub API lookup).

Every other structurally-identical read-only "maintainer-authenticated" report tool in the same file
(getRepoOutcomePatterns, getOutcomeCalibration, getGatePrecision, getSelftuneOverrideAudit,
getBurdenForecast, getConfigRecommendation, getRegistrationReadiness, getLabelAudit,
getMaintainerLane, getIssueQuality) correctly uses requireRepoAccess, whose underlying
canLoginAccessRepo check is the MCP-side equivalent of requireRepoMaintainer — i.e. it matches its
REST counterpart. The three tools above are the only outliers, and their own inline comments
(getAmsMinerCohort's comment literally says "same maintainer gate as getMaintainerNoise ... mirrors
GET /v1/repos/:owner/:repo/ams-miner-cohort") are factually wrong about which gate the REST route
actually uses.

Practical effect: a caller who is a legitimate maintainer by every other read tool's standard
(cached authorAssociation / installation-owner scope) but whose live GitHub collaborator lookup
fails, errors, or reflects team-based (non-collaborator-list) repo access gets denied specifically on
these three reports while every structurally identical sibling report tool succeeds for the same
caller. This is a functional regression relative to the tools' own documented intent, not an
over-permission/security bug — the fix tightens nothing, it aligns behavior with what's already
documented and with every sibling tool.

No existing test exercises the gap. test/unit/mcp-automation-state.test.ts directly exercises
requireRepoApprovalQueueAccess in-process with session identities, but only for the write tools
(propose_action, list/decide_pending_action, set_agent_paused, set_action_autonomy). The only
tests referencing loopover_get_maintainer_noise / loopover_get_ams_miner_cohort /
loopover_get_activation_preview (test/unit/mcp-cli-maintainer-noise.test.ts,
mcp-cli-ams-miner-cohort.test.ts, mcp-cli-activation-preview.test.ts) are stdio-proxy tests that
hit the REST endpoint over HTTP and never exercise LoopoverMcp's own gate branch as a session
identity — so this divergence has zero direct coverage today.

Requirements

  • Change all three handlers — getMaintainerNoise, getAmsMinerCohort, getActivationPreview — to
    call await this.requireRepoAccess(fullName) instead of
    await this.requireRepoApprovalQueueAccess(fullName), matching their documented REST mirrors and
    every structurally identical sibling read tool listed above.
  • Update the stale inline comments on all three handlers that currently claim parity with
    requireRepoApprovalQueueAccess/requireRepoWriteAccess-style gating — they must accurately
    describe the requireRepoAccess gate after the fix.
  • Do not touch requireRepoApprovalQueueAccess itself, or any of the write-action tools
    (propose_action, list/decide_pending_action, set_agent_paused, set_action_autonomy) that
    correctly and intentionally use the stricter gate — this issue is scoped to the three read-only
    report tools named above only.
  • Do not change src/api/routes.ts — the REST routes are already correct; only the MCP tool handlers
    are the mismatch.

Deliverables

  • getMaintainerNoise, getAmsMinerCohort, getActivationPreview in src/mcp/server.ts all use
    requireRepoAccess instead of requireRepoApprovalQueueAccess.
  • Each handler's inline comment accurately states which gate it uses and which REST route it
    mirrors.
  • A new in-process unit test (in a non-CLI test file, e.g. alongside
    test/unit/mcp-automation-state.test.ts's pattern) that constructs a session identity with
    cached-maintainer-level access but a failing/absent live collaborator-permission lookup, and
    asserts all three tools now succeed (regression test proving the gate now matches
    requireRepoAccess's behavior, not requireRepoApprovalQueueAccess's).

Test Coverage Requirements

This repo's Codecov patch gate is 99%+ of changed lines and branches (src/** is covered,
coverage.include). The new/changed lines in src/mcp/server.ts (the three requireRepoAccess call
sites) must be exercised by the new regression test above, plus both branches of the identity check
covered by the existing suite's pattern (cached-maintainer-pass and non-maintainer-reject cases) for
all three tools.

Expected Outcome

A caller who passes the maintainer check on any other read-only MCP report tool in this file also
passes it on getMaintainerNoise, getAmsMinerCohort, and getActivationPreview — no more silent,
undocumented stricter gate on exactly these three tools. Tool behavior matches both the code's own
inline documentation and its REST-route counterpart.

Links & Resources

  • src/mcp/server.ts:3458-3518 — the three tool handlers to fix
  • src/mcp/server.ts:3383-3411requireRepoApprovalQueueAccess (the gate to stop using here)
  • src/api/routes.ts:3202-3220, :3262-3278 — the REST routes these tools claim to mirror
  • test/unit/mcp-automation-state.test.ts — existing pattern for in-process session-identity tests
    against MCP gate functions

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:bugGittensor-scored bug fix — scores a 0.05x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions