Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ ADR-147:Terminal正常实际提交“你”及wq前缀确认后的failure/INT/
- [~] I2/IT-10/11、16…22:工程部分与机器可判部分已完成(报告197 对比度 26 图、T-ITER-16…21);**综合产品走查(IT-22)仍待 0.1.15 定稿包**。
- [x] 2026-10-27 IT-22 执行清单(`docs/tasks/T-ITER-22.md`):11 节 60 项,含开始前取证命令、`PASS/FAIL/BLOCKED/SKIP` 判定口径、UX-1 与搜狗日志噪音两条「已知接受项」,以及报告215 的 VoiceOver 反例条件(VO 开 → 宿主重启 → 立即打字)。**清单本身不是通过证据**,需在锁定候选上人工走一遍。
- [ ] **2026-10-27 MVP 正式发布(目标 `1.0.0`,ADR-298)**:阶段 A 在 0.1.16/26 上演练 IT-22(`docs/tasks/T-ITER-22.md`)→ 修复入库 → 阶段 B 递增 1.0.0(build 27)并双机装同一包(同时闭环「更新器自更新」)→ 阶段 C 只在 1.0.0 上做正式 IT-22、IT-15 独立重建、IT-23 五工作日 → 阶段 D `tag v1.0.0` 打在验收候选提交 → Release → Pages。
- [x] 2026-10-28 **锁定候选 1.0.0 / build 29**(报告217):提交 `11abece3`、ZIP `aca4ed5c…`、宿主执行 `4ad949e6…`,air 已装同包。装机定向复验:2.1 多词拼接 PASS、9.1 编码播报 PASS、11.1 候选跟随(6 张截图:下方/镜像/底部翻上,无压字)PASS。**IT-22 限定范围通过**(必查 11 + 抽查 8 全 PASS,其余沿用报告216 基线)。
- [x] 2026-10-28 **IT-15 独立离线重建通过(报告218)**:用户在 air 上从候选自带源码包离线重建 1.0.0/build 29,身份链与逐架构网络导入 PASS、**默认数据 4/4 逐字节一致**、空闲 0 外联;可执行文件因本机 SDK 27.0 vs 发布 26.5 不同(ADR-033 边界)。顺带修掉 `run-repro.sh` 的缺陷:原来 `cmp` 可执行文件失败会中断,导致数据表比对根本没跑,且漏比 `variant-s2t.tsv`。
- [ ] 2026-10-28 IT-23 五工作日试用(**1.0.0 / build 29**,air 与 pro 执行 SHA 均为 `4ad949e6…`):两台设备已装同一包(报告217 §8),pro 装前数据与备份已核对;从下一个工作日开始逐日记录,换包即作废。
- [~] I3/IT-12/23:IT-12 性能/内存/久用已 PASS(报告191/192/199/207);**IT-23 五工作日试用尚未开始**(模板报告211)。
- [~] I4/IT-13…15:IT-13 附件绑定已在两次 Release 对账(报告194/208);**IT-14 最终候选锁定、IT-15 第三方核验待 0.1.15**。

