Files
soft_quay/docs/tasks/T-608.md
ila 1b7f72e658
Harness governance / validate (push) Has been cancelled
Phase 0 build gate / verify (push) Has been cancelled
Add adapter interaction contracts (T-608)
2026-07-17 10:41:40 +08:00

8.3 KiB
Raw Permalink Blame History

id, title, phase, deps, status, created, issue, context_ref, claim_branch, work_branch, write_paths
id title phase deps status created issue context_ref claim_branch work_branch write_paths
T-608 建立双 Gio 适配器交互契约 2
T-607
DONE 2026-07-17 null 0705948d74 null agent/codex/T-608
docs/tasks/T-608.md
app-modern/ui/gio/
app-win7/ui/gio/
docs/routes.md
docs/04-architecture.md
docs/review/phase2-review.md
docs/00-ai-start-here.md
docs/06-tasks.md
docs/current-state.md

问题 / 背景

T-203 已把筛选、可见项、选中项和视图切换的核心语义收敛到共享的 core/application.CatalogListModel,modern/win7 也都用 layout.List 和按 AppID 保存的控件 map 实现了列表与详情。现有 core 测试充分覆盖 ViewModel 纯逻辑,两个 Gio 包也分别有窗口尺寸、500 项惰性布局、控件保留和详情渲染测试。

但两个适配器测试大多直接调用 shell.model.SetCategory、Select 等方法,没有证明 Editor、视图/分类/行/恢复/关闭控件产生的 Gio 事件确实经 Layout 的 drainInput 更新共享 model。现有 500 项测试只检查渲染数量小于总数,控件测试也没有覆盖重排后的行身份、分类控件释放或详情关闭后的完整上下文。双 Gio 版本继续平行演进时,这些接线缺口可能让一端出现按钮无效、按可见序号打开错误软件、过滤恢复语义漂移或控件泄漏,而 core 测试无法发现。

本任务建立两端一致的适配器交互契约,只验证 Gio 层如何把交互连接到已经验证的共享 ViewModel,不在两个 shell 中重复证明筛选算法本身。

方案

  1. 在 modern 与 win7 的 ui/gio 包分别增加同名、同场景的适配器契约测试矩阵:
    • 两端使用各自锁定的 Gio 版本和本包 AppShell,不得互相 import。
    • 场景名称、fixture 身份和断言语义保持一致;只允许 edition、窗口尺寸等真实适配差异。
    • 使用内存 fixture、widget.Clickable.Click、Editor 状态和确定性的 layout.Context,不依赖真实窗口、网络、磁盘、计时或截图。
  2. 验证输入接线而非绕过适配器直接改 model:
    • Editor 文本经一次 Layout 更新 model query。
    • 全部/已安装/可更新、分类和“显示全部软件”控件的 queued click 经下一次 Layout 更新或重置 model。
    • 软件行 queued click 必须按稳定 AppID 打开详情;Catalog 重排后仍打开原控件所属 AppID,不得按旧可见索引选择。
  3. 验证详情上下文契约:
    • 打开正确 AppID 后详情实际布局。
    • 关闭详情控件只清除 selection,保留 query、category、view 和 layout.List.Position 列表上下文。
  4. 收紧虚拟化与控件生命周期证据:
    • 500 项有限 viewport 中 lastRendered、layout.List.Position.Count 都证明只布局非零可见子集。
    • Catalog 过滤、重排和同 ID 更新保留 row control 指针;移除 app 后 row control 释放。
    • 保留分类继续复用 control;移除最后一个该分类的 app 后对应 category control 释放。
  5. 区分两类空状态的适配恢复路径:
    • 空 Catalog 不伪装成过滤无结果,没有可恢复筛选。
    • 非空 Catalog 被过滤为零项时保留 filter-active 事实,“显示全部软件”点击经 Layout 清空 Editor/筛选并恢复列表。
  6. 若契约测试暴露 modern/win7 接线漂移,只在对应 ui/gio 内做满足契约的最小修正;不得把共享 ViewModel 逻辑复制进适配层。

