diff --git a/docs/00-ai-start-here.md b/docs/00-ai-start-here.md index 3f3cdb0..cb2973e 100644 --- a/docs/00-ai-start-here.md +++ b/docs/00-ai-start-here.md @@ -47,7 +47,7 @@ SoftBox 软件盒子是一个使用 Go + Gio 开发的 Windows 桌面客户端, ## 当前阶段 -当前项目已完成 Phase 0~2、T-301~T-303、T-615 与审核整改 `T-604`~`T-614`。Windows 安全路径阻断项、图标缓存资源边界、后台结果回 UI 线程的事件接线、双适配器交互契约、`VisibleItems` 快照生命周期、双端 Gio shell 职责拆分、unsafe cache 安全诊断/runbook、ZIP 中央目录/EOCD(含 ZIP64)预扫描、安装文件/目录/journal 的代码层耐久顺序、Catalog canonicalization/签名静态 corpus,以及同句柄 Catalog size/SHA→严格 app.json→staging/switch/回滚安装链均已关闭;T-303 已将 verified-package 的 staging 前磁盘/运行状态预检和稳定失败码落实到 core,T-615 已将 ZIP 输入/staging 输出 I/O 分界、平台磁盘满分类和清理失败落实到 core。T-401 已完成完整路径进程检测、受控启动和 Switcher 临界区复查;T-402 已完成子软件更新编排;T-403 已完成受限 SoftBoxUpdater、自身 EXE 健康确认与可恢复切换。物理断电、文件锁与杀毒软件干扰验证保留到 T-601 发布前环境验证。 +当前项目已完成 Phase 0~2、T-301~T-303、T-615 与审核整改 `T-604`~`T-614`。Windows 安全路径阻断项、图标缓存资源边界、后台结果回 UI 线程的事件接线、双适配器交互契约、`VisibleItems` 快照生命周期、双端 Gio shell 职责拆分、unsafe cache 安全诊断/runbook、ZIP 中央目录/EOCD(含 ZIP64)预扫描、安装文件/目录/journal 的代码层耐久顺序、Catalog canonicalization/签名静态 corpus,以及同句柄 Catalog size/SHA→严格 app.json→staging/switch/回滚安装链均已关闭;T-303 已将 verified-package 的 staging 前磁盘/运行状态预检和稳定失败码落实到 core,T-615 已将 ZIP 输入/staging 输出 I/O 分界、平台磁盘满分类和清理失败落实到 core。T-401 已完成完整路径进程检测、受控启动和 Switcher 临界区复查;T-402 已完成子软件更新编排;T-403 已完成受限 SoftBoxUpdater、自身 EXE 健康确认与可恢复切换。T-616 已正式落成,用于关闭 production cmd 未投递 Catalog 快照、导致空白/无说明空目录的缺口;物理断电、文件锁与杀毒软件干扰验证保留到 T-601 发布前环境验证。 优先路径: @@ -55,7 +55,7 @@ SoftBox 软件盒子是一个使用 Go + Gio 开发的 Windows 桌面客户端, 2. 已完成 Phase 1:清单验签、ZIP 安全解压、原子切换回滚原型。 3. 已完成 Phase 2 与 T-301:清单/列表/详情/图标缓存 + 可恢复下载队列。 4. 已完成 T-604:modern/Win7 workspace 与 Gio 版本解析彻底隔离。 -5. 已完成 T-606~T-615:图标缓存资源边界、UI 线程事件接线、双 Gio 适配器交互契约、`VisibleItems` generation 生命周期、双端 `shell.go` 同 package 镜像职责拆分、unsafe cache 诊断/人工恢复指引、ZIP 中央目录/EOCD 预扫描、安装耐久顺序、Catalog 静态签名向量,以及 staging 输出 I/O 根因与磁盘满诊断;已完成 T-302/T-303:已验签 Catalog 选择与同句柄 size/SHA、严格 app.json、安全 staging/switch/健康与记录写回滚链路,以及 staging 前磁盘/运行状态预检与稳定失败码。T-401 已完成进程检测、受控启动与切换临界区复查;T-402 已完成关闭确认、自然退出等待和更新编排;T-403 已完成 SoftBoxUpdater 的受限 transaction、PID 自然退出、固定健康启动与恢复。下一步按路线图正式落成 Phase 5 的 T-501。T-601 仍须补真实 Windows 环境的断电/干扰注入。 +5. 已完成 T-606~T-615:图标缓存资源边界、UI 线程事件接线、双 Gio 适配器交互契约、`VisibleItems` generation 生命周期、双端 `shell.go` 同 package 镜像职责拆分、unsafe cache 诊断/人工恢复指引、ZIP 中央目录/EOCD 预扫描、安装耐久顺序、Catalog 静态签名向量,以及 staging 输出 I/O 根因与磁盘满诊断;已完成 T-302/T-303:已验签 Catalog 选择与同句柄 size/SHA、严格 app.json、安全 staging/switch/健康与记录写回滚链路,以及 staging 前磁盘/运行状态预检与稳定失败码。T-401 已完成进程检测、受控启动与切换临界区复查;T-402 已完成关闭确认、自然退出等待和更新编排;T-403 已完成 SoftBoxUpdater 的受限 transaction、PID 自然退出、固定健康启动与恢复。T-616 已正式落成,当前执行 Catalog 快照启动投递与明确空态诊断;完成后再按路线图正式落成 Phase 5 的 T-501。T-601 仍须补真实 Windows 环境的断电/干扰注入。 ## 领取任务规则 diff --git a/docs/06-tasks.md b/docs/06-tasks.md index 8949aa0..17d719a 100644 --- a/docs/06-tasks.md +++ b/docs/06-tasks.md @@ -60,6 +60,12 @@ Phase 1 安全整改按 `docs/review/phase1-security-review.md` 的交叉复核 | T-203 | 主界面软件列表 | T-202, T-003 | 虚拟列表 + 搜索/分类/视图切换;控件状态按软件 ID;数百项滚动流畅;Layout 无 IO | | T-204 | 软件详情与图标缓存 | T-203 | 详情弹层;图标内存+磁盘缓存(按 DPI);断网可显示缓存图标 | +#### Phase 2 运行时装配补缺 + +| ID | 任务 | 依赖 | 验收要点 | +| --- | --- | --- | --- | +| T-616 | Catalog 启动投递与空白界面诊断 | T-204, T-607 | 后台受测 loader 将已验证的内存 Catalog 快照投递到双端 Gio shell;无真实发布配置时显示稳定未配置诊断而非无说明空区;Windows 手工首帧 smoke 仅记录可见状态,不替代 T-601 真机矩阵 | + #### Phase 2 交叉审核加固 Phase 2 整改按 `docs/review/phase2-review.md` 的交叉复核定稿顺序串行落成。T-606 已关闭正式图标接入前的并发、读取和内存边界;T-607 建立后台图标结果经 application event 回到 Gio UI goroutine 的线程契约;T-608 为两个隔离 Gio 适配器建立交互契约;T-609 修正 `VisibleItems` 快照生命周期;T-610 在不改变行为的前提下拆分双端 Gio shell 职责;T-611 已用真实 fail-closed 传播、双端安全诊断和人工 runbook 关闭最终观察项。 diff --git a/docs/current-state.md b/docs/current-state.md index 3376e0d..04ac6c5 100644 --- a/docs/current-state.md +++ b/docs/current-state.md @@ -23,14 +23,14 @@ - 标准启动路径:`./init.sh` / `./init.ps1`(同步依赖、执行完整 Phase 0 闸门、打印双目标构建命令) - 标准验证路径:`bash scripts/verify_phase0.sh` / `./scripts/verify_phase0.ps1` - 版本管理:git 已初始化,main 分支,远端 origin 为 Gitea `opc/soft_quay`;harness 文档已提交 -- 当前 blocker:可信自更新包下载/签名、版本选择、许可证策略与完整端到端 cmd/UI 编排仍未装配;不得为此执行未验证 staging 或伪装自更新闭环。下一步应按路线图正式落成 Phase 5 的 T-501。T-614 的外部 `softbox-catalog` 消费 corpus CI 证据仍需跨仓库协调;物理断电、文件锁/杀毒软件干扰仍需 T-601 的目标 Windows VM/真机故障注入 +- 当前 blocker:`dist/SoftBox.exe` 只创建空 Gio shell,尚未向 `AppShell.SetItems` 投递已验证 Catalog/cache 快照;T-616 已正式落成以补齐后台投递和稳定空态诊断。真实 Catalog URL/公钥/发布配置仍未入库,不得用 testdata、未签名本地文件或 allow-all verifier 伪装可用列表。可信自更新包下载/签名、版本选择、许可证策略与完整端到端 cmd/UI 编排也仍未装配。T-614 的外部 `softbox-catalog` 消费 corpus CI 证据仍需跨仓库协调;物理断电、文件锁/杀毒软件干扰和真实图形环境仍需 T-601 的目标 Windows VM/真机故障注入 ## 当前目录要点 | 路径 | 状态 | 说明 | | --- | --- | --- | | `docs/` | 已有 | harness coding 文档集(本次初始化完成) | -| `docs/tasks/` | 已有 | Phase 0~2、T-301~T-303、T-604~T-615、T-401~T-403 已完成 | +| `docs/tasks/` | 已有 | Phase 0~2、T-301~T-303、T-604~T-615、T-401~T-403 已完成;T-616 已正式落成,正在执行 | | `scripts/` | 已有 | harness 治理、core 边界、Go 版本检查与 Phase 0 双平台验证入口 | | `core/` | 已建 | Go 1.20 兼容;已有正式 Catalog、本地状态/存储、共享 Windows safepath、列表模型、有界并发图标缓存、图标事件/relay、可恢复下载队列与 Phase 1 安装安全原型 | | `app-modern/` | 已建 | Go 1.25.0 + Gio v0.10.1;Modern AppShell 已接入虚拟列表、详情、图标事件 drain/过期拒绝和内存 ImageOp,并拆为五类 shell 职责文件 | @@ -43,7 +43,7 @@ 任务状态以 `docs/tasks/` 各任务文件 frontmatter 的 `status` 为准。本节只写项目级摘要: - 已完成:Phase 0 的 `T-001`~`T-004`;Phase 1 的 `T-101`、`T-102`、`T-103`;Phase 2 的 `T-201`~`T-204`;Phase 3 的 `T-301`~`T-303` 与 `T-615`;审核整改 `T-604`~`T-614`;Phase 4 的 `T-401`~`T-403`。 -- 正在进行:无;下一步可按路线图正式落成 Phase 5 的 T-501。T-601 的物理断电与干扰故障注入仍保留为发布前环境验证。 +- 正在进行:T-616(依赖 T-204/T-607 已完成);完成、验证并提交后,再按路线图正式落成 Phase 5 的 T-501。T-601 的物理断电与干扰故障注入仍保留为发布前环境验证。 ## 当前可运行内容 diff --git a/docs/tasks/T-616.md b/docs/tasks/T-616.md new file mode 100644 index 0000000..ae1638a --- /dev/null +++ b/docs/tasks/T-616.md @@ -0,0 +1,65 @@ +--- +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 或伪装可用列表。