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

63 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-303
title: 失败处理与磁盘预检查
phase: 3
deps: [T-302]
status: DONE
created: 2026-07-18
issue: null
context_ref: 449b1832741bef57fd6ef9bc771d2702a9120dc5
claim_branch: null
work_branch: agent/codex/T-303
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:领取任务,基线为 `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。