验收要点

  • modern/win7 都运行相同命名和语义的适配器场景矩阵,测试数据使用稳定 AppID,且两个 workspace 不互相解析对方 Gio 版本。
  • 搜索 Editor、三个视图按钮、分类按钮和恢复按钮都通过 Layout/drainInput 真正更新共享 model;测试不以直接调用对应 model setter 代替控件事件。
  • Catalog 重排后点击保留的 row control 仍选中正确 AppID;关闭详情后 query、category、view 与列表位置保持。
  • 500 项有限 viewport 只布局非零可见子集,不把“少于 500”作为唯一证据;测试同时核对 Gio list 的可见 count/position。
  • row controls 与 category controls 按稳定身份复用,删除 app/category 后不再留在 map;不按列表序号迁移状态。
  • 空 Catalog 与过滤无结果可观察地区分;只有后者通过恢复控件清除 Editor/筛选并重新显示 Catalog。
  • 测试只覆盖适配器接线与生命周期,不重复断言 CatalogListModel 的名称/tag/分类/状态过滤算法组合,不为测试导出新的生产 API。
  • GOTOOLCHAIN=go1.25.0 的 modern UI 测试与 GOTOOLCHAIN=go1.20.14 的 win7 UI 测试各自重复运行通过。
  • ./scripts/verify_phase0.ps1 全绿,包含 core Go 1.20 vet/test、双 workspace 测试和 Windows amd64 构建。
  • python scripts/validate_agent_context.py、python scripts/validate_harness_governance.py 与提交前差异检查通过。

边界(不改什么)

  • 不修改 core/application.CatalogListModel 的 VisibleItems 快照生命周期;该 API 健壮性按审核顺序另立后续任务。
  • 不拆分或重构两个 shell.go,不借测试任务统一现代版与 Win7 版的视觉布局或 Gio 依赖。
  • 不实现真实鼠标坐标命中、OS 窗口/IME 自动化、截图或滚动性能基准;本任务是确定性的包内交互契约,真机矩阵留 T-601/T-602。
  • 不接入下载、安装、启动、授权或真实图标 viewport 调度,不增加 Catalog/API/Schema 字段。
  • 不处理 ErrIconCacheUnsafe quarantine/诊断策略、ZIP 中央目录预扫描、断电耐久、Catalog 签名向量或 T-302 安装整合。
  • 不升级 Go/Gio,不合并 modern/win7 workspace,不修改、提交或删除用户的 soft_quay.code-workspace。

协作约束

  • 按仓库当前规则由单 Agent 串行执行,不启动子 Agent。
  • 本任务只允许修改 frontmatter 中的 write_paths;若测试需要修改 core ViewModel、公共协议或构建结构,必须停止并记录,不得在 T-608 内扩大边界。
  • T-608 完成、完整验证并提交前,不落成或领取 Phase 2 审核顺序中的后续任务。

执行记录

  • 2026-07-17:根据 docs/review/phase2-review.md 交叉复核定稿的第三优先级整改落成任务;现有全局最大任务为 T-607,因此取 T-608,依赖已完成的 T-607。
  • 2026-07-17:代码图核对显示两个 drainInput 都负责 Editor、视图、分类、行、恢复和关闭控件接线,但现有 shell 测试主要直接调用 model setter;任务据此冻结“验证适配器接线而非重复 ViewModel 纯逻辑”的范围。
  • 2026-07-17:本地 go doc 确认 modern Gio v0.10.1 与 win7 Gio v0.6.0 的 widget.Clickable 都提供 Click/Clicked,layout.List.Position 都暴露 First/Offset/Count,可用同一确定性场景矩阵而不跨 workspace import。
  • 2026-07-17:在 agent/codex/T-608 分支领取任务,基线为 0705948d749722af5814ee91267cb44db6c8164c;保持单 Agent 串行执行。
  • 2026-07-17:基线 ./init.ps1 通过,包含治理/上下文/边界/依赖版本检查、Go 1.20.14 core vet/test、modern Go 1.25 与 win7 Go 1.20.14 的测试和 Windows amd64 构建。
  • 2026-07-17:modern/win7 各新增 adapter_contract_test.go,四组同名场景只在 edition 与真实窗口尺寸上不同。测试用 Clickable.Click、Editor 状态与下一帧 Layout 驱动 drainInput,并用 input.Router 语义树确认“软件目录尚未加载”“没有匹配的软件”和“显示全部软件”恢复入口确实被布局。
  • 2026-07-17:契约覆盖三个视图按钮、分类/恢复/关闭事件,重排后保留 row control 仍按 AppID 打开正确详情,关闭详情保留 query/category/view 与 list First/Offset,500 项同时以 lastRendered 和 layout.List.Position.Count 证明 viewport 子集,并验证 app/category controls 复用及删除释放。两端首轮均通过,没有发现需要修改生产 shell.go 的漂移。
  • 2026-07-17:矩阵一致性 git diff --no-index 仅显示预期的 Modern/Legacy edition 与 1080×720/1024×680 viewport 差异;modern Go 1.25.0 与 win7 Go 1.20.14 的 go test -count=10 ./ui/gio 分别通过,对应 go vet ./ui/gio 通过。
  • 2026-07-17:完整 ./scripts/verify_phase0.ps1 通过,包含治理/上下文/边界/版本校验、Go 1.20.14 core vet/test、modern Go 1.25 与 win7 Go 1.20.14 的 UI/平台测试及 Windows amd64 构建;路由、架构、审核追踪和当前状态已同步。