# Canonical claims list

This file is the single source of truth for what Withheld attests to. Every
claim has (1) a plain-language statement, (2) the metric definition with
the exact SQL we use, and (3) the threshold for a "pass" disposition.

The live numbers backing each claim are served at
[/api/public/audit-metrics.json](/api/public/audit-metrics.json), updated
hourly and cached on the edge.

---

## 1. Submission completeness

**Claim:** Within 14 calendar days of a subscriber signing the mandate, we
submit at least one removal request to every applicable broker in their
jurisdiction.

**Metric:**

```sql
-- For each profile P provisioned for >= 14 days:
--   applicable = brokers where any jurisdiction intersects P.jurisdictions
--   submitted  = optout_requests where profile_id = P AND status != 'queued'
-- Pass = submitted / applicable >= 0.95 averaged across all profiles.
select
  avg(submitted::float / nullif(applicable, 0)) as completeness
from (
  select
    p.id,
    (select count(*) from brokers b
       where b.is_active and b.jurisdictions && p.jurisdictions) as applicable,
    (select count(*) from optout_requests r
       where r.profile_id = p.id and r.status <> 'queued') as submitted
  from profiles p
  where p.requests_enabled
    and p.created_at < now() - interval '14 days'
) t
where applicable > 0;
```

**Pass threshold:** mean completeness >= 95 %.

---

## 2. Verified removal rate

**Claim:** Of brokers that returned a definitive disposition (confirmed
removal OR rejected the request), the percentage that confirmed removal.

**Metric:** the `public.broker_success_rates` view aggregates the last
180 days per broker; the audit-metrics endpoint exposes the overall
ratio across all brokers.

```sql
select
  round(100.0 * count(*) filter (where status in ('confirmed','verified_removed'))
        / nullif(count(*) filter (where status in ('confirmed','verified_removed','rejected')), 0)) as success_pct
from optout_requests
where created_at > now() - interval '180 days';
```

**Pass threshold:** >= 75 %. (We do not over-promise — broker non-compliance is
real and varies by jurisdiction.) **Suppressed below n=50 decisive attempts.**

---

## 3. Evidence retention

**Claim:** Every state transition writes an immutable `request_events` row.
Inbound broker replies and submission screenshots are stored in a private
bucket and retrievable on demand for the life of the customer relationship.

**Metric (random sample test):** 30 request_ids drawn uniformly at random
from `optout_requests` where `status = verified_removed`. For each:

- the `request_events` log must contain at least one row of every status
  it transitioned through, AND
- if any `evidence` row points at storage, the auditor must be able to
  download the artefact via signed URL.

**Pass threshold:** 30/30 samples retrievable.

---

## 4. PII handling

**Claim:** Customer PII is processed only to submit and verify opt-outs.
We never sell, rent, lease, or share it with third parties. Dates of
birth are encrypted at rest.

**Verification:**

- Code review of every place `profiles.date_of_birth_encrypted` is read
  (auditor walks the codebase; the path uses `encryptPII` / `decryptPII`
  exclusively).
- Review of the data-processing addendum + sub-processor list.
- Database column inspection: `pg_dump` of a profiles row shows the DOB
  field is an opaque ciphertext, not a date.

**Pass threshold:** all three reviews satisfied; no instance of PII being
written to a third-party API outside the per-broker opt-out submission path.

---

## 5. Pause / cancel respected

**Claim:** When a subscriber pauses or cancels their subscription, the
provisioning and recheck workers stop creating new requests against their
profiles within one tick (max 5 minutes).

**Metric:**

```sql
-- Any optout_requests row created AFTER the subscription was paused
-- is a violation. Pass = zero violations.
select count(*) as violations
from optout_requests r
join profiles p on p.id = r.profile_id
join subscriptions s on s.user_id = p.user_id
where s.paused_at is not null
  and r.created_at > s.paused_at + interval '5 minutes';
```

**Pass threshold:** violations = 0.
