OPER-176
Add Task.risk_tier enum column for AI-triage auto-dispatch policy
Band
MEDIUM
Suggested
Justin Cooke
Body
feature_id: FEAT-studio-qa
## Context
PDT memo v5 ([REDACTED-DOB]) approved the AI-triage auto-dispatch policy for QA-reported bugs. The policy keys off the existing Build Risk Matrix (Sandbox / Scaffold / Safeguard / Stronghold). To make that policy machine-executable at ticket-creation time, Task needs a `risk_tier` enum column derived from the touched files' risk annotations + PHI floor check + severity check.
Without this column, the AI triage writer has nowhere to persist its risk classification, and downstream code (should_auto_dispatch decision, AiTriageClassPolicy lookup, AiTriageLog rows) has no join key. This is the schema foundation for the entire auto-dispatch flow.
## Acceptance Criteria
- Add enum `RiskTier { SANDBOX, SCAFFOLD, SAFEGUARD, STRONGHOLD }` in appropriate prisma schema file under `packages/database/prisma/schema/`.
- Add optional column `risk_tier RiskTier?` to Task model. Nullable because historical tickets pre-date the classifier.
- Migration file added under `packages/database/prisma/migrations/`, following the existing snake_case + @map() naming convention per OPERANT-BOILERPLATE.md.
- Backfill: NOT required in this ticket. Backfill script for historical tickets is a follow-up if/when we need to compute analytics over pre-existing tickets. Nullable column allows incremental population.
- Helper function `deriveRiskTier(evidenceTrace, suggestedPatchFilePaths, severity): RiskTier` in `packages/qa/src/risk-tier.ts` implementing the derivation logic:
- If severity is BLOCKER: return SAFEGUARD (BLOCKER goes to human via override, but tier itself is still classified for reporting).
- If any URL in evidence.trace.network matches `/api/phi/*` OR any file in suggestedPatchFilePaths is annotated `@risk-tier: stronghold`: return STRONGHOLD (PHI floor rule).
- Otherwise use `@risk-tier:` annotation on the touched files. Highest tier wins across the fileset.
- Default to SAFEGUARD if no annotations found (fail-safe: unknown code paths get failure-path-test discipline).
- Unit tests for deriveRiskTier covering all four tier outcomes + BLOCKER override + PHI floor + missing-annotation default. Failure-path tests first per Build Risk Matrix.
- AuditLog row on every risk_tier assignment: actor `system:qa-risk-tier-classifier`.
## Risk classification
Safeguard (Risk 7 / Reach 5). Schema change on Task is high-blast-radius because every downstream module reads Task rows. Failure-path tests before code + AuditLog per Build Risk Matrix.
## Depends on
OPER-175 (rerun watcher) — must land first because the auto-demote logic in the AI triage ticket depends on RERUN_PASS / RERUN_FAIL events being emitted by rerun.ts.
## Blocks
- AI triage writer + AiTriageClassPolicy + AiTriageLog + auto-demote/promote (next ticket)
- Playwright trace recorder (depends transitively — needs risk_tier to classify its output)Attachments
Loading attachments…
Comments
Loading comments…