Define process and launch task (T-401)

This commit is contained in:
ila
2026-07-19 20:47:45 +08:00
parent df6c243b21
commit d0cf333394
4 changed files with 74 additions and 7 deletions
+2 -2
View File
@@ -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 进程检测与软件启动。物理断电、文件锁与杀毒软件干扰验证保留到 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 已正式落成,下一步先实现进程检测、受控启动与切换临界区复查。物理断电、文件锁与杀毒软件干扰验证保留到 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,再继续 Phase 4-6。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 与 Phase 4-6。T-601 仍须补真实 Windows 环境的断电/干扰注入。
## 领取任务规则
+1 -1
View File
@@ -95,7 +95,7 @@ Phase 3 的 T-301 → T-302 → T-303 是安全关键依赖链,任务之间保
| ID | 任务 | 依赖 | 验收要点 |
| --- | --- | --- | --- |
| T-401 | 进程检测与软件启动 | T-303, T-615 | Toolhelp 快照检测运行状态;启动前检查文件/兼容/占用;切换临界区复查运行状态;WorkingDirectory 正确 |
| T-401 | 进程检测与软件启动 | T-303, T-615 | Toolhelp 快照按完整 entrypoint 身份检测运行状态;启动前检查受控文件/兼容/授权/占用;切换临界区复查仅明确运行中映射 `app_running`;WorkingDirectory 正确 |
| T-402 | 子软件更新流程 | T-401 | 可更新识别→确认退出→更新→失败回滚仍可启动旧版;更新不触碰 data/licenses |
| T-403 | SoftBoxUpdater 盒子自更新 | T-402 | 独立 Updater 按 CLI 合约工作;更新中断可恢复;新版健康状态写入 |
+4 -4
View File
@@ -13,7 +13,7 @@
## 当前快照
- 日期:2026-07-19
- 阶段:Phase 2 已完成(T-201~T-204);Phase 3 的 T-301 可恢复下载队列、T-302 安装流程整合、T-303 失败处理/磁盘预检查与 T-615 staging 输出 I/O/磁盘满诊断整改已完成;审核整改 T-604~T-614 已完成;下一步正式落成并执行 T-401 进程检测与软件启动
- 阶段:Phase 2 已完成(T-201~T-204);Phase 3 的 T-301 可恢复下载队列、T-302 安装流程整合、T-303 失败处理/磁盘预检查与 T-615 staging 输出 I/O/磁盘满诊断整改已完成;审核整改 T-604~T-614 已完成;T-401 已正式落成,当前执行进程检测、受控启动与切换临界区复查
- 技术栈:根 Go 1.25 workspace 只纳入 core/app-modern,`app-win7/go.work` 独立纳入 core/app-win7;版本闸门证明 modern Gio v0.10.1 与 win7 Gio v0.6.0 不交叉解析
- 生产代码:core 已有 Catalog/本地状态/存储、共享 Windows 安全相对路径策略与静态跨实现 canonicalization/Ed25519 vector corpus(拒绝非法 surrogate、`-0` 和非唯一 Base64 signature,大整数保持 token)、安全 ZIP 解压/回滚原型及 T-302/T-303/T-615 安装 use case(`core/application/install.InstallService` 只取已过滤 Catalog entry + architecture,强制注入 disk/storage-failure/target-state checker;`Extractor.ExtractVerifiedFileWithCheck` 在同一普通文件句柄按 size→SHA-256→EOCD/ZIP64→严格 app.json→已规划 payload 的 staging 前预检→安全 staging 的顺序处理,空间要求为 payload+64 MiB,ZIP 输入错误与 staging 创建/write/sync/close 错误分界并保留原始 I/O 链;平台可识别的后者磁盘满返回 `disk_full`,其余输出 I/O 返回稳定 code 且不触发 switch;清理失败可观察,Recover 仅删除已验证 layout 内的残留 staging;每个实际 payload 文件 hash 写入 installed-app;health 或记录写失败经 Switcher 回滚),transaction/switch/rollback/recovery 的 journal、rename、清理经统一 fail-closed 耐久栅栏,Windows 使用目录句柄 FlushFileBuffers)、发布稳定只读 generation 的无 IO 软件列表模型、按 key in-flight + 流式有界读取 + 32 MiB/256-key LRU 的可信图标缓存、图标 Load/Decode 事件发布用例、有界 application event relay,以及默认并发 2 的持久可恢复下载队列;modern/win7 主循环已接 relay/Invalidate,AppShell 已实现搜索/分类/视图、惰性列表、详情右栏、完整图标失败 identity 生命周期与仅 `unsafe_cache` 可见的安全 locator/人工恢复提示,并按 root/header/catalog/detail/style 同 package 镜像职责拆文件
- 测试:core 覆盖 Catalog 静态 canonicalization/Ed25519 vectors、非法 surrogate/`-0`/Base64 fail-closed、列表快照 generation/零复制、SemVer/12 状态、本地安装记录、Windows dot-space/设备名/Unicode 折叠路径攻击、ZIP destination 包含性与 EOCD/ZIP64 原始包/中央目录/条目数预扫描、T-302/T-303/T-615 同句柄 package size/SHA、严格/有界 app.json、verified payload 预检 hook、容量精确阈值/故障、程序运行/状态故障、稳定安装失败码、staging write/sync/close ENOSPC 与普通输出 I/O 原因保留、CRC 输入分界、清理失败/受控恢复、payload hash 记录、Catalog 选择拒绝、transaction recovery、health/记录写失败回滚、payload/staging tree/journal/rename/rollback/recovery/cleanup 耐久顺序及错误注入、Windows 原生目录 `FlushFileBuffers`、图标并发/取消/读取边界/LRU、真实目录/symlink fail-closed 与 cache→`unsafe_cache` event、relay 背压与关闭、下载并发/暂停/取消/重试/Range/断连/恢复/事件失败与文件身份替换;两个 app 覆盖 Editor/视图/分类/行/恢复/关闭接线、500 项 viewport、AppID 控件与分类控件生命周期、详情上下文、空状态语义、UI drain 前后、图标失败身份生命周期与 `unsafe_cache` 详情语义;安装恢复矩阵保持通过
@@ -21,14 +21,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:T-615 已关闭 staging 输出 I/O 错误链、磁盘满分类和清理失败恢复语义;T-401 尚未正式落成,必须先定义其消费 T-303 的 `TargetStateChecker`、切换临界区最后复查与启动边界。T-614 的外部 `softbox-catalog` 消费 corpus CI 证据仍需跨仓库协调,但不阻止 T-401。物理断电、文件锁/杀毒软件干扰仍需 T-601 的目标 Windows VM/真机故障注入
- 当前 blocker:T-401 正在定义并实现 Toolhelp 运行状态、启动元数据/受控启动、授权注入及 `TargetStateChecker` 切换临界区复查;下载 completed 文件的生产消费、许可证策略与完整端到端编排仍不在本任务。T-614 的外部 `softbox-catalog` 消费 corpus CI 证据仍需跨仓库协调,但不阻止 T-401。物理断电、文件锁/杀毒软件干扰仍需 T-601 的目标 Windows VM/真机故障注入
## 当前目录要点
| 路径 | 状态 | 说明 |
| --- | --- | --- |
| `docs/` | 已有 | harness coding 文档集(本次初始化完成) |
| `docs/tasks/` | 已有 | Phase 0~2、T-301~T-303、T-604~T-615 已完成;下一步落成 T-401 进程检测与软件启动任务 |
| `docs/tasks/` | 已有 | Phase 0~2、T-301~T-303、T-604~T-615 已完成;T-401 已正式落成,正在执行进程检测与软件启动任务 |
| `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 职责文件 |
@@ -42,7 +42,7 @@
- 已完成: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`。
- 正在进行:无。
- 下一个动作:正式落成 T-401(其依赖 T-303、T-615 均已完成),然后按单 Agent 流程领取执行。T-601 的物理断电与干扰故障注入仍保留为发布前环境验证。
- 正在准备领取:T-401(其依赖 T-303、T-615 均已完成);完成并提交后才可正式落成 T-402。T-601 的物理断电与干扰故障注入仍保留为发布前环境验证。
## 当前可运行内容
+67
View File
@@ -0,0 +1,67 @@
---
id: T-401
title: 进程检测、受控启动与切换临界区复查
phase: 4
deps: [T-303, T-615]
status: TODO
created: 2026-07-19
issue: null
context_ref: null
claim_branch: null
work_branch: null
write_paths:
- docs/tasks/T-401.md
- core/application/install/
- core/application/launch/
- core/installer/
- core/storage/
- app-modern/platform/windows/
- app-win7/platform/windows/
- app-modern/cmd/softbox/
- app-win7/cmd/softbox/
- docs/api.md
- docs/04-architecture.md
- docs/00-ai-start-here.md
- docs/06-tasks.md
- docs/current-state.md
- schemas/installed-app.schema.json
---
## 问题 / 背景
T-303 已定义 `TargetStateChecker` 并在 staging 前拒绝运行中的旧版本,但当前只有测试构造者;两个 `platform/windows` 仅返回 edition,未实现 Toolhelp 进程快照,也没有启动器。更重要的是,解压结束到 `current → backup` 之间仍可能启动旧版本。Phase 3 交叉复核要求在 rename 紧邻前显式复查;只有该检查明确返回运行中,才可映射 `app_running`,不得把权限、杀毒或目录错误的 rename 失败误归因。
当前 `installed-app.json` 只有 ID、版本和 payload files,未保留已验证 entrypoint、working directory、min_os 与 requires_admin;因此启动器不能在脱离 Catalog/下载任务时从本地可信记录安全推导启动路径,也不能做系统兼容与 elevation 预检。Gio shell 目前只展示“实际操作将在后续用例接入”,命令层也尚未装配安装或启动工作流;本任务必须如实保持这一现实,不能因此把未完成的下载→安装消费链或授权实现伪装为已完成。
## 方案
1. 在两个 `platform/windows` 增加相同的进程与启动适配边界。Windows 实现以 Toolhelp32 进程快照枚举并以规范化的绝对 entrypoint 身份匹配,不按可碰撞的 exe basename 匹配;通过内部 snapshot seam 覆盖枚举、条目和错误。非 Windows stub 对运行状态与启动返回明确“不支持/不可用”错误,绝不把无法检测伪装为“不在运行”。启动实现只执行已验证的绝对 EXE,显式设置 working directory,不经 shell、URL、PATH 搜索或任意 UI 字符串拼接;需要 elevation 时由 Windows 平台边界按既定 `requires_admin` 语义处理。
2. 扩展 `installed-app.json` v1 的可选启动元数据(`entrypoint`、`working_directory`、`min_os`、`requires_admin`):新安装必须从已比对的 Catalog/app manifest 写入并严格复用安全相对路径与已知 OS/布尔规则;旧 v1 记录保持可读,但没有完整启动元数据时启动 fail closed,不臆测默认 EXE 或工作目录。同步 schema、storage 校验、T-302 写记录路径和文档。
3. 新建纯 core 的 `application/launch` use case,只通过明确接口读取本地记录/受控 current 路径、检查系统兼容、授权和当前运行状态,再调用平台 launcher。它必须验证 `current`/working directory 为真实受控目录、entrypoint 为普通非 symlink 文件且仍位于 current 内;启动请求只含 app ID,不能接受任意 exe/path/args。授权是必需注入边界,T-401 只定义/消费它,不实现许可证策略、更不能使用 allow-all 生产实现。稳定 launch 结果码、错误和 `AppStarted` 事件只携带安全的 app ID/PID/码,原始错误留给后台诊断。
4. `InstallService` 显式消费既有 `TargetStateChecker`,通过 installer 的可注入 pre-switch hook 在存在旧 `current` 时、`current → backup` rename 紧邻前复查。明确返回运行中时清理本次 staging 并返回 `app_running`;检测错误返回 `target_state_unavailable`;其他 rename 错误仍保持原有 switch/rollback 归因。首次安装没有旧 current 时不执行第二次检查。这个 hook 不 import Windows API,也不等待、强杀或启动进程。
5. 两端 cmd 只装配可复用的 platform/core 启动依赖与后台提交边界,Gio Layout 仅提交 app ID,不做磁盘、进程或启动 I/O。若现有命令缺少 Catalog/许可证/下载消费的生产源,必须保留显式未装配状态并在 `current-state.md` 记录,不能伪称端到端闭环;T-402 只在 T-401 完整验证和提交后再落成。
## 验收要点
- Toolhelp 适配在 Windows 以完整 entrypoint 身份判断运行状态;snapshot 创建、迭代或路径查询失败可由调用者识别,并在 core 映射 `target_state_unavailable`。两个 workspace 均有相同 public contract、Windows build 与非 Windows stub 测试。
- 解压期间第二次检查发现旧 current 正在运行时,安装返回 `InstallStageSwitch` + `app_running`,旧 `current` 与 `installed-app.json` 字节不变,本次 staging/journal 被安全清理;第二次检查故障返回 `target_state_unavailable`。首次安装只走 staging 前检查。
- 新安装写入完整启动元数据;缺失/非法元数据、unsafe current/entrypoint、缺文件、系统不兼容、未授权、已运行与启动器失败均有稳定 launch 结果且不启动任何进程。启动器接收的 entrypoint/working directory 必须是 current 内的绝对路径;测试证明不调用 shell/PATH 且工作目录正确。
- 授权、兼容、进程和启动 I/O 均在后台 use case/平台层;Gio Layout 不做 I/O。`AppStarted` 只使用 app ID/PID,UI 不显示 raw error。没有真实许可证实现时,cmd 不得注入 allow-all 或宣称授权闭环完成。
- `go -C core vet ./...`、`go -C core test -count=1 ./...`、`go -C core test -count=10 ./application/install ./application/launch ./installer`、两个 Windows 交叉编译、`./scripts/verify_phase0.ps1`、`python scripts/validate_agent_context.py` 与 `python scripts/validate_harness_governance.py` 全部通过;执行记录写明是否存在尚未装配的真实 Catalog/许可证/下载消费来源。
## 边界(不改什么)
- 不实现下载 completed 文件的安全消费、失败保留或删除协议,不让 `InstallService` 删除任意 `DownloadPath`(O3 留给后续正式下载→安装编排)。
- 不实现等待退出、提示保存、超时、强杀、命名管道 `prepare_update/ready` 或物理 Windows 文件锁结论;前四项属于后续更新协议,锁/杀毒/断电真机验证属于 T-601。
- 不实现许可证签发、机器指纹、试用、导入或 allow-all 授权策略;这些属于 T-501~T-503。不得修改 Catalog、package、下载任务协议或 Gio 版本/Go 工具链。
- 不将 Windows API、Gio、SQLite 或第三方依赖引入 core;不执行 package 内任意脚本,不开放 UI/CLI 传入任意 exe、路径、参数或 shell command。
## 协作约束
- 当前项目为单 Agent 串行模式;当前 Agent 独占全部 `write_paths`,自行完成设计、安全复核、测试和提交,不启动子 Agent。
- 先提交本任务规格及路线图/状态文档;领取后将本文件改为 `DOING`,填写当前 HEAD `context_ref` 与 `work_branch: agent/codex/T-401`,再运行基线和实现。
- T-402 仅在本任务 `DONE`、验证和实现提交后再正式落成;若生产 cmd 仍无可信 Catalog/许可证/下载消费装配,必须在状态文档中明确其非闭环事实而非擅自扩展本任务。
## 执行记录
- 2026-07-19:正式落成。依据 Phase 3 交叉复核冻结 Toolhelp 身份匹配、启动元数据、受控启动、授权注入和 switch 临界区复查;明确 O3、退出协议、许可证策略与 T-601 真机验证的边界。