66 lines
6.1 KiB
Markdown
66 lines
6.1 KiB
Markdown
---
|
||
id: T-616
|
||
title: Catalog 启动投递与空白界面诊断
|
||
phase: 2
|
||
deps: [T-204, T-607]
|
||
status: TODO
|
||
created: 2026-07-19
|
||
issue: null
|
||
context_ref: null
|
||
claim_branch: null
|
||
work_branch: null
|
||
write_paths:
|
||
- docs/tasks/T-616.md
|
||
- core/application/catalog_bootstrap.go
|
||
- core/application/catalog_bootstrap_test.go
|
||
- app-modern/cmd/softbox/
|
||
- app-win7/cmd/softbox/
|
||
- app-modern/ui/gio/
|
||
- app-win7/ui/gio/
|
||
- docs/00-ai-start-here.md
|
||
- docs/04-architecture.md
|
||
- docs/06-tasks.md
|
||
- docs/api.md
|
||
- docs/routes.md
|
||
- docs/current-state.md
|
||
- docs/testing/windows-ui-smoke.md
|
||
---
|
||
|
||
## 问题 / 背景
|
||
|
||
`dist/SoftBox.exe` 的入口只创建空 `AppShell`,未装配 Catalog client/cache、也未向 `AppShell.SetItems` 投递快照;生产调用点不存在。因此软件目录永久为空。空目录仍应显示完整 shell 和明确状态,但当前 `-H=windowsgui` 构建隐藏 stdout/stderr,用户看到白色/空白窗口时无法区分“没有可信 Catalog 来源”与 Gio 首帧渲染故障。现有测试只在内存 `layout.Context` 中验证布局和图标事件,不是 Windows 真机 GPU 首帧证据。
|
||
|
||
仓库当前没有可入库的真实 Catalog HTTPS URL、Ed25519 公钥或发布配置。不能用 testdata、allow-all verifier、未签名本地文件或环境变量临时拼装成生产来源;这样会破坏 T-201 的签名/缓存信任边界。
|
||
|
||
## 方案
|
||
|
||
1. 在纯 Go 1.20 的 `core/application` 新增窄 `CatalogSnapshotLoader`、不可变 `CatalogSnapshot` 和 `CatalogBootstrap`。后台 bootstrap 只调用注入 loader,并通过现有 runtime 发布 `CatalogRefreshed`(带已准备 `CatalogListItem` 快照)或 `CatalogRejected`(只带稳定 `catalog_source_unconfigured` / `catalog_load_failed` 代码);它不 import Gio、Windows、网络、存储或 `catalog` 实现,且不把 raw error/URL/签名材料放进 UI payload。
|
||
2. 两端 `cmd/softbox` 在 event pump 建好后启动 bootstrap,且为没有正式发布配置的当前发行物明确注入 fail-closed 的 `catalog_source_unconfigured` loader。为以后可信装配保留受测的 `runWithCatalogLoader` composition seam;未来只能把已验签、目标过滤后的 T-201 Catalog/cache 转成 `CatalogSnapshot` 后注入,不能绕过 verifier/cache 或让 UI 读取文件/网络。
|
||
3. 两端 Gio shell 在 UI goroutine 的 `ApplyEvent` 严格解析 Catalog payload:刷新事件用新快照调用 `SetItems`,拒绝事件只更新最小的启动状态。空列表区须明确区分“正在加载”“来源尚未配置”“验证/加载失败”“已加载但空 Catalog”“筛选无结果”;页面保留 header、导航和 footer,绝不显示 raw error、URL、文件路径或密钥信息。Layout 继续只读取内存状态。
|
||
4. 固定 API/架构/路由文档中的 payload、信任边界和当前不含真实 Catalog 来源的事实。新增 Windows 手工 UI smoke runbook:从 `dist/SoftBox.exe` 验证首帧标题、搜索、导航与“来源未配置”诊断可见;它记录观察步骤而不把人工视觉检查伪装成 CI/GPU 结论。T-601 仍负责真实 Win7/图形环境矩阵。
|
||
5. core 测试覆盖成功快照的深拷贝/事件、未配置/加载失败的稳定代码、context/发布失败;两端 UI contract 测试覆盖 event→`SetItems`、四种空态和未知/错误 payload fail closed;cmd composition test 证明 loader 只在后台启动一次且通过 relay 更新 UI。验证脚本继续构建双端主程序。
|
||
|
||
## 验收要点
|
||
|
||
- `CatalogBootstrap` 只接受完整有效的内存快照,发布成功/失败均保留错误链供后台观察,UI 只收到稳定公开代码;nil loader、非法 payload、取消和 runtime/relay 关闭 fail closed,不发布伪造列表。
|
||
- 成功刷新后双端 shell 显示 loader 注入的 `CatalogListItem`,保留既有搜索/分类/选择/图标生命周期;错误或未配置不会清除已成功显示的快照,也不会让 Layout 进行 I/O。
|
||
- 默认 `dist/SoftBox.exe` 不使用 testdata、URL、环境变量、假公钥或 allow-all verifier;没有正式可信来源时稳定显示“Catalog 来源尚未配置”而非白色/无说明空区,并在文档如实说明无法显示真实软件列表的原因。
|
||
- API/架构/路由与 Windows UI smoke runbook 对齐;手工 smoke 只验证 UI 可见诊断,不声明 GPU、RDP、杀毒或 Win7 真机兼容已经由自动化证明。
|
||
- `go -C core vet ./...`、`go -C core test -count=1 ./...`、两个 app 的全包测试、两个 Windows amd64 主程序构建、`./scripts/verify_phase0.ps1`、`python scripts/validate_agent_context.py` 与 `python scripts/validate_harness_governance.py` 全部通过。
|
||
|
||
## 边界(不改什么)
|
||
|
||
- 不引入真实 Catalog URL、公钥、私钥、证书、环境变量协议、未签名本地文件、testdata 生产回退或 allow-all verifier;不实现 Catalog 发布、下载、安装、授权、图标网络请求或更新按钮。
|
||
- 不修改 T-201 验签/缓存语义、manifest/schema、installed-app 扫描、UI 布局风格、Gio/Go 版本或 Windows 图形后端;不把手工 smoke 当作 T-601/T-602 的真机矩阵结论。
|
||
- 不在 Layout 做文件/网络/哈希,也不让后台 goroutine 改 shell;不自动收集截图、启动外部 shell、写日志中的敏感 URL/密钥或改变 `data/`、`licenses/`。
|
||
|
||
## 协作约束
|
||
|
||
- 当前项目为单 Agent 串行模式;当前 Agent 独占全部 `write_paths`,自行完成规格、实现、测试、审查、状态更新和提交,不启动子 Agent。
|
||
- 先提交本任务规格和项目快照;领取后将本文件改为 `DOING`,填写当前 HEAD 的 `context_ref` 与 `work_branch: agent/codex/T-616`,再重跑基线。
|
||
- T-501 仍是 Phase 5 的下一条路线图任务;T-616 仅关闭已证实的 Phase 2 production composition/诊断缺口,不改变授权任务依赖或假定真实发布配置已经存在。
|
||
|
||
## 执行记录
|
||
|
||
- 2026-07-19:正式落成。根据 `dist/SoftBox.exe` 白色/空白界面诊断,冻结“受测后台 Catalog 快照投递 + UI 明确空态”的最小闭环;明确当前无可信发布配置时默认发行物必须 fail closed 并说明原因,而不是读取 testdata 或伪装可用列表。
|