fix(ios,android): close the acceptance gaps the review found, add Android CI
- 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.
This commit is contained in:
@@ -540,10 +540,10 @@ W5 验收(report-only, 并行)
|
||||
| T-iOS-13 SessionList | `[x]` | `Screens/SessionListScreen.swift`、`Components/TelemetryChips.swift`、`ViewModels/SessionListViewModel.swift` + Tests |
|
||||
| T-iOS-14 Gate/Digest UI | `[x]` | `Components/{GateBanner,PlanGateSheet,AwayDigestView}.swift`、`ViewModels/GateViewModel.swift` + `GateViewModelTests` |
|
||||
| T-iOS-15 App 接线+生命周期 | `[x]` | `Wiring/{RootView,AppCoordinator,PrivacyShade,ColdStartPolicy,TerminalContainerView}.swift` + `PrivacyShadeTests`/`ColdStartPolicyTests` |
|
||||
| T-iOS-16 集成 CI | `[x]` | `IntegrationTests/**` **10** `@Test` + `scripts/coverage-gate.sh` + `ios.yml` 六个 job(含 iPad 单测腿/iPad UI 腿/iOS-17 底线腿)。**未核实**:GH Actions 平台侧的运行结果(本环境 `gh` 未登录) |
|
||||
| T-iOS-16 集成 CI | `[x]` | `IntegrationTests/**` **26** `@Test`(10 基线 + 8 令牌端到端 + 8 令牌策略漂移守卫)+ `scripts/coverage-gate.sh`(现门 **5** 个包,含 ClientTLS)+ `ios.yml` 六个 job(含 iPad 单测腿/iPad UI 腿/iOS-17 底线腿)+ 新增 `android.yml`。`ServerHarness.locateTsx` 改为逐级向上解析,故 worktree 内无 `node_modules` 也能自举。**未核实**:GH Actions 平台侧的运行结果——本仓库唯一 remote 是自建 Gitea,两个 workflow **从未在任何 runner 上跑过**;本地已逐条复跑其命令 |
|
||||
| T-iOS-17 ntfy 桥验证+文档 | `[x]` | `ios/README.md` ntfy 章节(逐条引 `setup-hooks.mjs` 行号,只读验证,未动用户 hook 配置)。**DEFERRED**:手机端到端 |
|
||||
| T-iOS-18 F 走查(真机) | `[~]` | 机器可执行项已执行并指认测试名(P0 收官条目)。**缺口**:F-iOS 的真机项(QR 扫码/IME/震动/切换器遮罩目检/ntfy 端到端)仍 DEFERRED,手工清单在 LOG |
|
||||
| T-iOS-19 安全核对 | `[~]` | P0 面已逐条核(Origin 单点、G/RO 分界、五段 CIDR + 零 ArbitraryLoads、Keychain 属性)。**缺口**:P2 新增的 `NSMicrophoneUsageDescription`/`NSSpeechRecognitionUsageDescription` 尚未在**产物层**复核;release ipa 层核对仍未做(免费 team 无分发通道) |
|
||||
| T-iOS-19 安全核对 | `[~]` | P0 面已逐条核(Origin 单点、G/RO 分界、五段 CIDR + 零 ArbitraryLoads、Keychain 属性)。P2 新增的 `NSMicrophoneUsageDescription`/`NSSpeechRecognitionUsageDescription` **已在产物层复核**(真机构建产物的 Info.plist 实测有这两键)。**剩余缺口**:release ipa 层核对仍未做(免费 team 无分发通道) |
|
||||
| T-iOS-20 server APNs | `[x]` | `src/push/apns.ts` + `test/push-apns.test.ts`(含本地 h2c 假 APNs 的双 e2e;具体测试数以 `npm test` 输出为准,LOG 记 65)。**DEFERRED**:真机端到端需付费账号 |
|
||||
| T-iOS-37 server lastOutputAt | `[x]` | `src/types.ts:315` 可选字段 + `src/session/manager.ts:197` 映射 + 测试 |
|
||||
| T-iOS-38 APIClient P1 契约 | `[x]` | `APIClient/{ApnsToken,Projects,Prefs}.swift` + `ApnsTokenTests`/`ProjectsTests`/`PrefsRoundTripTests` |
|
||||
@@ -560,9 +560,9 @@ W5 验收(report-only, 并行)
|
||||
| T-iOS-31 语音 PTT | `[x]` | `Components/{VoicePTT,VoicePTTBanner,SpeechDictation}.swift` + `KeyBar` 🎤 键 + `VoicePTTTests` **40** `@Test`。**DEFERRED**:真机口述→确认→注入 |
|
||||
| T-iOS-32 Worktree + `--resume` 历史 | `[~]` | `Screens/{WorktreeSheet,ResumeHistorySheet}.swift`、`ViewModels/{WorktreeViewModel,ResumeHistoryViewModel}.swift` + `WorktreeViewModelTests`(22)/`ResumeHistoryViewModelTests`(12)/`ProjectResumeLaunchTests`(7)。**缺口**:Accept 的"端到端一次"(对真服务器真建/真删 worktree)无自动化腿、本环境也未手工跑 |
|
||||
| T-iOS-33 终端内搜索 | `[x]` | `Components/TerminalSearchBar.swift` + `TerminalScreen` 绑定 SwiftTerm 搜索 API + `TerminalSearchTests` **18**(含 2 条真 view 高亮断言) |
|
||||
| T-iOS-34 主题 + Dynamic Type | `[~]` | `DesignSystem/{AppTheme,TerminalPalette}.swift`、`Screens/SettingsScreen.swift`、`Tokens/Typography` 浅色档 + `AppThemeTests`(24)/`DynamicTypeLayoutTests`(8)。**缺口(已实测、未修)**:AX5 下键栏需 ~108.24pt 而 `KeyBarMetrics.barHeight` 固定 52pt → 键帽裁切,以 `withKnownIssue` 钉住(`KeyBar.swift` 不在该任务 Owns) |
|
||||
| T-iOS-34 主题 + Dynamic Type | `[x]` | `DesignSystem/{AppTheme,TerminalPalette}.swift`、`Screens/SettingsScreen.swift`、`Tokens/Typography` 浅色档 + `AppThemeTests`(24)/`DynamicTypeLayoutTests`(**14**)/`KeyBarTests`(**12**)。**缺口已闭合**(收尾波):`KeyBarMetrics.barHeight` 由常量 52pt 改为按字号档推导,`withKnownIssue` 已删、换成正向断言(AX5 不裁切 · 全 12 档不裁切且 ≥44pt · XS–XL 逐点仍 52pt 零回归 · 未封顶 AX5 溢出旧固定高的护栏)。**取舍**:键帽字体封顶在 `DS.Typography.numericClamp`(.accessibility2),故 AX3–AX5 的字号不再增长(不封顶时 AX5 要 108.24pt,会吃掉终端);该封顶由测试钉死不得漂移 |
|
||||
| T-iOS-35 web `?join=` 互通 | `[x]` | `DeepLinkRouter.swift` 的 `.joinShared` 分支 + `DeepLinkJoinTests` **19**(含改写后的既有拒绝用例) |
|
||||
| T-iOS-36 P2 验收 | `[~]` | 本波 Wave D 的验收 agent 正在执行;**结果与真实数字以 `PROGRESS_LOG.md` 的该条目为准**,本文不预写结论 |
|
||||
| T-iOS-36 P2 验收 | `[x]` | 两轮独立复验(Wave D + 收尾波)均已跑完,**真实数字以 `PROGRESS_LOG.md` 的该条目为准**:452 包测 / 550 App 测(iPhone 16 Pro 与 iPad Pro 11" M4 各一遍,**0 known issue**)/ 26 集成测 / 覆盖率门 5/5 / 真机构建 `BUILD SUCCEEDED` 且产物无 `aps-environment`。P2 五项逐条走查见本节上方各行 |
|
||||
|
||||
**说明**:上表的"测试数"是 `@Test` **声明**静态计数(`grep -rh '@Test'`),与 commit `850531f`/`a5fa843` 里实跑数字一致;
|
||||
参数化用例实跑会更多。App bundle 侧共 **532** 条 `@Test` 声明。
|
||||
@@ -588,10 +588,15 @@ W5 验收(report-only, 并行)
|
||||
另补 iPad UI-test 腿(同 commit)。
|
||||
- **签名解锁**:`DEVELOPMENT_TEAM` + target 级 `CODE_SIGN_IDENTITY` + `WEBTERM_PUSH_ENTITLEMENTS` env 开关
|
||||
(commit `c4f8b5b`;真机构建在免费 team 上 `BUILD SUCCEEDED`,7 天临时 profile)。
|
||||
- **已知未闭合缺口(供后续任务领走)**:① AX5 键栏裁切(见 T-iOS-34 行);② **无端到端令牌腿**——
|
||||
`IntegrationTests` 与模拟器内 live-server smoke 都不带 `WEBTERM_TOKEN` 起服务器(grep 无 `WEBTERM_TOKEN`/`webterm_auth`),
|
||||
令牌路径目前只有单元级覆盖;③ T-iOS-19 的产物层复核未覆盖 P2 新增的两条 usage description;
|
||||
④ worktree 建/删的**端到端**一次(T-iOS-32 Accept)既无自动化腿也未手工跑。
|
||||
- **收尾波(2026-07-30)闭合了其中三条**:① AX5 键栏裁切 → 已修(见 T-iOS-34 行);
|
||||
② 端到端令牌腿 → `IntegrationTests/AccessTokenGateTests.swift` **8 例**对真服务器(带 `WEBTERM_TOKEN` 自举)
|
||||
跑通:对令牌放行 / 错令牌 401 终态且 **connect 计数 == 1**(另有可重试失败的对照组证明"零重试"不是计时假象)/
|
||||
令牌不替代 Origin(合法 cookie + 外域 Origin 仍拒)/ `POST /auth` 的 204+Set-Cookie、401、204-无-Set-Cookie 三态;
|
||||
另加 `TokenPolicyDriftTests.swift` **8 例**漂移守卫(运行期读 `src/config.ts` 与 `src/http/auth.ts` 的真字面量,
|
||||
与三份 Swift 谓词逐条比对,含变异测试证明守卫自身够响);③ 两条 usage description 已在产物层复核(见 T-iOS-19 行)。
|
||||
- **剩余未闭合**:release ipa 层核对(免费 team 无分发通道);真机人工腿(口述 / 扫码 / 锁屏 Face ID / IME);
|
||||
Android instrumented 腿(`TinkAccessTokenStoreTest` 是令牌静态加密的唯一证明,需真机或模拟器,CI 上暂设为
|
||||
`workflow_dispatch` 触发——理由写在 `android.yml` 文件头:没人见它绿过的腿若设为必过,只会逼出一个假绿)。
|
||||
|
||||
### P0 — 每日可用("口袋里能开终端、能批准")· 合计 ~13 人天
|
||||
|
||||
@@ -920,7 +925,7 @@ W5 验收(report-only, 并行)
|
||||
- **T-iOS-33** · 终端内搜索 `[x]` ~1 pd。**Wave**: W9 · **Owns**: `App/WebTerm/Components/TerminalSearchBar.swift` + Tests · **Depends**: T-iOS-11 · **Accept**: SwiftTerm search API 命中高亮。
|
||||
- **T-iOS-34** · 主题 + Dynamic Type `[~]` ~1.5 pd。**Wave**: W9 · **Owns**: 主题/字号小增量(与同波任务文件不相交,开工时列明文件清单)· **Depends**: T-iOS-11/13 · **Accept**: 亮暗主题 + 最大字号不破版。
|
||||
- **落地**: `DesignSystem/{AppTheme,TerminalPalette}.swift` + `Screens/SettingsScreen.swift`(齿轮入口在 `ProjectsToolbarItem` 内,stack 与 split 两根视图共享)+ Tokens/Typography 浅色档;`AppThemeTests`(24)/`DynamicTypeLayoutTests`(8)。默认仍是深色(零回归)。
|
||||
- **缺口(已实测、未修)**: AX5 下键栏两行需 **108.24pt**,`KeyBarMetrics.barHeight` 固定 **52pt**(44+8)→ 键帽裁切;以 `withKnownIssue` 钉在 `DynamicTypeLayoutTests`(修好后该用例会报 "known issue was not recorded",提醒删标记)。`Components/KeyBar.swift` 不在该任务 Owns,需另派。
|
||||
- **缺口已闭合(收尾波,2026-07-30)**: `KeyBarMetrics.barHeight` 从常量 52pt 改为 `max(minHitTarget, keycapHeight(category)) + sm8`,`intrinsicContentSize`/init frame/`apply(contentSizeCategory:)` 三处同源,并经 iOS 17 `registerForTraitChanges` 支持运行期改档。`withKnownIssue` 已删。**取舍**:键帽字体封顶 `.accessibility2`(不封顶时 AX5 需 108.24pt,会把终端吃掉),沿用 DS 对密集内容的既有策略;实测条高 XS–XL 52 / XXL 55 / XXXL 59 / AccM 68 / AccL–AX5 77。
|
||||
- **T-iOS-35** · web `?join=` 互通(分享 QR 双向)`[x]` ~0.5 pd。**Wave**: W9 · **Owns**: `DeepLinkRouter.swift` 增量(`?join=` 解析)· **Depends**: T-iOS-22 · **Accept**: 手机扫 web 分享 QR 直达同会话。
|
||||
- **落地**: `DeepLinkRouter` 增 `.joinShared` 分支 + `DeepLinkJoinTests` 19 测(含把原"scheme 不是 webterminal"的拒绝理由改写为"web 形状只许单一 `join` 键");主机身份只经 `HostStore`+`HostEndpoint.originHeader` 解析,未配对 origin 一律走配对页且 hint 不回显链接内容。
|
||||
- **DEFERRED**: 用真手机相机扫 web 分享 QR 的目视走查(模拟器无相机)。
|
||||
|
||||
Reference in New Issue
Block a user