From da9ba9a021ca2885a137f64f497e117dc9969ccc Mon Sep 17 00:00:00 2001 From: wangzhizhou <824219521@qq.com> Date: Thu, 29 Oct 2026 19:52:26 +0800 Subject: [PATCH 1/2] docs: move the trial baseline to build 30 on both machines Records the build-30 identity (ZIP 9704f209, host executable 16ac739f on air and pro), the reason 29 was replaced (report 219), and that the swap does not disturb IT-23 because day one has not been recorded yet. Signed-off-by: wangzhizhou <824219521@qq.com> --- ROADMAP.md | 3 ++- docs/reviews/217-1.0.0-freeze.md | 13 ++++++++----- docs/reviews/219-caret-follows-focus.md | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 01d85bd..1920622 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -245,7 +245,8 @@ ADR-147:Terminal正常实际提交“你”及wq前缀确认后的failure/INT/ - [ ] **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 装前数据与备份已核对;从下一个工作日开始逐日记录,换包即作废。 +- [ ] 2026-10-29 IT-23 五工作日试用(**1.0.0 / build 30**,air 与 pro 执行 SHA 均为 `16ac739f…`):两台设备已装同一包(报告217 §8)。build 29 因「候选窗跟随鼠标」缺陷(报告219)被 30 取代,IT-23 尚未起算,故换包不影响基线。 +- [x] 2026-10-29 **候选窗跟着鼠标而不是插入点(报告219,build 30)**:`caretRect` 给解析器传了 `allowsEmptyCaret: false`,`length()==0` 时解析直接返回 nil → 落到鼠标兜底;改为 `true`,并把回退链收敛为「本轮 → 上次成功位置 → 鼠标」,新增 3 条断言。两台设备已装 build 30。 - [~] 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**。 diff --git a/docs/reviews/217-1.0.0-freeze.md b/docs/reviews/217-1.0.0-freeze.md index 714ca65..c663e34 100644 --- a/docs/reviews/217-1.0.0-freeze.md +++ b/docs/reviews/217-1.0.0-freeze.md @@ -123,15 +123,15 @@ platforms/macos/tests/run-repro.sh \ - **静态零外联**:`./scripts/verify-no-network.sh`(或 `make verify-no-network`)通过。 - **运行时零外联**:一边打字一边 `lsof -i -a -p "$(pgrep -x Lampyris)"`,预期**无输出**。 -## 8. IT-23 试用基线:两台设备装同一个包(2026-10-28) +## 8. IT-23 试用基线:两台设备装同一个包(2026-10-29 更新为 build 30) | 项 | 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 | +| 版本 / 构建 | **1.0.0 / 30** | **1.0.0 / 30** | +| 宿主执行 SHA-256 | `16ac739f135ef1e9abfd750956a54411da3313e9cf675bdf7f50a165d246bddb` | **同值**(同一个二进制) | +| 更新程序构建号 | 30 | 30 | | 签名 / 公证 | Developer ID + `spctl` Notarized | 同(`codesign --strict`、`stapler validate` 均 PASS) | -| 用户数据 | config `cfc86cff…`、词库 800+ 行 | config `2bd3fde6…`、词库 **593 行**(装前装后一致) | +| 用户数据 | config `cfc86cff…`、词库 800+ 行 | config `cb8e7d05…`、词库 **685 行**(build 30 装前装后一致) | | 旧版本备份 | `updates/`、`uninstalled/` 历史项 | `uninstalled/bundle.aPZKev`(0.1.16) | | 输入源 | `cn.jokerhub.inputmethod.Lampyris.default` 已启用 | 已启用;当前停在 ABC,使用时按 ⌃Space 切 | @@ -140,3 +140,6 @@ pro 的安装记录:`ev-95-pro-stage.log`(ZIP 校验 → 解包 → 停宿 改为「停宿主 → 确认 `pgrep -x Lampyris` 为空 → 立即安装」后成功;这是安装器**正确的**保护行为,不是缺陷。 **IT-23 从下一个工作日开始**:两台设备都固定在 1.0.0/29,期间任何换包都会让当天记录作废。 + +> **为什么从 29 换到 30**:build 29 装机复验时发现「聚焦输入框 + 鼠标在远处 → 候选窗跟着鼠标」, +> 根因与修法见报告 219。IT-23 尚未开始记第 1 天,因此换包不影响试用基线;两台设备均已升级到 30。 diff --git a/docs/reviews/219-caret-follows-focus.md b/docs/reviews/219-caret-follows-focus.md index ecacc33..9dfc098 100644 --- a/docs/reviews/219-caret-follows-focus.md +++ b/docs/reviews/219-caret-follows-focus.md @@ -34,9 +34,9 @@ HUD 那条路径一直传的是 `allowsEmptyCaret: true`,所以同样的场景 | 单元 | `caret-placement.swift` 新增回退链三例:本轮结果优先 / 无本轮时用上次位置 / 两者都没有才用鼠标 | | 解析器 | 既有断言已覆盖「空文档 + `allowsEmptyCaret: true` 取到行框」,本次让候选窗走同一条 | | 回归 | `make verify`、`make macos-offline-tests`(56 文件 / 303 例)全绿 | -| 实机 | 待 build 30 装机复验:**聚焦输入框、把鼠标移到屏幕另一端、再打字**,候选窗应贴着插入点 | +| 实机 | 待用户复验(build 30 已装两台设备):**聚焦输入框、把鼠标移到屏幕另一端、再打字**,候选窗应贴着插入点 | ## 4. 影响 -- 版本仍 1.0.0,构建号 29 → **30**;锁定候选随之更新(报告 217 §8 的身份表在复验后补记)。 +- 版本仍 1.0.0,构建号 29 → **30**;锁定候选随之更新为 build 30(ZIP `9704f209…`、宿主执行 `16ac739f…`,报告 217 §8)。 - IT-23 尚未开始记第 1 天,因此**不影响**试用基线;两台设备都升级到 30 后再开始计时。 From e09f314cbf69d4bf9d73d116ee153345fd841a7f Mon Sep 17 00:00:00 2001 From: wangzhizhou <824219521@qq.com> Date: Thu, 29 Oct 2026 20:13:59 +0800 Subject: [PATCH 2/2] diag: file-based switch and branch logging for the state HUD Two rounds of "the HUD did not appear" could not be settled because LAMPYRIS_HUD_DIAG set through launchctl does not reliably reach a host that launchd started, so the log was simply never written. The switch is now also a file (~/Library/Application Support/Lampyris/hud-diag), and showStateFeedback logs which branch it took (inline chip vs HUD), the panel/composition state, and the caret it passed on. hudCaretRect logs the client and frontmost bundle at entry. Build 31 so this can be diagnosed on the machine where it happens. Signed-off-by: wangzhizhou <824219521@qq.com> --- packaging/build-number | 2 +- platforms/macos/Sources/InputController.swift | 21 +++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packaging/build-number b/packaging/build-number index 64bb6b7..e85087a 100644 --- a/packaging/build-number +++ b/packaging/build-number @@ -1 +1 @@ -30 +31 diff --git a/platforms/macos/Sources/InputController.swift b/platforms/macos/Sources/InputController.swift index 9eee0b5..ff7966c 100644 --- a/platforms/macos/Sources/InputController.swift +++ b/platforms/macos/Sources/InputController.swift @@ -272,11 +272,20 @@ final class LampyrisInputController: IMKInputController { // 只有会话仍在组合、候选窗会保留时才内联;宽度/模式/中英会 cancel 组合, // 这类切换必须走 HUD,否则候选窗随即关闭、用户什么都看不到。 if let window = candidateWindow, window.isVisible, session?.isComposing == true { + if Self.hudDiagEnabled { + Self.hudDiag("feedback msg=\(message) branch=chip visible=true composing=true") + } window.updateStatus(candidateStatus()) window.refreshLayout() return } - StateHUDController.shared.show(message, caret: hudCaretRect()) + let caret = hudCaretRect() + if Self.hudDiagEnabled { + Self.hudDiag("feedback msg=\(message) branch=hud visible=" + + "\(candidateWindow?.isVisible ?? false) composing=\(session?.isComposing ?? false) " + + "caret=\(caret.map(NSStringFromRect) ?? "nil")") + } + StateHUDController.shared.show(message, caret: caret) } /// HUD 用光标矩形:无客户端/取不到时返回 nil(不显示,不退鼠标)。 @@ -298,6 +307,11 @@ final class LampyrisInputController: IMKInputController { let length = max(0, client.length()) let selection = client.selectedRange() let bundle = client.bundleIdentifier() ?? "" + if Self.hudDiagEnabled { + Self.hudDiag("hud client=\(bundle) frontmost=" + + "\(NSWorkspace.shared.frontmostApplication?.bundleIdentifier ?? "nil") " + + "len=\(length) sel=\(selection.location)") + } let windowLevel = client.windowLevel() let diag = Self.hudDiagEnabled let startIndex = Self.caretLookupIndex( @@ -376,7 +390,10 @@ final class LampyrisInputController: IMKInputController { /// 诊断开关(默认关闭):`launchctl setenv LAMPYRIS_HUD_DIAG 1` 后重启宿主, /// 光标矩形解析过程写入 `$TMPDIR/lampyris-hud-diag.log`,用于真机定位 HUD 偏移。 static var hudDiagEnabled: Bool { - ProcessInfo.processInfo.environment["LAMPYRIS_HUD_DIAG"] != nil + if ProcessInfo.processInfo.environment["LAMPYRIS_HUD_DIAG"] != nil { return true } + // 文件开关:宿主由 launchd 拉起,`launchctl setenv` 不总能传进来(报告219/220)。 + let marker = ImePaths.supportDirectory()?.appendingPathComponent("hud-diag") + return marker.map { FileManager.default.fileExists(atPath: $0.path) } ?? false } static func hudDiag(_ message: String) {