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

63 lines
6.8 KiB
Markdown
Raw Normal View History

2026-07-18 18:04:01 +08:00
---
id: T-303
title: 失败处理与磁盘预检查
phase: 3
deps: [T-302]
2026-07-18 18:14:25 +08:00
status: DONE
2026-07-18 18:04:01 +08:00
created: 2026-07-18
issue: null
2026-07-18 18:14:25 +08:00
context_ref: 449b1832741bef57fd6ef9bc771d2702a9120dc5
2026-07-18 18:04:01 +08:00
claim_branch: null
2026-07-18 18:14:25 +08:00
work_branch: agent/codex/T-303
2026-07-18 18:04:01 +08:00
write_paths:
- 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 的进程检测边界。
2026-07-18 18:14:25 +08:00
- 2026-07-18:领取任务,基线为 `449b1832741bef57fd6ef9bc771d2702a9120dc5`,工作分支 `agent/codex/T-303`;下一步运行统一初始化/完整基线,再开始实现。
- 2026-07-18:基线通过:`./init.ps1` 完成治理、core 架构/Go 版本闸门、Go 1.20 core vet/test、modern/Win7 test/build 与 Python harness 校验。
- 2026-07-18:实现 verified-package pre-extract hook(仅暴露已验证 payload bytes/files/entrypoint)和 `InstallServiceConfig` 的强制 disk/target-state 注入;预检在严格 ZIP/app manifest 验证后、staging 创建前执行,空间阈值固定为 payload 加 64 MiB。稳定 `FailureCode` 保留原始 `errors.Is` 原因,未引入 Windows API 或命令层装配。
- 2026-07-18:复核成功、精确容量阈值、首次/更新磁盘不足、磁盘/运行状态查询故障、运行中、哈希不符、CRC 损坏、hook 顺序及旧版本/记录保护;`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` 全部通过。Windows Toolhelp/正常退出等待和命令层实际装配仍保留给 T-401。