fix(miner): honor --json on governor pause/resume/status error paths (#5914) - #6034
Conversation
|
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 #6034 +/- ##
===========================================
+ Coverage 78.84% 95.16% +16.31%
===========================================
Files 592 592
Lines 46949 46945 -4
Branches 15003 15003
===========================================
+ Hits 37019 44675 +7656
+ Misses 7754 1512 -6242
+ Partials 2176 758 -1418
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-15 07:23:08 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 4 non-blocking
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://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.
|
Summary
governor-pause-cli.jswas the last CLI module inpackages/loopover-miner/lib/that never adopted the sharedcli-error.jsfailure contract:runGovernorPause,runGovernorResume, andrunGovernorStatuseach handled their parse-error and catch-error paths with a rawconsole.error(...); return 2;. Soloopover-miner governor pause|resume|status --jsonprinted plain text to stderr on any error path instead of the documented{ok:false,error}envelope on stdout, breaking scripted/MCP consumers that always pass--jsonand expect JSON regardless of outcome.reportCliFailure(...), matching the reference implementation inclaim-ledger-cli.js:222,253and the same shape already used byplan-store-cli.js,run-state-cli.js,event-ledger-cli.js,portfolio-queue-cli.js, and 10 other sibling modules.argsWantJson(args)(raw argv) and catch paths passparsed.json, exactly as the siblings do. This distinction is load-bearing, not an inconsistency: a parse failure returns{error}with no.jsonfield, and a token can abort the parse before--jsonis ever read —loopover-miner governor resume extra --jsonis a real case, and it has a dedicated test.--jsoninvocations is unchanged: plain text to stderr, exit code 2.reportCliFailure's defaultexitCodeis already 2, so every path returns the same code it did before.Closes #5914
Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #123) — a linked open issue is required for every contributor PR.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragenpm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateIf any required check was skipped, explain why:
lib/*.jsmodule and its unit test; the unrun checks cover surfaces this diff does not touch — no workflow files (actionlint), no worker/MCP/OpenAPI/UI files (test:workers,build:mcp,test:mcp-pack,ui:*), no migrations, schema,wrangler.jsoncbindings, orenv.*reads (so nocf-typegen/ env-reference regeneration is owed). CI runs all of them regardless.test:coverage: I ran the changed file's coverage scoped rather than the full unsharded suite. Result onpackages/loopover-miner/lib/governor-pause-cli.js: 100% statements (93/93), 100% branches (53/53), 100% lines — the whole file, so every changed line and branch is covered by construction. The 4 changed statements themselves introduce no new conditionals.typecheck:tsc --noEmitexits 0 on the full workspace.governor-pause-cli.jstomainand re-running the new#5914block fails 6 of 7 tests withSyntaxError: "undefined" is not valid JSON(nothing reaches stdout, because the old code wrote to stderr). The 7th (keeps non-JSON error paths on stderr as plain text) passes both before and after by design — it is the behavior-preservation test pinning the unchanged non---jsoncontract.runGovernorPause/runGovernorResume/runGovernorStatushave exactly one non-test consumer —governor-ledger-cli.js:150-152, which dispatchesgovernor pause|resume|status. Its suite (test/unit/miner-governor-ledger-cli.test.ts) passes unchanged.apps/loopover-miner-ui/vite-governor-api.tsonly references the module in a comment and reads governor-state directly; nothing shells out to this CLI to parse its output.node --checkpasses (whatbuild:minerdoes).Safety
UI Evidencesection 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.The four unchecked Safety boxes are not applicable to this diff, so they are left unchecked rather than checked as a formality: it touches no auth/cookie/CORS/App/Cloudflare/session surface, no API/OpenAPI/MCP behavior, and no UI — so there is no
UI Evidenceto attach. The--jsonerror envelope is an existing documented contract this module was not honoring; no public doc changes, and no changelog edit (not a release-prep PR).Notes
--jsonruns.describeCliErrorreproduces the previouserror instanceof Error ? error.message : String(error)normalization exactly, so the non-Error throw path keeps stringifying identically (still covered by the pre-existing tests atminer-governor-pause-cli.test.ts).if ("error" in parsed) return reportCliFailure(argsWantJson(args), parsed.error);into a local helper: all 15 sibling CLI modules inline this exact pattern, and matching the established convention keepsgovernor-pause-cli.jsdiffable against its siblings. For the same reason I did not add an inline comment explainingargsWantJson(args)vsparsed.json— that rationale is documented once at the definition site (cli-error.js:19) and no sibling repeats it; this PR's Summary records the reasoning instead.