bug(mcp): a sequant_run whose issues were all skipped by the state guard reports status success and passed: N — a skip is not a pass

Open
#1,595 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
api, backend, testing

Research direction

Start with src/mcp/tools/run.ts and its tests, then read the two skip sites in src/lib/workflow/run-orchestrator.ts and the orchestrator tests. Trace how phase events and fallback responses are handled, and run the named Vitest commands. Done means skipped issues are reported with their reasons and status: "skipped", while mixed runs retain parsed results and existing MCP tests pass.

Written by the indexing model from the issue text.

Description

bug

Found while closing #1520 (PR #1587); filed with the owner's word 2026-10-26.

Problem

A sequant_run MCP call whose only issue was skipped by the state guard reports a pass. Observed 2026-10-26: #1520 was at ready_for_merge in .sequant/state.json; sequant_run({ issues: [1520], phases: "qa" }) returned

{"status":"success","issues":[],"summary":{"total":1,"passed":1,"failed":0,"partial":0,"durationSeconds":0},
 "rawOutput":"... !  #1520: already ready_for_merge — skipping (use --force to re-run)\n\n  All issues already completed. Use --force to re-run.\n",
 "runLogMissing":true,"requestedIssues":[1520],"note":"Run log not found ... The summary counts only reflect the exit code."}

The CLI exits 0 when every issue is skipped (src/lib/workflow/run-orchestrator.ts:1010 and :1141 print the skip; :1030 prints "All issues already completed"), and no run log is written. buildFallbackResponse (src/mcp/tools/run.ts:434) then derives the summary from the exit code: passed: overallStatus === "success" ? issueNumbers.length : 0 (:451). So "nothing ran" and "everything passed" are the same JSON to an MCP caller, apart from a note string and an empty issues array. The note says the counts reflect the exit code, which is true and is the problem: a skip is not a pass.

Acceptance Criteria

  • AC-1: When the CLI skipped every requested issue, the result's status is "skipped" (a new value beside success/failure), summary.passed is 0, and each requested issue appears in issues[] with status: "skipped" and the guard's reason (already ready_for_merge). Evidence: npx vitest run src/mcp/tools/run.test.ts -t "skipped" → ≥ 2 passed, 0 failed (new cases: all skipped; some skipped and the rest ran; today the filter matches 0 of 101 tests)
  • AC-1 is classified as a gate test by isGateTestEvidence; the PR body carries its SEQUANT_MUTATION record (make the fallback count a skipped issue as passed again → the all-skipped case fails; restore).
  • AC-2: The detection is structured, not a regex over rawOutput: the CLI emits one SEQUANT_PROGRESS line per skipped issue (event: "skipped", with reason), and the MCP tool reads it the way it reads phase events. Evidence: grep -c '"skipped"' src/lib/workflow/run-orchestrator.ts → ≥ 1 (today 0 as an event name) and npx vitest run src/lib/workflow/run-orchestrator.test.ts -t "skipped" → ≥ 1 passed, 0 failed
  • AC-3: A run where some issues ran and one was skipped keeps its parsed run log for the issues that ran and lists the skipped one as above; summary.total still equals the requested count. Evidence: covered by AC-1's second case
  • AC-4: The tool's note and description tell the caller that force: true re-runs a skipped issue. Evidence: grep -c 'force' src/mcp/tools/run.ts → rises by ≥ 1 from today's count, recorded in the PR body
  • AC-5: Existing MCP run tests pass. Evidence: npx vitest run src/mcp/ → 0 failed

May touch

src/mcp/tools/run.ts, src/mcp/tools/run.test.ts, src/lib/workflow/run-orchestrator.ts (the two skip sites, one progress line each), its test, docs/features/mcp-server.md, CHANGELOG.

Non-Goals

  • Changing the state guard itself (#592 tracks stale in_progress entries; --force stays the override).
  • Any change to sequant_status.
  • No edits under plugin/, .claude/skills/, templates/skills/ (plugin freeze).
Dominant language
TypeScript
Stars
1
Forks
1
Avg merge
11h 3m
Merged PRs (30d)
84

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from sequant-io/sequant

All issues in sequant-io/sequant

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.