|
|
4880c31110
|
跨端: fix(设备闸): app state 交叉验证(矛盾⇒拿不准)+ 正例换成**真机实采**样本
pi 邮件 `6f902e1e` 指出两件,都对:
1. **我那条正例是自相矛盾的**:我用脚本把 `state #FOREGROUND` 对调,却漏了同一块的 `app state #X`
⇒ 造出 `state FG` + `app state BG` 这种**真机上不会出现**的 dump。于是"闸能放行"这条正例
建在**非法输入**上 —— 它绿,但它没证明任何真机会发生的事。
现在:正例改用 12:08 **真机实采**的 `fixtures/aa-dump-l-ours-foreground.txt`(两个 mission 都在、
`state`/`app state` 一致、FG 是我们);
2. 顺手把"矛盾怎么办"钉成规则:同一块里 `state` 与 `app state` 打架 ⇒ **`unverified`**,
**不许"挑一个信"**(那是把互相打脸的证据当成证据)。`app state` 缺失时不因此判未验
(否则老格式 dump 会一律未验 —— 那是"更安静的失效")。
判据 8 条全绿;登记同步为 8。
|
2026-09-15 12:10:49 +08:00 |
|
|
|
5337d51bfb
|
test(设备闸): 补第二份真样本(单 mission,我们不在列表里)+ 把"状态对调"那条从弱断言改成**严格正例**(pi §4②)
- 新样本 `fixtures/aa-dump-l-single-theirs.txt`:由真样本删掉我们那块得到,形状与 pi 12:03 的活 dump 一致
(单 mission、`state #FOREGROUND` 是对方)⇒ 正确判决 **`other`**,不是 `unverified`
—— 否则会把"别人占着前台"和"没读到"混成一种;
- `#FOREGROUND` 全删 ⇒ `unverified`(缺证据不猜);
- ★ 原"状态对调"那条我原先只断言 `ours || unverified`(当时心虚写宽的)。pi 指出:
**只判"读不出来就不许过"是不够的,还得有正例证明"读出来了真的能过"** —— 否则这道闸的失效方式是
"永远说未验"(更安静的失效,而且欠账永远还不完)。已改成严格断言 `ours` + `mayAssertOn === true`。
- 登记 5→7(我一度写成 8:我只加了 2 条,5+2=7 —— 相等契约下这种手误会被套件当场抓住,这正是它该干的事)。
|
2026-09-15 12:08:09 +08:00 |
|
|
|
b413fbb43e
|
跨端: fix(设备闸): 按真机形状改写解析(前台 = state #FOREGROUND 那个 mission 的 bundle),判据改喂真机样本
第一版是**猜的**格式(`bundleName: com.x`),真机上根本没有这种写法;退一步"取第一个 bundle name"
又会取到别人的(真机多 mission,`#31 com.example.homeagent` 排在我们 `#32` 前)⇒ 假绿(pi 独立复现)。
真机形状(样本 `test/fixtures/aa-dump-l-real.txt`,实采):每块 `Mission ID #N … ` +
`bundle name [com.x]` + `state #FOREGROUND/#BACKGROUND`;**前台只由 `state #FOREGROUND` 决定**。
- `parseMissions` / `foregroundBundle`:按块解析,取不到返回空(不猜、不兜底);
- `foregroundVerdict` 三态不变:`ours` / `other` / `unverified`;
- 有 mission 但**全无 FOREGROUND** ⇒ `unverified`(不是"没我们所以算别人");
- 空 dump / 截断 ⇒ `unverified`,状态词写明"**缺证据 ≠ 没有那个现象**"。
判据 5 条(喂真样本 + 对调状态 + 空/截断/无前台 + 撞名撞文案反证)全绿。
真样本本身含"对方在前台"那一刻 —— 争用在一分钟内真实发生过,所以这不是构造出来的场景。
|
2026-09-15 12:05:17 +08:00 |
|
|
|
e917b8782a
|
跨端: feat(设备闸): DeviceProbe.ts —— "读到别人的界面"是假绿来源,读之前先判"是谁的",拿不到就记未验
pi 邮件 `971c58fa` §4 / `bf583b0f` §2。别的 agent 在同模拟器上 `aa start` 会抢前台,
之后读到的控件树是**它的窗口** ⇒ 断言可能通过也可能红,**两者都不是在讲我们的界面**(前者=假绿)。
- `foregroundVerdict` 判决只有三种:`ours` / `other` / `unverified`;**只按 bundle 判,不许看标题/文案/控件名**
(别人的合法 dump 里完全可能有同名控件与同文案,"邮件"这种通用词尤其容易撞);
- `parseForeground` 取不到就 **undefined**(空 dump / 截断 / 格式变了都不猜);
- `mayAssertOn === false` ⇒ 调用侧必须记 **`未验`**(欠账继续开着),**不许**记通过、**不许**静默跳过
—— 跳过会在下一轮被读成"验过了";
- `unverifiedReason` 统一状态词,并写明"**缺证据 ≠ 没有那个现象**"。
判据喂 4 类样本(pi 指定的最易漏输入):① 我们的 dump ② **别人的合法 dump(含同名控件 + 同文案)**
③ 截断/畸形 ④ **空 dump**(窗口没起来时最常见,最容易被当成"坏现象不存在")。
另加一条只按 bundle 判的反证(把标题改成"像我们"也不许变 ours)。
**顺手抓到自己一个坑**:`firstMatch` 第一版的否定类既接受非 ASCII 也接受**换行**
⇒ 对 `windowTitle: 邮件\n abilityName: …` 会吞掉中文标题并**捕获下一行的键名**,
"标题"读到 `abilityName`(看起来有值、其实指错地方)。判据当场抓到 ⇒ 改成按行取、值允许中文、空值不回退。
|
2026-09-15 11:54:25 +08:00 |
|