# v0.0.25 Phase 3 Verification

Date: 2026-05-17

## Full Test Suite

```
go test -tags tls -race -count=1 ./...
```

| Package | Result |
|---|---|
| foxhound | PASS |
| behavior | PASS |
| benchmarks | PASS |
| cache | PASS |
| captcha | PASS |
| cmd/foxhound | PASS |
| engine | PASS |
| fetch | PASS |
| fetch/presets | PASS |
| identity | PASS |
| middleware | PASS |
| monitor | PASS |
| parse | PASS |
| pipeline | PASS |
| pipeline/export | PASS |
| proxy | PASS |
| proxy/providers | PASS |
| queue | PASS |
| tests | PASS |

**19/19 packages green. 0 failures. Race detector clean.**

---

## Acceptance Tests (Fix-specific)

### Fix 1: WebRTC mDNS obfuscation

| Test | Result |
|---|---|
| `TestBuildCamoufoxConfig_WebRTCMDNSPref` | PASS |

`BuildCamoufoxConfig()` emits `"media.peerconnection.ice.obfuscate_host_addresses": true`. Baseline (before): key absent from config map. After: key present and value is `true`.

### Fix 2: Locale policy decoupling

| Test | Result |
|---|---|
| `TestLocalePolicy_EnglishDefault_WithCountryRU` | PASS (30 iterations) |
| `TestLocalePolicy_EnglishDefault_NoGeoConstraint` | PASS |
| `TestLocalePolicy_ExplicitLocaleWins` | PASS |
| `TestLocalePolicy_ProxyGeo_DefaultPreserved` | PASS |

`WithLocalePolicy(LocalePolicyEnglishDefault)` + `WithCountry("RU")` yields `Locale=en-US` with `Europe/Moscow` timezone. `WithLocale("ja-JP")` still wins over any policy. Default `LocalePolicyProxyGeo` continues to produce geo-matched locale. All 4 cases verified.

### Fix 3: PerimeterX detection + press-hold solver

| Test | Result |
|---|---|
| `TestDetectPerimeterX_PxCaptchaElement` | PASS |
| `TestDetectPerimeterX_PressAndHoldText` | PASS |
| `TestDetectPerimeterX_NegativeCase` | PASS |
| `TestPressHoldDuration` | PASS (10 000 samples in [0.8s, 4.0s]) |
| `TestPressHoldDuration_Distribution` | PASS (mean in [1.0s, 2.0s]) |
| `TestPressHoldApproach` | PASS |
| `TestPressHoldApproach_ZeroLength` | PASS |

`CaptchaPerimeterX` detection fires on `px-captcha` DOM element and "press and hold" + "human" text pattern. Weibull-sampled hold duration is clamped correctly. Bézier approach trajectory is non-empty and terminates near target. NopeCHA path completely untouched.

---

## Guardrails Verified

- No competitor names in any project file (CHANGELOG, README, CLAUDE.md)
- NopeCHA files unmodified (captcha/nopecha/, captcha/nopecha.go)
- `behavior/press_hold.go` has no `playwright` import — buildable without build tag
- `captcha/press_hold_solver.go` correctly gated `//go:build playwright`
- `.dev-squad/audit-*` and `.dev-squad/camoufox-alignment-*` untouched
- `.dev-squad/cloakbrowser-audit/.gitignore` in place — screenshots/results not staged

## Decision

All acceptance criteria met. Phase 4 release proceeds.
