test(review-residue): unit tests for the two runner paths — the PR-body SEQUANT_MUTATION merge and resolveReadFirstPR's state-record fallback with its open-PR guard
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 55/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- github, typescript
- Domain
- backend-api-design, testing
Research direction
Start with src/lib/workflow/review-residue.post.test.ts, then read the referenced paths in review-residue.post.ts and batch-executor.ts to see how the post body and state-record fallback are handled. Add tests for a PR-body SEQUANT_MUTATION marker and for open versus closed or merged state-record PRs; run the listed Vitest commands and npm run lint:health to confirm the cases pass.
Written by the indexing model from the issue text.
Description
Follow-up of #1520 (PR #1587); QA 3's two fix_now items.
Problem
Two runner-written paths in the Read-first post have no unit test. Both were exercised only by the testbed runs (ad-motion #290, #291) and by fake-provider cases that never reach them:
deliverReadFirstComment(src/lib/workflow/review-residue.post.ts:190) reads the PR body throughprovider.fetchIssue(String(prNumber))and merges itsSEQUANT_MUTATIONrecords with this run's exec output (mergeMarkers, :151). No fake PR body inreview-residue.post.test.tscarries a marker, so a regression that drops the PR-body source would rendermutation record: noneon every qa-only re-run and no test would notice.resolveReadFirstPR(src/lib/workflow/batch-executor.ts:3037) falls back to the state record's PR and posts only whenprovider.getPRStatussays it is open. The post tests passservices.stateManager: nulland a fake whosegetPRStatusalways answersopen, so neither the fallback nor the guard runs under test.
Acceptance Criteria
- AC-1: A qa-only run whose fake PR body carries a
SEQUANT_MUTATIONrecord rendersmutation record: AC-Nfor the named test file in the posted comment, with no exec output in the run. Evidence:npx vitest run src/lib/workflow/review-residue.post.test.ts -t "PR body"→≥ 1 passed, 0 failed(new case; today the filter matches 0 of 6 tests) - AC-1 is classified as a gate test by
isGateTestEvidence; the PR body carries itsSEQUANT_MUTATIONrecord (remove the PR-body source frommergeMarkers's inputs → the new case fails; restore). - AC-2: With no post-QA PR and no early PR, a run whose state record names an open PR posts on it, and a run whose state record names a closed or merged PR posts nothing. The case constructs a real
StateManageron a temp dir (or an in-memory one) with aprrecord and a fake whosegetPRStatusanswers each state. Evidence:npx vitest run src/lib/workflow/review-residue.post.test.ts -t "state record"→≥ 2 passed, 0 failed(new cases; today the filter matches 0 of 6 tests) - AC-2 is classified as a gate test by
isGateTestEvidence; the PR body carries itsSEQUANT_MUTATIONrecord (remove thestatus.state === "open"check inresolveReadFirstPR→ the closed-PR case fails; restore). - AC-3: The existing six cases still pass and no new test mocks
child_process. Evidence:npx vitest run src/lib/workflow/review-residue.post.test.ts→≥ 9 passed, 0 failedandnpm run lint:health→no metric rose above the baseline
May touch
src/lib/workflow/review-residue.post.test.ts (and a small fixture if the PR body is long). No production change is expected; if one is needed to make a seam testable, it stays in review-residue.post.ts or batch-executor.ts's resolveReadFirstPR.
Non-Goals
- Changing what the comment renders or where it posts (ADR-0021).
- 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
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from sequant-io/sequant
-
graph-2026-11-simplify
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
sequant-io/sequant#1650 ·
Maintainers usually reply within 1 day
-
run: --phases does not suppress the UI-label test phase (determinePhasesForIssue adds it to an explicit list)Possibly taken @admarble claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
sequant-io/sequant#1631 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
sequant-io/sequant#1601 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
sequant-io/sequant#1582 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 76/100
sequant-io/sequant#1381 ·
Maintainers usually reply within 1 day
All issues in sequant-io/sequant
Similar issues
-
content triage
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
tensorflow/tfjs#8754 ·
-
tool-submission
Difficulty 1/5 Under an hour Newbie friendliness 83/100
BraveOPotato/NoSignups#2348 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
code-yeongyu/oh-my-openagent#12784 ·
Maintainers usually reply within 1 day
-
external-issue to-triage
Difficulty 2/5 1-3 hours Newbie friendliness 71/100
Maintainers usually reply within 1 day