# C49 fixture matrix

_Source: `system/caliber/lib/__fixtures__/c49/`. These are the red/green fixtures that prove the
scanner discriminates the four cases. Synthetic SQL — no secrets or customer data._

| Category | Fixture | Rule exercised | Expected |
| --- | --- | --- | --- |
| **Allowed** | `pass/01-write-time-scrub.sql` | write-time `scrub_pii_jsonb` before hash | PASS |
| **Allowed** | `pass/02-allowed-redaction.sql` | non-payload UPDATE **with** `-- caliber-allow: audit-redaction` annotation | PASS |
| **Forbidden** | `fail/01-payload-update.sql` | `UPDATE audit_events SET <payload column>` (Rule 1) | FAIL |
| **Forbidden** | `fail/02-nonpayload-no-annotation.sql` | non-payload UPDATE **without** annotation (Rule 2) | FAIL |
| **Forbidden** | `fail/03-delete.sql` | `DELETE FROM audit_events` (Rule 3) | FAIL |
| **Warned** | `warn/01-add-column.sql` | `ALTER TABLE audit_events ADD COLUMN` (Rule 4) | WARN |
| **Grandfathered** | `grandfather/20260507c_label_scrub.sql` | the incident migration — two non-payload label UPDATEs | INFO (downgraded) |

The grandfather fixture reproduces the incident migration's two statements exactly:

```sql
-- reproduced from the grandfathered CrewOS 20260507c migration (sandbox-only rows)
UPDATE audit_events SET entity_label_snapshot = 'redacted';
UPDATE audit_events SET actor_label = 'redacted';
```

Both target non-payload columns; under the standard they are a forbidden shape going forward, and the
scanner downgrades this specific named file to INFO so the historical migration does not fail a graded
project while every new occurrence of the shape fails.