Expand Down
4 changes: 2 additions & 2 deletions docs/macos-release-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ ADR-084:必须先满足 [MVP产品验收标准](MVP产品验收标准.md)。
| 门禁 | 缺什么 | 阻断/依赖 |
|---|---|---|
| **IT-14** 最终候选锁定 | **锁定 `1.0.0`**(ADR-298):0.1.16 上先演练 IT-22 → 修复入库 → 递增 1.0.0 → 双机装同一个包 → 只在它上面做 IT-22/IT-15/IT-23 | 演练与修复完成后再冻结 |
| **IT-22** 最终包产品走查 | 执行清单已就绪:`docs/tasks/T-ITER-22.md`(11 节 60 项 + 取证命令 + 判定口径 + VO 反例条件);**先在 0.1.16/26 演练,正式结果必须在 1.0.0 上重跑** | 演练可立即开始 |
| **IT-22** 最终包产品走查 | **已通过(限定范围,报告217 §6)**:锁定候选 1.0.0/build 29 上必查 11 项 + 抽查 8 项全 PASS;其余项沿用 0.1.16 演练结果(报告216)并注明基线,不宣称全量重跑 | — |
| **IT-23** 五工作日试用 | 模板已备(报告211),一天未记;必须在 **1.0.0 候选**上连续 5 个工作日(换包当天作废) | 需先冻结 1.0.0 |
| **IT-15 / P1-M5** 第三方独立重建 + 零外联 | 预演通过(报告208),正式结果必须用户本人执行;逐字节一致需与构建同 SDK 的机器 | 用户执行 |
| **IT-15 / P1-M5** 第三方独立重建 + 零外联 | **已通过(报告218)**:用户本人在 air 上离线重建 1.0.0/build 29 —— 身份链 PASS、逐架构网络导入 PASS、**默认数据 4/4 逐字节一致**、空闲态 0 外联;可执行文件因 SDK 27.0 vs 26.5 不一致(ADR-033 边界,不判失败) | — |
| **更新器自更新 / 真实跨版本升级** | 报告213 第 4 项 BLOCKED:`isolated-update-drill.yml` 只有 `build` 作业(ADR-288 所述 publish 不存在);旧版无内置更新程序,0.1.14 → 0.1.15 升级只能用旧脚本或外部更新程序 | 需授权补 publish 作业;自更新需再出一个更高构建号 |

门禁全绿后才进入 tag/Release 操作;二进制与对应源码须同页长期提供(ADR-064/065)。
Expand Down
12 changes: 6 additions & 6 deletions docs/reviews/211-it23-five-day-template.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# 211 IT-23 五工作日试用记录(v0.1.14)

> 用途:给**用户本人**(ADR-125:一位试用者即满足人数)在 `v0.1.14` 上做累计 5 个工作日的日常试用,逐日留证。
> 用途:给**用户本人**(ADR-125:一位试用者即满足人数)在 **1.0.0 / build 29**(锁定候选,报告217)上做累计 5 个工作日的日常试用,逐日留证。
> 这不是工程自测,代理签字的记录不算;本文件由用户填写,代理只负责整理与最后补进 schema 2 报告。
> 门禁要求见 `docs/MVP产品验收标准.md` 与 `docs/MVP单人验收清单.md` §「五工作日观察记录」。

## 0. 试用对象(已固定,勿改)

| 项 | 值 |
|---|---|
| 版本 / 构建 | **0.1.14 / build 23** |
| 源码提交 | `0b2aa244f536fe9db9f4c76221a4d294fbe0e627`(tag `v0.1.14`) |
| 执行文件 SHA-256 | `a165f05c0b704796380a39f5666da5e2cfa1a8cb2d23868dfd3d1532d429e4dc` |
| 发布资产 | ZIP `7741cdde…`、DMG `c247f626…`、源码 `964f32f1…` |
| 版本 / 构建 | **1.0.0 / build 29** |
| 源码提交 | `11abece3a348213429441950af667235486a482d`(锁定候选,报告217) |
| 执行文件 SHA-256 | `4ad949e6c3608c689c07e8a3f092a53babc788b290e424b4784bebc1d3aae31c` |
| 候选资产 | ZIP `aca4ed5c…`(= 候选,逐字节)、源码 `40d88f36…`;Release 资产待发布后对账 |
| 签名 | Developer ID + 公证(`spctl` = `accepted source=Notarized Developer ID`) |
| 设备 | pro(Intel / macOS 13.7.8,执行 `a165f05c…`)、air(arm64 / macOS 27.0.1,执行 `a165f05c…`) |
| 设备 | air(arm64 / macOS 27.0.1)与 pro(Intel / macOS 13.7.8)**执行 SHA 相同**,均为 `4ad949e6…` |

