fix(mcp): drop autonomy levels the server removed in #4620 from the CLI - #6378
Conversation
…rom the CLI `loopover-mcp maintain set-level` client-side-validated against MAINTAIN_AUTONOMY_LEVELS, which still listed "suggest"/"propose". JSONbored#4620 removed both server-side -- PUT /settings validates the body against the live AUTONOMY_LEVELS enum -- so the CLI waved through two values the API rejects, turning what should be an immediate, clear client-side error into a confusing 400. The same stale list also fed `maintain --help`, so the help text advertised both dead levels as valid input. Narrow MAINTAIN_AUTONOMY_LEVELS to the live enum. Both call sites (help text and validation) read the constant, so this fixes them together. Kept as a literal rather than an import, per the issue's fallback: this file resolves @loopover/engine through the published package (^3.0.0), whose export map exposes only `.` plus a few ./scoring/* and ./signals/* subpaths. Neither surfaces AUTONOMY_LEVELS, so importing the canonical list would mean widening the engine's public API -- a larger refactor than this fix. The comment now records that, and the source of truth. Since the copies stay hand-synced, a test pins the invariant instead: the list parsed from the committed CLI source must equal the live enum, so the two cannot drift again silently. Both new tests fail against the old list. Left MAINTAIN_ACTION_CLASSES alone: it reads stale next to the engine's AGENT_ACTION_CLASSES, but it is a deliberate operator-settable subset that src/mcp/server.ts's MAINTAIN_AUTONOMY_ACTION_CLASSES mirrors on purpose. Noted inline so the next reader doesn't "fix" it. Also refreshed server.ts's comment, which cited this list as the stale one. Closes JSONbored#6153
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6378 +/- ##
===========================================
+ Coverage 36.39% 95.60% +59.20%
===========================================
Files 599 599
Lines 47235 47235
Branches 15031 15031
===========================================
+ Hits 17192 45157 +27965
+ Misses 27412 1291 -26121
+ Partials 2631 787 -1844
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-16 05:27:03 UTC
Review summary Nits — 5 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk 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.
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.
|
Summary
loopover-mcp maintain set-levelclient-side-validated againstMAINTAIN_AUTONOMY_LEVELS, which still listed"suggest"/"propose".#4620removed both server-side, andPUT /settingsvalidates the body against the live enum (src/api/routes.ts->z.enum(["observe","auto_with_approval","auto"])), so the CLI waved through two values the API rejects — turning what should be an immediate, clear client-side error into a confusing 400.The same stale constant also fed
maintain --help, so the help text advertised both dead levels as valid input. Both call sites read the constant, so narrowing it fixes them together.The whole executable change is one line. Everything else is a test and comments.
Why a corrected literal, not an import
The issue asked me to consider importing the canonical list rather than keeping two hand-synced copies. I checked, and it isn't reachable from here:
bin/loopover-mcp.jsresolves@loopover/enginethrough the published package ("@loopover/engine": "^3.0.0").exportsmap exposes only.plus a few./scoring/*and./signals/*subpaths — there is no./settings/*entry, and the root entry doesn't exportAUTONOMY_LEVELS(it exportsTENANT_AUTONOMY_LEVELS, an unrelated dial).So importing it would mean widening the engine's public API — larger than this issue's scope, which is exactly the case the issue scoped out. I took the blessed fallback: corrected literal + a comment naming the source of truth and why the import isn't available.
Since the copies stay hand-synced, I pinned the invariant instead of trusting the comment: the list parsed out of the committed CLI source must equal the live
AUTONOMY_LEVELS. If either side moves again, the test fails immediately.Validation
npx vitest run test/unit/mcp-cli-maintain.test.ts— 10/10 pass.expected ['observe','suggest',...(3)] to deeply equal ['observe',...(2)], and the regression reportspromise resolved "'Set review autonomy to suggest for owner/repo'" instead of rejecting— i.e. the old CLI reported success for a value the real API 400s.maintain,basics,completion-spec,autonomy,autonomy-engine,automation-state,tool-categories) — 120/120 pass.npm run typecheck— 0 errors.npm run build:mcp— passes (syntax-checks the changed file).npm run docs:drift-check— ok.git diff --check— clean.main— no base conflict.The regression test proves the failure is client-side: the fixture's
PUT /settingsechoes any autonomy body back as a success, exactly like a server with no enum — so a rejection can only have come from the CLI's own check, before any round-trip.Coverage
No patch surface: coverage is collected over
src/**,packages/loopover-engine/src/**, andpackages/loopover-miner/lib/**. The one-line change is inpackages/loopover-mcp/**(not collected), thesrc/mcp/server.tsedit is comment-only, andtest/**is ignored.Scope note — what I deliberately did NOT change
MAINTAIN_ACTION_CLASSES(the line directly above) reads stale next to the engine'sAGENT_ACTION_CLASSES, which now carriesreview_state_label/update_branch/assign. That divergence is intentional: it's the operator-settable subset the maintain surface exposes, andsrc/mcp/server.ts'sMAINTAIN_AUTONOMY_ACTION_CLASSESmirrors those same six on purpose. I left it alone and said so inline, so the next reader doesn't "sync" it and widen the surface by accident.I also refreshed the comment in
src/mcp/server.tsthat explained its choice of the live enum by citing this list as "still carries suggest/propose" — true before this PR, stale after it.Scope
packages/,src/,test/).site/,CNAME, orlovablechanges; no generated artifact invalidated (command-referenceis generated fromsrc/github/commands.ts, not this CLI).Safety
set-level review observestill succeeds, so the fix narrowed the list without breaking it.Closes #6153