Files
soft_quay/docs/tasks/T-303.md
T

5.5 KiB
Raw 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-303 失败处理与磁盘预检查 3
T-302
TODO 2026-07-18 null null null null
docs/tasks/T-303.md
core/application/install/
core/installer/
docs/api.md
docs/04-architecture.md
docs/00-ai-start-here.md
docs/current-state.md

问题 / 背景

T-302 已把已验签 Catalog selection、同句柄 package 校验、严格 app.json、安全 staging 和可回滚 switch 串成无头安装 use case,但失败结果仍主要是内部错误链。调用方尚不能稳定地区分哈希不符、包损坏、可用磁盘不足和已有版本正在运行,也没有在创建 staging 前依据实际解压计划阻止空间不足的写入。

更新场景中,任何上述失败都必须保留旧 current 与其 installed-app.json;不能以错误码映射为由提前切换、删除旧版本,或把原始底层错误直接作为 UI 合约。运行状态的 Windows Toolhelp 实现和等待用户正常退出属于 T-401,本任务只建立 core 可注入的预检边界。

方案

  1. 在 core/installer 为已经通过同句柄 size/SHA、ZIP 预扫描和 app.json 身份比对的包暴露只读的 verified-package pre-extract hook。hook 提供已规划 payload 的精确展开字节数、普通文件数和已验证 entrypoint;它在任何 staging 创建或 payload 写入之前调用。保留现有无 hook 提取入口,避免把 application/平台依赖带入 installer。
  2. 将 InstallService 的构造改为显式配置并强制注入 DiskSpaceChecker 与 TargetStateChecker。pre-extract hook 对 app root 查询可用空间,并要求至少容纳 payload 展开字节数加固定 64 MiB staging/元数据保留;容量查询失败、非法返回值或可用空间不足一律 fail closed。运行检查只接受已验证的 app ID 与 current/<entrypoint> 路径;发现运行、或状态无法可靠取得时一律在 staging 前终止。本任务不启动、终止、等待或枚举进程,也不在 core import Windows API。
  3. 在 core/application/install 定义稳定 FailureCode 与带 stage/code/root cause 的安装错误。至少冻结 hash_mismatch、zip_path_escape、zip_corrupt、disk_full、disk_check_failed、app_running、target_state_unavailable、package_invalid 与兜底 install_failed;底层根因继续可由 errors.Is 识别,UI/事件只消费稳定 code。把已存在的 package/switch/health/record 错误按此表映射,不能暴露文件路径或原始系统错误作为用户合约。
  4. 为成功、精确空间阈值、空间不足、容量查询失败、运行中、运行状态查询失败、哈希不符与 ZIP/CRC 损坏补齐单元/集成测试。每个失败都断言 staging 未创建或被清理、旧 current/安装记录保持可用、错误码确定且根因仍可识别;验证通过才更新任务状态。

验收要点

  • installer 在所有 Catalog/ZIP/manifest 验证成功后、创建 staging 前,向调用方给出精确 payload bytes/files 与安全 entrypoint;hook 失败不产生 staging/payload 写入。
  • InstallService 无法在缺少 disk 或 target-state checker 时构造。它以 payload_bytes + 64 MiB 为所需空间;可用空间小于该值返回 disk_full,等于该值允许继续,查询故障返回 disk_check_failed。
  • 对已有版本更新时,hash_mismatch、zip_path_escape、zip_corrupt、disk_full、app_running 和两种 checker 故障均发生在 switch 前,旧 current 和旧 installed-app.json 字节保持不变;首次安装不留下 executable current。
  • 所有安装失败以稳定英文 FailureCode 报告,原始原因仍可被 errors.Is 检测;错误码表已写入 docs/api.md,不包含绝对路径、URL、token 或系统原始错误。
  • go -C core vet ./...、go -C core test -count=1 ./...、go -C core test -count=10 ./installer ./application/install、./scripts/verify_phase0.ps1、python scripts/validate_agent_context.py 与 python scripts/validate_harness_governance.py 全部通过;任务执行记录写明结果。

边界(不改什么)

  • 不修改 Catalog、app.json、files.json、installed-app Schema 或签名/哈希协议;不改变 T-302 同句柄验证和 switch/rollback 的先后顺序。
  • 不实现 Toolhelp 进程枚举、等待退出、强杀、启动程序、Gio 状态展示、下载重试或命令层依赖装配;T-401 负责 Windows 运行检测与启动协议,后续 UI/编排任务负责事件展示和实际装配。
  • 不以磁盘预检查替代写入时的错误处理;预检查与 extract/switch 的所有 I/O 错误仍必须 fail closed 并保留 rollback 语义。
  • 不引入第三方包、Gio、Windows API、SQLite 或 Go 1.21+ API;不做物理断电、文件锁或杀毒软件故障注入(T-601)。

协作约束

  • 当前项目为单 Agent 串行模式;当前 Agent 独占全部 write_paths,自行完成设计、安全复核、测试和提交,不启动子 Agent。
  • 先提交本任务规格与关联协议/架构/状态文档;领取后将本文件改为 DOING,填写当前 HEAD context_ref 与 work_branch: agent/codex/T-303,再运行基线和实现。
  • T-401 及任何后置任务在本任务 DONE、验证与实现提交前不得领取或提前修改。

执行记录

  • 2026-07-18:正式落成。冻结 verified-package hook、64 MiB 解压保留、强制注入 disk/target-state checker、稳定失败码及 T-401 的进程检测边界。