OPER-175
[OPER-QA-5] QA re-run loop (rerun.ts watcher)
Suggested
Justin Cooke
Body
feature_id: FEAT-studio-qa ## Context The QA primitive is live (OPER-100 landed [REDACTED-DOB]): TestCase / TestRun / TestBugLink / CoverageCell + OPER-129 Ledger Task writer for RUN_TEST assignments. What's missing is the loop-closer: when an auto-dispatched fix ticket completes (Task.status -> DONE), a new TestRun for the covered TestCase should fire automatically so the Coverage Grid's green cells always reflect verification the current head passed, not a stale run against pre-fix code. Without this loop, every AI-triage auto-dispatch policy is speculative — there's no signal to feed rolling-window auto-demote (3 consecutive rerun failures = demote). The re-run watcher is the primary evidence source for that logic and for Shankar's calibration review of demoted classes at /qa/triage-log. Plan document already authored at packages/qa/OPER-125-rerun-plan.md. Risk classified Safeguard (Risk 7 / Reach 4): autonomous POSTs to Ledger + test-run dispatch. Silently wrong means duplicate-ticket storm in the dispatch queue or a bug that never re-runs, making the Coverage Grid assert green coverage nothing re-verified. ## Acceptance Criteria - New module `packages/qa/src/rerun.ts` implements the watcher: subscribes to Task status transitions, for Task.status = DONE where Task has a TestBugLink -> TestCase relation, opens a new TestRun for that TestCase. - Failure-path tests written BEFORE implementation code, per Build Risk Matrix Safeguard tier discipline. Minimum 16 test cases in `packages/qa/src/rerun.test.ts` covering: duplicate suppression (same Task DONE fires twice), race between watcher and manual re-run, deleted TestCase, orphaned TestBugLink, TestCase whose CoverageCell is disabled, missing agentWorkerId, project without members, and the 9 happy-path variants across TestKind values. - AuditLog row on every state change: rerun_scheduled, rerun_skipped_duplicate, rerun_skipped_deleted_case, rerun_failed_dispatch. Actor stamp `system:qa-rerun`. - Drop the OPER-QA-0 `openBugForFailedRun` placeholder in `packages/qa/src/index.ts` — that scaffolding is superseded by this loop. - README update in `packages/qa/README.md` documenting the loop + closed harm_class vocabulary. - No schema change, no migration. - No PHI in scope: Studio stores pointers, ticket body carries ids and enum names only. ## Risk classification Safeguard (Risk 7 / Reach 4). Failure-path tests before code + AuditLog on every state change, per the Build Risk Matrix. ## Depends on None — this is the load-bearing loop-closer that unblocks everything downstream (Task.risk_tier schema, AI triage, trace recorder). ## Blocks - Task.risk_tier schema extension (next ticket) - AI triage writer + AiTriageClassPolicy + AiTriageLog + auto-demote/promote - Playwright trace recorder - /qa/triage-log and /qa/live-fixes canvases
Attachments
Loading attachments…
Comments
Loading comments…