You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of #9515 — the AMS half of "MCP as the management plane." The miner MCP (packages/loopover-miner/bin/loopover-miner-mcp.ts) exposes 11 read-only tools, while the entire mutating ops surface is CLI-only: governor pause/resume (lib/governor-pause-cli.ts), queue ops (lib/portfolio-queue-cli.ts: next|claim-batch|done|release|requeue), claim ops (lib/claim-ledger-cli.ts), run-state set (lib/run-state-cli.ts), deny-hooks approve/reject (lib/deny-hooks-cli.ts), calibration apply/revert (lib/calibration-cli.ts, double-gated), right-to-be-forgotten purge (lib/purge-cli.ts), store migrations (lib/migrate-cli.ts). The safe-dispatch chokepoint already exists: lib/chat-action-registry.ts + chat-action-dispatch.ts structurally refuse any handler that isn't governorGatedHandler-wrapped (built for the dashboard chat, #6521/#6838/#6839), and the miner dashboard already dispatches governor pause/resume + queue release/requeue through it (apps/loopover-miner-uivite-governor-api.ts:56-58, vite-portfolio-queue-actions-api.ts:92-94).
Hosted AMS bones also exist: control-plane/ tenant CRUD + cron wake (ams-wake.ts), loopover-miner-hosted entry with /health+/ready (lib/ams-health-server.ts), tenant CLI (lib/tenant-cli.ts) — and #9199 wants tenant-scoped, chat-groundable health tools.
The 11 existing tools gain contract registration + output schemas in #9518 (not here). This issue adds the mutating and hosted tool families.
Tool catalog (the deliverable — renames/cuts recorded on this issue first)
Local ops, read (availability selfhost, locality miner): loopover_miner_doctor (dedicated tool — today doctor rides inside loopover_miner_status; split so status stays cheap and doctor can grow checks) · loopover_miner_get_metrics_snapshot (the Prometheus families already exported by the metrics CLI, as structured JSON).
Local ops, mutating (availability selfhost, all dispatched through the governor-gated chokepoint — a raw handler that bypasses chat-action-registry is defective by definition, mirroring test/unit/no-direct-octokit.test.ts's structural rule): loopover_miner_governor_pause / loopover_miner_governor_resume (mirror the dashboard actions; fire the same ams-notifications side-channel) · loopover_miner_queue_release / loopover_miner_queue_requeue (per-item, mirroring the dashboard's two queue actions) · loopover_miner_claim_release · loopover_miner_deny_hooks_decide (approve|reject on a pending synthesized hook) · loopover_miner_run_migrations (existing-stores-only, dry-run default like the CLI) · loopover_miner_purge_repo (destructive: right-to-be-forgotten; requires confirm: z.literal(true) + elicitation; returns the same per-store purge report as the CLI).
Deliberately excluded from MCP (recorded as decision): calibration apply-min-rank/revert-min-rank (stays CLI-only behind its existing double gate — an agent-reachable path to loosen calibration floors is not wanted), state set (raw run-state mutation is a repair tool, not an operation), kill-switch trip/untrip (one-way breaker semantics stay out of agent reach; pause/resume is the agent-safe control).
Hosted tenants (availability cloud, auth control-plane admin; served by the hosted/remote side, not the local bin): loopover_ams_tenant_create / loopover_ams_tenant_list / loopover_ams_tenant_destroy (destructive, confirm + elicitation) — wrapping lib/tenant-client.ts's control-plane calls · loopover_ams_tenant_health (#9199: per-tenant health/status — wake schedule, last cycle outcomes, container health) · loopover_ams_tenant_wake (trigger an immediate cycle for one tenant via the ams-wake machinery, bounded by the same per-tenant schedule guards).
Structural governor gating: the miner MCP's mutating tools register through chat-action-registry (or a shared registry both chat and MCP consume — preferred; record the shape in the PR), so the compile-time/structural "only governor-gated handlers" rule covers MCP identically. Add the structural test.
Mutating tools write the event ledger exactly as their CLI twins do (same event types), so loopover_miner_get_audit_feed shows MCP-initiated actions indistinguishably from CLI ones, with an actor/source field distinguishing origin.
Privacy boundary unchanged: no wallet/hotkey/reward/trust-score data in any tool response (existing FORBIDDEN_CONTENT matchers extended to the new tools in the miner contract parity suite).
The dashboard's governor/queue endpoints and the new MCP tools call the same underlying action functions — one implementation, asserted by test.
Full branch-counted coverage; fix-what-you-find applies (the docker-compose.miner.yml/k8srun→loop defect is already being fixed separately — do not duplicate it here).
Exclusion decisions above recorded (calibration/state-set/kill-switch stay CLI-only)
Generated docs picked up the catalog with zero hand-edits
Expected outcome
A dual-role operator (or the #9184 hosted chat) can pause/resume the governor, groom the portfolio queue, decide deny-hooks, run store migrations, execute a confirmed right-to-be-forgotten purge, and administer hosted tenants — all over MCP, all schema-validated, all governor-gated and ledger-audited, with the dangerous calibration/kill-switch levers deliberately unreachable by agents.
References
Part of #9515. Blocked by #9518. Advances #9184 (action catalog) and #5230 (AMS cloud convergence); implements #9199's health-tool half. Relates to #5221/#5226 (fleet rollout/health design).
Context
Part of #9515 — the AMS half of "MCP as the management plane." The miner MCP (
packages/loopover-miner/bin/loopover-miner-mcp.ts) exposes 11 read-only tools, while the entire mutating ops surface is CLI-only: governor pause/resume (lib/governor-pause-cli.ts), queue ops (lib/portfolio-queue-cli.ts:next|claim-batch|done|release|requeue), claim ops (lib/claim-ledger-cli.ts), run-state set (lib/run-state-cli.ts), deny-hooks approve/reject (lib/deny-hooks-cli.ts), calibration apply/revert (lib/calibration-cli.ts, double-gated), right-to-be-forgotten purge (lib/purge-cli.ts), store migrations (lib/migrate-cli.ts). The safe-dispatch chokepoint already exists:lib/chat-action-registry.ts+chat-action-dispatch.tsstructurally refuse any handler that isn'tgovernorGatedHandler-wrapped (built for the dashboard chat, #6521/#6838/#6839), and the miner dashboard already dispatches governor pause/resume + queue release/requeue through it (apps/loopover-miner-uivite-governor-api.ts:56-58,vite-portfolio-queue-actions-api.ts:92-94).Hosted AMS bones also exist:
control-plane/tenant CRUD + cron wake (ams-wake.ts),loopover-miner-hostedentry with/health+/ready(lib/ams-health-server.ts), tenant CLI (lib/tenant-cli.ts) — and #9199 wants tenant-scoped, chat-groundable health tools.The 11 existing tools gain contract registration + output schemas in #9518 (not here). This issue adds the mutating and hosted tool families.
Tool catalog (the deliverable — renames/cuts recorded on this issue first)
Local ops, read (availability
selfhost, localityminer):loopover_miner_doctor(dedicated tool — today doctor rides insideloopover_miner_status; split sostatusstays cheap anddoctorcan grow checks) ·loopover_miner_get_metrics_snapshot(the Prometheus families already exported by themetricsCLI, as structured JSON).Local ops, mutating (availability
selfhost, all dispatched through the governor-gated chokepoint — a raw handler that bypasseschat-action-registryis defective by definition, mirroringtest/unit/no-direct-octokit.test.ts's structural rule):loopover_miner_governor_pause/loopover_miner_governor_resume(mirror the dashboard actions; fire the sameams-notificationsside-channel) ·loopover_miner_queue_release/loopover_miner_queue_requeue(per-item, mirroring the dashboard's two queue actions) ·loopover_miner_claim_release·loopover_miner_deny_hooks_decide(approve|rejecton a pending synthesized hook) ·loopover_miner_run_migrations(existing-stores-only, dry-run default like the CLI) ·loopover_miner_purge_repo(destructive: right-to-be-forgotten; requiresconfirm: z.literal(true)+ elicitation; returns the same per-store purge report as the CLI).Deliberately excluded from MCP (recorded as decision): calibration
apply-min-rank/revert-min-rank(stays CLI-only behind its existing double gate — an agent-reachable path to loosen calibration floors is not wanted),state set(raw run-state mutation is a repair tool, not an operation), kill-switch trip/untrip (one-way breaker semantics stay out of agent reach; pause/resume is the agent-safe control).Hosted tenants (availability
cloud, auth control-plane admin; served by the hosted/remote side, not the local bin):loopover_ams_tenant_create/loopover_ams_tenant_list/loopover_ams_tenant_destroy(destructive, confirm + elicitation) — wrappinglib/tenant-client.ts's control-plane calls ·loopover_ams_tenant_health(#9199: per-tenant health/status — wake schedule, last cycle outcomes, container health) ·loopover_ams_tenant_wake(trigger an immediate cycle for one tenant via theams-wakemachinery, bounded by the same per-tenant schedule guards).Requirements
@loopover/contractentry (real input/output schemas,auth/locality/availability/destructiveHint), registered per contract(remote): migrate the remote MCP server's tools to @loopover/contract — typed handlers, real output schemas #9518, smoke-called invalidate:mcp(mcp: validate:mcp contract validator — Ajv output enforcement, per-tool smoke gate, version tri-lock across all three servers #9520) with fakes for stores/control-plane.chat-action-registry(or a shared registry both chat and MCP consume — preferred; record the shape in the PR), so the compile-time/structural "only governor-gated handlers" rule covers MCP identically. Add the structural test.loopover_miner_get_audit_feedshows MCP-initiated actions indistinguishably from CLI ones, with anactor/sourcefield distinguishing origin.FORBIDDEN_CONTENTmatchers extended to the new tools in the miner contract parity suite).docker-compose.miner.yml/k8srun→loopdefect is already being fixed separately — do not duplicate it here).Non-goals
Deliverables
purge_repodoctorsplit + metrics snapshot toolExpected outcome
A dual-role operator (or the #9184 hosted chat) can pause/resume the governor, groom the portfolio queue, decide deny-hooks, run store migrations, execute a confirmed right-to-be-forgotten purge, and administer hosted tenants — all over MCP, all schema-validated, all governor-gated and ledger-audited, with the dangerous calibration/kill-switch levers deliberately unreachable by agents.
References
Part of #9515. Blocked by #9518. Advances #9184 (action catalog) and #5230 (AMS cloud convergence); implements #9199's health-tool half. Relates to #5221/#5226 (fleet rollout/health design).