Closes the six remediation items from the 2026-07-29 iOS completion audit plus the
whole P2 wave and Android access-token parity.
The audit's headline was that the client was code-complete but stuck at the device
door: no DEVELOPMENT_TEAM, no entitlements, so it had never run on real hardware
once, and it had fallen two months behind the server (Android had the git panel,
iOS had none) while neither native client could connect at all once WEBTERM_TOKEN
was set.
Package tests 310 -> 452, app bundle 296 -> 550 (iPhone and iPad, zero known
issues), integration 10 -> 32, Android 687 -> 691. ClientTLS went 55.76% -> 89.49%
and is now actually in the coverage gate, which it never was. Device build now
succeeds on the free personal team.
src/ and public/ are untouched — the git-panel endpoints already existed
server-side; iOS simply never consumed them.
# Conflicts:
# android/.gitignore
# android/README.md
# android/api-client/src/main/kotlin/wang/yaojia/webterm/api/routes/Endpoints.kt
# android/app/src/main/java/wang/yaojia/webterm/screens/PairingScreen.kt
# android/app/src/main/java/wang/yaojia/webterm/viewmodels/PairingViewModel.kt
# android/app/src/main/java/wang/yaojia/webterm/wiring/AppEnvironment.kt
# android/transport-okhttp/src/main/kotlin/wang/yaojia/webterm/transport/OkHttpClientFactory.kt
# docs/PROGRESS_LOG.md
- T-iOS-34's stated acceptance is "最大字号不破版" and it was failing: the key bar
froze its height at 52pt while an AX5 keycap needs 108.24pt, so caps clipped —
recorded as a withKnownIssue rather than fixed. Height now derives from the
content size category (and tracks live changes via registerForTraitChanges);
the known-issue marker is gone, replaced by positive assertions including a
12-category no-clip sweep and a guard that stays red if anyone writes the
constant back. Honest tradeoff: the keycap font is clamped at .accessibility2,
the same policy the design system already applies to dense content, because an
unclamped AX5 bar would eat the terminal. A test pins the clamp so the two
cannot drift.
- Thumbnails silently 401'd on a token-gated host: the pipeline built its own
transport with no token source, and by design never throws, so every preview
degraded to a placeholder with no signal. Assembled from AppEnvironment now.
- Android had zero CI while the token wave shipped 24 files of secret-handling
code. The instrumented leg is workflow_dispatch-only and says why in the file:
no one has ever seen it green on a runner, and a required leg nobody trusts
just produces a false green.
- Android persisted a validated token before the host probe succeeded, stranding
a secret for a host that never paired.
App bundle 534 -> 550 on both simulators, zero known issues. Android 687 -> 691.