OPER-123
[OPER-QA-3] TestFixtureRef writer with neverStoresPhi invariant
Band
MEDIUM
Suggested
Justin Cooke
Body
feature_id: FEAT-studio-qa
## Context
Ship `packages/qa/src/fixtures.ts` — the writer + reader for `TestFixtureRef` rows. Per the [REDACTED-DOB] QA-primitive PDT Marisol constraint: Studio stores POINTERS to fixtures, never PHI itself. Fixtures live in the product tenant (Portico's Neon); Studio's `TestFixtureRef` carries only the content-addressable hash + shape schema.
The `neverStoresPhi` column defaults to `true` and this writer enforces it — any attempted write with `neverStoresPhi: false` from a call site outside `packages/qa/src/regulated/` throws. This is the PHI-boundary contract the whole primitive depends on.
## Acceptance Criteria
- `packages/qa/src/fixtures.ts` exports `writeFixtureRef(input: FixtureRefInput): Promise<TestFixtureRef>` and `readFixtureRef(id: string, opts: { teamId: string })`
- Writer enforces `neverStoresPhi === true` unless caller path matches `packages/qa/src/regulated/` (checked via stack trace of the calling module in dev, and a `[BYPASS_KEY]` opt-in the regulated modules present)
- Content-addressable: `sha256(JSON.stringify(shape))` is the hash column; shape is a Zod schema serialization
- Reader resolves the pointer via the product's tenant adapter (Portico's `getFixtureByHash(hash)`) and never returns raw fixture bytes — only shape confirmation + resolution URL
- Vitest coverage: (a) non-PHI fixture writes; (b) PHI attempt from non-regulated caller throws; (c) regulated-caller bypass works; (d) hash collision returns existing row
- phi-guard scanner does not flag this module
Attachments
Loading attachments…
Comments
Loading comments…