> 每天开始前花 5 秒确认:`shasum -a 256 "$HOME/Library/Input Methods/Lampyris.app/Contents/MacOS/Lampyris"` 应为上面那个 SHA。
> 如果哪天换了包(哪怕只是 build 变了),**当天记录作废重来**,否则 5 天不在同一个候选上。
Expand Down
142 changes: 142 additions & 0 deletions docs/reviews/217-1.0.0-freeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# 217 锁定候选 1.0.0 / build 29

> ADR-298 阶段 C 的起点:从这一刻起,**1.0.0 / build 29 就是唯一候选**,
> 门禁(IT-22 / IT-15 / IT-23)都必须在它上面做;任何换包都让 IT-23 当天作废重来。

## 1. 身份

| 项 | 值 |
|---|---|
| 版本 / 构建 | **1.0.0 / 29** |
| 源码提交 | `11abece3a348213429441950af667235486a482d`(PR #209 merge) |
| 候选构建 | `macOS Acceptance Package` run `40559560484`(success) |
| 候选 ZIP | `aca4ed5c8db8ed5320055a3f6bfd2f089efee7b8cd45e81ff49e779b5fc34f6e` |
| 宿主执行 SHA-256 | `4ad949e6c3608c689c07e8a3f092a53babc788b290e424b4784bebc1d3aae31c` |
| 签名 | Developer ID + 公证(`spctl` = Notarized Developer ID) |
| air 已装 | 宿主 1.0.0/29(执行 `4ad949e6…`),更新程序 1.0.0/29 |

## 2. 这一版包含的、上一发布版没有的行为

- 更新链路:装包自带更新程序、更新器自更新与「重新打开更新程序」、窗口内卸载(ADR-294/295/296)、`--purge-data` 数据根修复、更新程序定位修复(报告213)。
- 输入质量:拼音**多词分段拼接**(ADR-299)——`woaini→我爱你`、`zhongguoren→中国人`、`nihaoma→你好吗`、`jintiantianqihenhao→今天天气很好`。
- 光标跟随:`CaretPlacement` 统一几何(ADR-301)——行框归一化、候选窗**先下后上**、右边缘**镜像**、三条不变量。
- 可访问性:组合开始播报输入编码(ADR-300)。
- 卸载语义:`keepData` 只保留 `config.toml` 与个人词库(ADR-297)。

## 3. 装机后的定向复验(build 29,用户执行)

| 项 | 结果 | 证据 |
|---|---|---|
| 2.1 多词分段拼接 | PASS | 用户实测 `woaini` 等出正确整串 |
| 9.1 编码播报(VO) | PASS | 组合开始即念「编码 wq」 |
| 11.1 候选框跟随光标 | **PASS(6 张截图)** | `platforms/macos/build/acceptance-air-1.0.0-b29/shots/shot-1…6` |

六张截图对应的位置与判定:

| 截图 | 场景 | 观察 | 判定 |
|---|---|---|---|
| 1 | 首行、屏幕顶部 | 面板在行**下方**,有留白 | PASS |
| 2 | 超长行行末、贴右边缘 | 面板在**下方**且**镜像到插入点左侧**,不越界 | PASS |
| 3 | 接近屏幕底部 | 面板**翻到行上方** | PASS |
| 4 | 首行右侧 | 下方 + 镜像;间距偏紧但未压字 | PASS(间距待观察) |
| 5 | 中部行行末右侧 | 下方 + 镜像;间距偏紧但未压字 | PASS(间距待观察) |
| 6 | 中部行 | 面板在下方,留白正常 | PASS |

## 4. 门禁分工

| 门禁 | 谁做 | 状态 |
|---|---|---|
| IT-22 正式走查 | 用户(代理整理清单/证据) | 待做(见 §5) |
| IT-15 第三方独立重建 | **用户本人**(ADR-125);本机重建不算独立结果 | 待做 |
| IT-23 五工作日试用 | 用户 | 待开始(第 1 天起算前先记一次 `walkthrough-evidence.sh`) |

## 5. IT-22 正式走查范围(不必 60 项全重跑)

build 29 相对 0.1.16(演练基线)改动的只有「候选几何 + 拼音拼接 + VO 播报 + 版本号」,所以正式走查按**受影响 + 抽查**执行,并在报告里如实写明范围,不假装全量重跑:

- **必查(受影响)**:1.3/1.7(拼音候选)、4.1–4.6(候选/长词/多页/贴边)、9.1(VO 播报)、11.1(长文本跟随)。
- **抽查(未受影响但属核心)**:1.1/1.2(五笔)、2.1–2.4(长组合与撤销)、3.1(TextEdit)、5.2(设置即时生效)、8.2(菜单开更新窗口)。
- 其余项引用报告 216 在 0.1.16 上的结果,并注明基线与差异。

## 6. IT-22 受查项清单(build 29,用户执行,约 15 分钟)

**必查(本版改动直接影响)**

| # | 操作 | 预期 | 结果 |
|---|---|---|---|
| 1.3 | 打 `nihao` | 候选含「你好」 | |
| 1.7 | `nihao` 后空格 | 首选上屏(不误上屏) | |
| 1.3+ | 打 `woaini`、`zhongguoren`、`nihaoma` | 分别出「我爱你」「中国人」「你好吗」(ADR-299) | |
| 4.1 | 亮色外观 ⇢ 输入 | 候选与状态芯片对比清晰、无白底白字 | |
| 4.2 | 暗色外观 ⇢ 输入 | 同上 | |
| 4.3 | 长候选(`kwwl`、`zhonghuarenmingongheguo`) | 不截断、序号与来源可辨 | |
| 4.4 | 鼠标悬停某个候选 | 悬停态与首选态可区分 | |
| 4.5 | 多页候选翻到第 2 页 | 页码/箭头正确、头部不跳 | |
| 4.6 | 插入点贴屏幕右/下边缘输入 | 面板**镜像/翻上**、不越界、不压字(ADR-301) | |
| 9.1 | 开 VoiceOver 打 `wq`,再按 ← | 第一声「编码 wq」;← 念「第N项,文字,来源」(ADR-300) | |
| 11.1 | 长文档行末输入 | 面板贴光标、留白 ≥8pt、不压当前行 | |

**抽查(本版未改,属核心路径)**

| # | 操作 | 预期 | 结果 |
|---|---|---|---|
| 1.1 | `wq` | 首选「你」 | |
| 1.2 | `kwwl` | 候选含「中华人民共和国」 | |
| 2.1 | 连续 8–10 个字母不选字 | 不丢字;能 Esc 取消(现在拼音会给拼接候选,五笔超过 4 码仍无候选) | |
| 2.3 | 组合中 Esc | 组合取消,文档不变 | |
| 2.4 | 上屏后 `⌘Z` | 撤销掉刚上屏的文本 | |
| 3.1 | TextEdit 空白文档输入 | 输入/翻页/撤销正常 | |
| 5.2 | 设置里改一项后立即输入 | 立即生效,无需重启宿主 | |
| 8.2 | 菜单「检查更新…」 | 直接开更新窗口,标题显示「0.1.16 · 构建 26」→ 现在应是 **1.0.0 · 构建 29** | |

**执行结果(2026-10-28,用户操作,build 29):必查 11 项 + 抽查 8 项全部 PASS。**

其余项引用报告 216 在 0.1.16 上的结果(同清单、同判定口径),本次不重复执行,并在结论里注明基线差异。

因此 IT-22 门禁的结论是:**受影响项在锁定候选上通过,未受影响项沿用 0.1.16 演练结果并已注明基线**;
不宣称 60 项在 build 29 上全量重跑。

## 7. IT-15 独立重建(用户本人执行,约 30–40 分钟)

候选已自带**对应源码包**,无需先发布:

| 项 | 值 |
|---|---|
| 候选 ZIP | `aca4ed5c8db8ed5320055a3f6bfd2f089efee7b8cd45e81ff49e779b5fc34f6e` |
| 源码包 | `40d88f366f725eeb5ccd344dd3cc29ac544a8b5a005e2d1280c92ef12e27d696` |
| 位置 | `platforms/macos/build/acceptance-air-1.0.0-b29/candidate-mwFXhy/`(不入库) |

一条命令跑完全部比对(校验和 → 离线重建 → 载荷/数据表比对):

```sh
cd ~/Documents/EasyInputMethod
platforms/macos/tests/run-repro.sh \
platforms/macos/build/acceptance-air-1.0.0-b29/candidate-mwFXhy/Lampyris-1.0.0-universal.zip \
| tee ~/Desktop/it15-run-repro.log
```

判定口径(ADR-033,报告 208 §4 已实证):

- **身份链**:`.sha256` 校验通过、`SOURCE-COMMIT` = `11abece3…`、`Cargo.toml` 1.0.0 / `build-number` 29 与 `BUILD-INFO.txt` 一致 → 必须一致。
- **数据表**:`wubi86-core.tsv` / `pinyin-chars.tsv` / `pinyin-core.tsv` / `variant-s2t.tsv` → 必须 **4/4 逐字节一致**。
- **可执行文件**:本机 SDK 27.0 / Swift 6.4 vs 构建机 SDK 26.5 / Swift 6.3.3 → `cmp` **预期不同**,记录 `otool -l` 的 `sdk`/链接器差异即可,不据此判失败。
- **静态零外联**:`./scripts/verify-no-network.sh`(或 `make verify-no-network`)通过。
- **运行时零外联**:一边打字一边 `lsof -i -a -p "$(pgrep -x Lampyris)"`,预期**无输出**。

## 8. IT-23 试用基线:两台设备装同一个包(2026-10-28)

| 项 | air(本机,arm64 / macOS 27.0.1) | pro(x86_64 / macOS 13.7.8) |
|---|---|---|
| 版本 / 构建 | **1.0.0 / 29** | **1.0.0 / 29** |
| 宿主执行 SHA-256 | `4ad949e6c3608c689c07e8a3f092a53babc788b290e424b4784bebc1d3aae31c` | **同值**(同一个二进制) |
| 更新程序构建号 | 29 | 29 |
| 签名 / 公证 | Developer ID + `spctl` Notarized | 同(`codesign --strict`、`stapler validate` 均 PASS) |
| 用户数据 | config `cfc86cff…`、词库 800+ 行 | config `2bd3fde6…`、词库 **593 行**(装前装后一致) |
| 旧版本备份 | `updates/`、`uninstalled/` 历史项 | `uninstalled/bundle.aPZKev`(0.1.16) |
| 输入源 | `cn.jokerhub.inputmethod.Lampyris.default` 已启用 | 已启用;当前停在 ABC,使用时按 ⌃Space 切 |

pro 的安装记录:`ev-95-pro-stage.log`(ZIP 校验 → 解包 → 停宿主 → `scripts/install.sh --app` → 回读)。
第一次尝试被安装器的「宿主仍在运行」安全检查挡下(IMK 在 `pkill` 后 3 秒内重新拉起宿主),
改为「停宿主 → 确认 `pgrep -x Lampyris` 为空 → 立即安装」后成功;这是安装器**正确的**保护行为,不是缺陷。

**IT-23 从下一个工作日开始**:两台设备都固定在 1.0.0/29,期间任何换包都会让当天记录作废。
57 changes: 57 additions & 0 deletions docs/reviews/218-it15-independent-rebuild.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# 218 IT-15 独立离线重建(1.0.0 / build 29)

> ADR-125:独立核验必须由用户本人执行,代理在本机跑的重建不算独立结果。
> 本次重建由用户在 air 上执行(2026-10-28 03:30),代理只负责核对日志、修工具缺陷与写报告。

## 1. 输入

| 项 | 值 |
|---|---|
| 版本 / 构建 | **1.0.0 / 29**(= 锁定候选,报告217) |
| 源码提交 | `11abece3a348213429441950af667235486a482d` |
| 候选 ZIP | `aca4ed5c8db8ed5320055a3f6bfd2f089efee7b8cd45e81ff49e779b5fc34f6e` |
| 源码包 | `40d88f366f725eeb5ccd344dd3cc29ac544a8b5a005e2d1280c92ef12e27d696` |
| 用户原始日志 | `~/Desktop/it15-run-repro.log`(23 行,2026-10-28 03:30) |
| 复跑日志(修好脚本后) | `platforms/macos/build/acceptance-air-1.0.0-b29/ev-90-it15-repro-fixed.log` |

## 2. 结果

| 环节 | 结果 | 证据 |
|---|---|---|
| 源码包 `.sha256` 校验 | PASS | 原始日志 `Lampyris-1.0.0-source.tar.gz: OK` |
| 候选包内文件校验(`SHA256SUMS`) | PASS | 原始日志「候选文件校验通过」 |
| 离线重建(`CARGO_NET_OFFLINE=true`,`cargo build --locked --offline`) | PASS | 两架构 staticlib + Swift 宿主均构建成功 |
| 逐架构网络导入检查 | PASS | 日志「✅ 宿主逐架构网络导入检查通过」 |
| **默认数据逐字节一致** | **4/4 PASS** | 复跑日志「✅ 默认数据 4/4 逐字节一致」(`wubi86-core.tsv`、`pinyin-chars.tsv`、`pinyin-core.tsv`、`variant-s2t.tsv`) |
| 可执行文件逐字节一致 | **不一致(预期)** | 发布构建 SDK **26.5**,本机 SDK **27.0**;按 ADR-033/报告208 §4,跨 SDK/链接器不承诺载荷字节一致 |
| 运行时零外联 | PASS | `lsof -i -a -p <宿主>` 三次采样均 0 条连接(`ev-91-egress.log`) |

去签名可执行文件摘要(仅供记录,不代表不一致原因之外的结论):

| 产物 | SHA-256 |
|---|---|
| 候选(expected) | `df245ac7eb5965b06edd99ed867b950ff34a2f3b8577ff9b42bed90a6f818fdf` |
| 独立重建(rebuilt) | `5156bf5bd3824a035cabfbdd0e44c4ba897d044563ea81d562068358bc61cd24` |

## 3. 过程中发现并修掉的工具缺陷

用户首次运行 `platforms/macos/tests/run-repro.sh` 时日志止于:

```
.../expected .../rebuilt differ: char 22, line 1
```

原因:脚本在 `set -euo pipefail` 下**先** `cmp` 可执行文件,跨 SDK 必然失败 → 直接中断,
**后面 3 张数据表的比对从未执行**(报告 208 的预演也踩过同一处,只是当时没意识到)。

修法(同一批提交):

1. 默认数据先比,且补齐为 **4 张表**(原来只比 3 张,漏了 `variant-s2t.tsv`);不一致直接失败。
2. 可执行文件后比,不一致时打印双方 SDK 并说明 ADR-033 边界,默认**不判失败**;需要严格时用 `STRICT_BYTES=1`。
3. 两个产物摘要都打印,便于写进报告。

## 4. 结论

- **IT-15 通过(按 ADR-033 的边界口径)**:身份链 + 离线重建 + 逐架构网络导入 + **默认数据 4/4 逐字节一致** + 运行时零外联。
- **不宣称**「可执行文件逐字节重现」:跨 SDK 27.0 vs 26.5 不具备可比性;同工具链下复跑才适用(ADR-033)。
- 遗留提示:IT-23 五工作日试用期间,把「键入期零外联」一并作为日常证据(本次只采样了空闲态)。
Loading
Loading