# Issue 5639 — read-only proof audit, pass 1

Scope: base `9bc0c33438` → head `853aceb5a1390badfe165d72266ce178bfee1886` in `/home/ubuntu/wt/issue-5639`. Diff inspected only; no worktree edits, forge reads, server/device activity, or test execution. Native build is ongoing according to the supplied context. This document is a proof plan, not a claim of verification.

## Behavior derived from the diff

The Expo plugin changes from setting Android `usesCleartextTraffic` alone to also referencing a generated `@xml/network_security_config`. Its base config trusts both `system` and `user` certificate stores and explicitly permits cleartext. The minimum proof therefore covers added user-CA trust, rejection without that trust, and retention of system-CA and cleartext behavior. Scope is Android native networking; no rendering changed. Use the actual Pixel 9 / API 36 fixture for all required runtime rows. No viewport/theme Cartesian product is justified.

## Required fixture matrix

Every row below involves interaction or connection timing and therefore requires a **screen recording**, not a screenshot alone. Recordings are pending; none were made or inspected in this pass.

| ID | Build / trust / transport fixture | Interaction and observable acceptance | Required proof | Status |
| --- | --- | --- | --- | --- |
| R0 | Base build; private server CA installed in Android user store; valid hostname and chain; HTTPS/WSS | On the same Pixel, Chrome successfully opens the HTTPS endpoint, then T3 attempts HTTPS discovery and shows the reported Transport error. Establish the original failure with the same endpoint used in R1. | **Recording:** Chrome success followed by T3 discovery failure; identify base build and device/API in sanitized evidence notes. Existing supplied observation is context, not an inspected recording. | Reported before state; capture pending |
| R1 | Head native build; same private CA installed; same endpoint; HTTPS/WSS | Discover environment over HTTPS; complete pairing through the normal flow; reach connected state; perform one harmless refresh/read that receives fresh server data over WSS. Disconnect and reconnect once to show the authenticated WSS connection remains usable. No Transport error or certificate bypass. | **Recording:** discovery → pairing completion → live data round trip → reconnect and fresh data. Sanitized transport evidence must establish HTTPS discovery/pairing and WSS traffic; a connected label alone does not prove WSS. | Pending native build and runtime proof |
| R2 | Head native build; same private CA absent from user and system stores; same otherwise-valid HTTPS/WSS endpoint | Start a fresh app process with clean pairing state and attempt HTTPS discovery: reject the untrusted chain and do not connect. If a direct/manual pairing route can bypass discovery, attempt it too and show rejection. For WSS, use retained pairing in isolated fixture state from R1, remove the CA, restart the app to eliminate live sockets/session reuse, and attempt reconnect: it must fail to establish WSS. | **Recording:** absent-CA fixture identity → discovery rejection → direct pairing rejection if reachable → retained-pairing WSS reconnect rejection. Pair with sanitized certificate/transport failure evidence to distinguish trust rejection from an unreachable server. Use the same reachable endpoint as R1. | Pending; direct pairing route applicability to be determined during capture |
| R3 | Head native build; publicly/system-trusted valid server chain, with no private user CA installed; HTTPS/WSS | Discover, pair, reach connected state, and receive fresh server data over WSS. This guards retention of the explicit `system` anchor independently of the user store. | **Recording:** HTTPS discovery → pairing → fresh WSS data. Sanitized transport evidence identifies the transport and system-trusted fixture. | Pending |
| R4 | Head native build; isolated reachable local server; HTTP/WS | Discover over HTTP, pair through the supported cleartext flow, reach connected state, and receive fresh data over WS. This guards the old cleartext behavior now controlled by the XML base config. | **Recording:** HTTP discovery → pairing → fresh WS data; sanitized transport evidence identifies HTTP/WS. | Pending |

R1, R3, and R4 can each cover discovery, pairing, and socket traffic in one recording; separate recordings per step are unnecessary. R2 may use separate clips for its fresh-state and retained-pairing fixtures. No fixed sleep duration or latency threshold is part of acceptance: wait for an explicit success/failure outcome, and retain enough recording to make it legible. An indefinite spinner or ambiguous network error without transport evidence is inconclusive.

## Native artifact gate and evidence hygiene

Before crediting head results, identify the installed native artifact as the head build; a JavaScript reload cannot install this native configuration. Retain sanitized inspection evidence that the built/merged manifest references `@xml/network_security_config` and that the packaged XML contains `system`, `user`, and `cleartextTrafficPermitted="true"`. This is an artifact check, not an interaction/time row, so text evidence suffices. It complements runtime proof; it cannot replace it.

Use dedicated fixture state and innocuous server data. Do not publish CA private keys, credentials, pairing URLs/tokens/QR codes, cookies, authorization headers, or private customer data. Redact pairing secrets in recordings while keeping the pairing interaction and outcome visible. Share only sanitized transport metadata, such as scheme, operation, outcome, and certificate trust category. This uploaded matrix contains no credentials or actual endpoint addresses.

## Necessary proof versus hardening

**Necessary:** artifact gate and R0–R4. R0 provides before evidence for the reported regression; R1 demonstrates the fix across HTTPS and WSS; R2 proves uninstalled private roots remain untrusted; R3 and R4 guard the two explicitly retained policies. Do not interpret “no user CA rejection” as rejection of system-trusted certificates: R2 uses the private chain without its root, while R3 must succeed.

**Optional hardening:** hostname mismatch, expired certificate, incomplete chain, unrelated installed user CA, multiple user roots, another supported Android API/device, and an additional release artifact if the required capture used a debug build. These can expose broader certificate or build-variant issues but are not required to prove this narrow diff. If another plugin/build variant overrides the packaged policy, promote that variant check to required. iOS and visual viewport/theme permutations are outside this Android-only change.

No meaningful existing Vitest fixture exercises Android OS trust. A mock fetch or XML string assertion would not prove the native fix. Selected proof is the packaged artifact inspection plus native runtime captures above; no new unit test is requested by this audit.

## FRICTION

- Native build still ongoing; no head artifact or runtime outcome verified in this pass.
- Supplied Chrome-success/T3-Transport-error baseline has not been inspected as a recording.
- Negative trust proof needs both clean pairing state and retained pairing with a fresh process; otherwise cached connections can create a false pass.
- UI success alone cannot establish WSS or explain a generic Transport error; sanitized transport evidence is needed.
- Discovery/pairing route availability and a harmless operation that demonstrably traverses WSS must be identified during authorized capture.
- Device/server/browser use was explicitly excluded, so all runtime rows remain pending. No blockers were bypassed and no additional access was requested.
