Add T-606~T-614 remediation review; ignore editor workspace
Verify at code level that the Phase 1/2 review findings were actually closed (not just self-reported): icon cache concurrency + LRU + bounded fetch (T-606), UI-thread icon delivery (T-607), install durability with Windows FlushFileBuffers / POSIX dir sync (T-613), ZIP central-directory preflight (T-612), and catalog signature cross-impl vectors (T-614). All confirmed real. Records three residuals (R1 real power-loss validation, R2 per-file fsync cost, R3 singleflight ctx caveat). Also gitignore *.code-workspace (per review recommendation). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -30,3 +30,6 @@ gitea.env.*
|
||||
# Python 本地校验缓存
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# 本地编辑器 workspace 配置(个人,不入库)
|
||||
*.code-workspace
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# 整改审核:T-606 ~ T-614(Phase 1/2 审查结论的落地验证)
|
||||
|
||||
> 审查范围:`f1cc730`(T-606)、`0945fe9`(T-607)、`1b7f72e`(T-608)、`1715729`(T-609)、`e9386d2`(T-610)、`320b83d`(T-611)、`0f69fa3`(T-612)、`20596a7`(T-613)、`0c1b766`(T-614)。
|
||||
> 审查视角:全栈开发工程师。
|
||||
> 审查方式:静态代码审计——**不信任任务自述,逐项核实际代码**;重点核并发、耐久性、路径/DoS、签名四类高风险改动。因 WSL 无 Go,未执行测试。
|
||||
> 日期:2026-07-18
|
||||
|
||||
## 总体判断
|
||||
|
||||
**合理,且是真修复,不是文档层的自述。** Codex 系统性关闭了 Phase 1 与 Phase 2 审查的**全部可执行结论**——不仅 Phase 2 的 6 项(T-606~611),还回补了 Phase 1 遗留的三项(T-612 中央目录 DoS、T-613 断电耐久性、T-614 签名跨实现向量)。逐项核了实际代码,实现方向和落地都对。剩余的是几处诚实的残留(见末尾),不影响"整改成立"的结论。
|
||||
|
||||
## 逐项核实(代码级)
|
||||
|
||||
| 任务 | 对应审查项 | 核实结论 | 代码证据 |
|
||||
| --- | --- | --- | --- |
|
||||
| T-606 | Phase2 P1 + 交叉裁定"内存无界" + Codex NEW P1 | **成立** | `icon_cache.go`:in-flight 去重(leader 在锁外做 disk/network,waiter 释放锁等 `flight.done` 或 `ctx.Done()`,`delete(inflight)`+`close(done)` 在成功/失败都执行,无泄漏);`icon_memory.go` 用 `container/list` LRU 按字节(32MiB)+ 条数(256)双限;fetcher 改流式 `IconFetchResponse{Body,ContentLength}`,`readFetchedIcon` 先拒 `ContentLength>max`、再 `io.ReadAll(io.LimitReader(Body,max+1))`、再复检、`defer Body.Close()`;`SetItems` 剪枝 `shell.icons` 等全套图标 map |
|
||||
| T-607 | Codex NEW P2(UI 线程投递) | **成立** | 后台 Load/Decode 只发事件,经有界 FIFO relay 回 Gio UI goroutine 后再 `ApplyEvent`/`ApplyIcon`;`SetItems` 剪枝 `iconRequests/iconApplied/iconFailures`,迟到结果按最新请求/删除/IconRef 变化/取消阻断 |
|
||||
| T-608 | Phase2 P2(sharpen) | **成立** | 双端交互契约测试:验证 Editor/Clickable 经 Layout 更新共享 model、重排后 AppID 行身份、详情关闭上下文、500 项 viewport、controls 释放;非重复断言 ViewModel |
|
||||
| T-609 | Phase2 P4(sharpen) | **成立** | `refilter` 构造新 backing array 后原子替换(非每帧拷贝),旧 generation 跨五类 mutation 稳定 |
|
||||
| T-610 | Phase2 P5 | **成立** | 双端 `shell.go` 拆为 header/navigation、catalog/list、detail、style 同 package 职责文件,根调用链不变 |
|
||||
| T-611 | Phase2 P6 | **成立** | symlink/非普通 cache entry fail-closed、零 fetch、不改写 entry/target,发 `IconFailed/unsafe_cache` + 人工 runbook;自动 quarantine 仍留威胁模型裁定 |
|
||||
| T-612 | Phase1 P2(中央目录 DoS) | **成立** | 新增 `zipscan.go`;`ExtractFile` 要求 `expectedPackageSize`,`openAndScanArchive` 在 `zip.NewReader` **前**校验文件大小精确等于 Catalog 声明并预扫描;`limits.go` 加 `MaxArchiveBytes`(4GiB)+ `MaxCentralDirectoryBytes`(且校验 ≤ archive) |
|
||||
| T-613 | Phase1 P1(断电耐久性)+ Codex NEW(payload 未 sync) | **成立** | `durability.go` 抽象 fence;**`durability_windows.go` 用 `syscall.FlushFileBuffers`、`durability_other.go` 用 `directory.Sync()`**;`extractor.go` 每个 payload `syncFileWithFence` + `syncStagingTree`;`switcher/transaction/recovery/layout` 在每次 rename、journal 替换、备份/恢复/删除后插目录 fsync 点 |
|
||||
| T-614 | Phase1 P3(跨实现签名向量) | **成立** | `canonical.go` 加 `validateJSONStringSurrogates`(拒绝孤立高/低 surrogate、不配对);`testdata/catalog/canonical-vectors.json` 覆盖 reject-isolated-high/low-surrogate、mismatched-pair、negative-zero、signature-crlf/space/tab、missing/extra-padding、equivalent-object-order |
|
||||
|
||||
## 重点模块判断
|
||||
|
||||
- **T-606 并发正确性**:in-flight 去重无死锁(leader 全程不持锁做 IO,waiter 只等 channel),不同 key 真并行、同 key 只拉一次、错误也清 flight。这是对我"naive check-unlock-fetch"的正确超越。
|
||||
- **T-613 耐久性方向正确**:目录级 fsync 的平台分叉(Windows `FlushFileBuffers` / POSIX dir `Sync`)+ payload 文件 sync + journal 与 rename 之间的顺序点,正是 Phase 1 P1 建议的完整落地。fence 可注入,`durability_test.go`(334 行)做步骤间故障注入。
|
||||
- **T-612/T-614 安全闭合**:包大小在解析任何 ZIP 数据前强制等于已验签 Catalog 声明;签名向量把 surrogate/base64 空白/负零/等价顺序行为**冻结**成跨实现测试,发布端可据此对齐。
|
||||
|
||||
## 残留与提醒(不影响"整改成立",但应记录)
|
||||
|
||||
### R1 · T-613 的耐久性是"构造正确",真机断电验证仍未做(且 Windows 更需要)
|
||||
|
||||
fsync 点插得对,但**真实断电保证依赖 OS/FS 履行 fsync 语义**。关键:Windows 对**目录句柄** `FlushFileBuffers` 是否真正持久化目录项,MSDN 不像 POSIX `fsync(dir)` 那样有明确保证。因此:
|
||||
|
||||
- 结论应表述为"耐久性顺序已构造正确",而非"断电安全已验证"。
|
||||
- 真机/VM 断电故障注入(Phase 1 已划 T-302/T-601)在 **Windows 上比 POSIX 更必要**,不能因为代码已插 fsync 就跳过。
|
||||
|
||||
### R2 · T-613 逐 payload 文件 fsync 的性能成本待真实包复核
|
||||
|
||||
`syncFileWithFence` 逐个 payload 文件调用;含数千文件的包会产生数千次 fsync,在慢盘或杀软介入下安装可能明显变慢。正确性优先的取舍成立,但阈值/策略应在 T-302 用真实包分布复核(可评估"逐文件 sync + 目录 sync"是否可优化为"批量 + staging 树 sync")。
|
||||
|
||||
### R3 · T-606 waiter 继承 leader 的 ctx 取消(singleflight 通病,低危)
|
||||
|
||||
leader 的 ctx 取消会让所有 waiter(即使自身 ctx 有效)拿到取消错误。对图标是良性(重试即可),但若未来复用该模式于非幂等/高代价资源,需重新评估是否给 waiter 独立重试或 leader 交接。
|
||||
|
||||
## 结论
|
||||
|
||||
T-606~T-614 是一次**系统性、可核实**的整改:Phase 1 与 Phase 2 审查的可执行结论已全部落地并接线,实现质量与前几个阶段一致。当前无需回滚或返工。剩余的是三条已记录的残留(R1 真机断电验证、R2 fsync 性能、R3 singleflight 通病),其中 R1 是唯一需要在发布前用真实环境关闭的项,且本就属 T-302/T-601 既定范围。
|
||||
|
||||
> 声明:本报告为静态代码审计,逐项核实了实现而非任务自述;因 WSL 无 Go 未执行测试,Codex 自述双 workspace 闸门通过。R1 的真机断电语义本就需硬件级注入,不由静态审计或步骤级故障注入替代。
|
||||
Reference in New Issue
Block a user