Operant Studio
OPER-65

Fix 12 pre-existing flaky tests: dispatcher-blocked-by, dispatcher-claim-dispatch, workflow-reaper

Suggested
Justin Cooke

Body

feature_id: FEAT-studio-dispatcher

## Context

Three test files under `apps/web/src/lib/` have been failing on `main` for the entire OPER-60 rebase window (verified at `origin/main` HEAD `9f52fff` before the OPER-60 merge and again at the post-merge head):

- `src/lib/dispatcher-blocked-by.test.ts` — 2 failures under "POR-478 B1 — claim() is the authoritative promotion gate"
- `src/lib/dispatcher-claim-dispatch.test.ts` — 8 failures under "OPER-6 — claim() fires workflow_dispatch" and "OPER-11A — claim() ensures the agent branch exists"
- `src/lib/workflow-reaper.test.ts` — 2 failures under "OPER-14A reapCompletedWorkflows — acceptance branches"

Total: 12 tests / 3 files failing pre-existing on `main`, 659/671 passing in the rest of `apps/web`. Root cause on inspection: fake `db` shapes in these tests are missing tables the runtime code now touches. `workflow-reaper.test.ts` fails with `TypeError: db.dispatchAudit.findMany is not a function` — the reaper started calling `dispatchAudit.findMany` (see `packages/dispatcher/src/workflow-reaper.ts:285` in `countConsecutiveSuccessNoPrAudits`) but the test's fake scoped db was never updated. `dispatcher-blocked-by.test.ts` and `dispatcher-claim-dispatch.test.ts` fail with `TypeError` in the same shape, most likely on `packages/dispatcher/src/backend.ts:777` (branch-check retry path). These are drift bugs, not new regressions from OPER-60.

The failures were called out during the OPER-60 rebase verification but explicitly not fixed inside PR #177 to keep that PR scoped to admission gate + rebase. This ticket is the follow-up.

## Scope

1. Diagnose each failure by comparing the runtime code path to the fake `db` shape in the affected test's `makeDb` / test setup. The three files likely share the same "add missing table stubs to the fake" pattern.
2. Add the missing stubs (`dispatchAudit.findMany` at minimum for the reaper file; enumerate the rest during the diagnosis). Use `vi.fn(async () => [])` as the safe default when the return type is `T[]` and the test does not care about the value.
3. Do NOT introduce a real DB in these tests. That is a separate ticket (see OPER-66). Stay in fake-scoped-db territory to keep the file's runtime under 30ms per suite.
4. Verify: `pnpm --filter web vitest run src/lib/dispatcher-blocked-by.test.ts src/lib/dispatcher-claim-dispatch.test.ts src/lib/workflow-reaper.test.ts` returns 12/12 previously-failing tests passing, 0 new failures elsewhere.

## Acceptance Criteria

- All 12 previously-failing tests in the three named files pass locally.
- Full `apps/web` vitest run reports 671/671 passing.
- No new dependencies added; only fake-db shape updates.
- The added stubs are commented with a one-line pointer to the runtime line that reads them, so the next drift is easier to catch.
- No changes to the runtime code under `packages/dispatcher/src/` or `apps/web/src/lib/dispatcher-*`, `workflow-reaper*` — this ticket is test-fixture-only.

## Non-goals

- Adding a real-DB integration test for the dispatcher path (OPER-66).
- Rewriting the branch-check retry pattern surfaced by OPER-11A. If the retry pattern is buggy, that is a separate ticket.
- Touching the `apps/web/src/lib/plan-*` files. They passed in the OPER-60 rebase and are out of scope.

## Verification

`pnpm --filter web vitest run`

Attachments

Loading attachments…

Comments

Loading comments…