# notification — VALIDATION RESULTS

## Signal hypothesis

Real users who have been prompted at any site have permission state
"granted" or "denied". Stealth frameworks spawning new contexts always
return "default". First-visit users have "default" normally.

## 3-condition results

| Condition | permission | verdict |
|---|---|---|
| Vanilla headless | **denied** | ✅ Real user |
| CDP-attached | default | 🟡 Fresh context |
| Headful (Xvfb) | default | 🟡 Fresh context |

**Inverted from theory**: vanilla headless returns "denied", CDP+headful
return "default". This is likely because:
- Vanilla Playwright uses `--user-data-dir` that has previously denied
  notifications on this server
- CDP/headful use fresh user data dirs → "default"

## Verdict: ❌ REJECTED — state-dependent, not a discriminator

The signal depends entirely on:
1. Has the user/framework been prompted before?
2. What was their response?
3. Was the user data dir cleared between runs?

None of these are headless-vs-headful discriminators. They're context
state. A new Chrome install = "default". A long-time Chrome user =
"granted" or "denied".

**False positive risk:** Catastrophic. Every new Chrome install would be
flagged as suspicious. Returning users with "default" permission would
be flagged.

## Recommendation

DO NOT SHIP. This is not a signal — it's state that varies independently
of automation status.

## Phase 3 consideration

This was originally planned as a Phase 3 signal (needs visit history).
But even with visit history, the signal is too state-dependent to be
useful. Skip.

## Files

- `demo.html`
