Operant Studio
OPER-202

HV-1: Schema migration -- TestRun columns + HumanVerification + FeatureConfidenceRollup

Suggested
Justin Cooke

Body

---
feature_id: FEAT-studio-qa
size: M
module: qa
phi_in_scope: true
has_migration: true
write_sets:
  - packages/database/prisma/schema/qa.prisma
  - packages/database/prisma/schema/migrations
  - apps/web/src/lib/phi-redactor.ts
  - packages/audit/src
---

## Context

Parent: OPER-196.

Roll-forward-only additive migration in `packages/database/prisma/schema/qa.prisma`. Adds three columns to `TestRun`, one new `HumanVerification` model, one new `FeatureConfidenceRollup` model.

`HumanVerification.probeText` is PHI-adjacent. The Marisol conditional sign-off from the PDT memo requires `/// @PHI` annotation on the column + `redactPhi()` at the write path + `AuditLog READ_PHI` at every read path, all landing in the same PR. Missing any of the three flips the sign-off to a full veto.

Reuse the `PhiHarmScan.humanVerdict/By/At` all-set-or-all-null CHECK-constrained trio pattern (`phi-guard.prisma:41-48`) for the `verifierId/verifiedAt` pair on `HumanVerification`.

`FeatureConfidenceRollup` mirrors the `CoverageCell` shape (`qa.prisma:139`): unique on (`teamId`, `projectId`, `featureId`, `buildSha`), indexed on (`teamId`, `projectId`, `status`).

## Acceptance Criteria

- `TestRun` gains: `humanVerificationRequired: Boolean @default(false)`, `humanVerificationCompletedAt: DateTime?`, `experienceScoreMedian: HumanExperienceScore?`
- New `HumanVerification` model with `id`, `testRunId`, `verifierId`, `verifiedAt`, `experienceScoreExpected: HumanExperienceScore`, `experienceScoreTimeSaving: HumanExperienceScore`, `correctnessVerdict: HumanCorrectnessVerdict`, `probeText: String? /// @PHI`, `responsePayload: Json`, CHECK constraint that verifierId/verifiedAt are both null or both set
- New `FeatureConfidenceRollup` model shaped like `CoverageCell`
- New enums: `HumanExperienceScore { BROKEN, MEH, GOOD, DELIGHTFUL }`, `HumanCorrectnessVerdict { CORRECT, WORKS_BUT_WRONG, BROKEN }`
- `redactPhi()` runs on `probeText` at the write endpoint
- `AuditLog` row written with `action: READ_PHI` at every read path of `probeText`
- Migration is roll-forward-only
- schema-guard, phi-auditor, migration-safety subagents all green

---
<!-- planner-rescope: phi_no_reviewer -->
**Planner rescope (phi_no_reviewer):** Task has phiInScope=true but no PHI-eligible reviewer is available. Register a reviewer worker advertising the `phi` capability before admitting PHI work.

Attachments

Loading attachments…

Comments

Loading comments…