按全栈视角审核脚手架/签名/传输/Call/验收,记录达标判定与分级整改项 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
8.1 KiB
Phase 0 代码评审 · 脚手架与契约骨架(T-001~T-005)
- 评审人:Claude(全栈视角)
- 日期:2026-07-06
- 范围:
tasks.mdPhase 0 全部任务 T-001~T-005,对应docs/05阶段 0 - 方法:静态代码审读 + git 历史核对。本环境离线无 go 1.24 工具链,未能动态跑
go build/test;涉及运行时行为处已标注"未动态复验"。
结论(Gate 判定)
Phase 0 未通过验收门槛(有条件达标)。
T-001~T-004 的设计与实现质量良好、分层清晰、测试到位。但 T-005 及其修复代码整体未提交,导致仓库层面无法复现"Go 侧真实握手成功",违反看板自身的"DONE 需可复现证据 + clean-state"规则;且传输层存在生产阻断项(不支持 https、未处理 gzip)。
| 任务 | 达标判定 | 说明 |
|---|---|---|
| T-001 骨架 | ✅ 达标 | go module + 双 mode + viper config + 占位示例,测试覆盖 mode 解析/配置加载 |
| T-002 签名 | ✅ 达标 | MD5 正确、向量与 Python 一致、ask 不进 headers/日志 |
| T-003 传输(HEAD 版) | ✅ 达标(但已被工作区改写取代) | 提交版是干净 net/http + SOCKS5、无拟态头 |
| T-004 Call/codes/envelope | ✅ 达标(有小瑕疵) | 信封/判码/路径正确,测试充分;Envelope 顶层 BaseInfo 冗余 |
| T-005 验收 | ❌ 不达标(仓库层面) | 代码全部未提交;HEAD 无法复现验收;传输层 gzip/https/死代码 |
P1 · 阻断项(必须先解决)
P1-1 T-005 代码整体未提交,仓库与"DONE"不符
tasks.md/progress.md/docs/05 均标 T-005 DONE、里程碑 M1"真实握手成功"已宣告,但以下文件全部停留在工作区未入库(HEAD 停在 T-004 2a77a4d):
M main.go (新增 -verify-jkda-id-card 入口)
M osi/transport.go (改写为裸 HTTP/1.1,+110 行)
M config/config.go (OSI_* 环境变量绑定)
M osi/transport_test.go
?? verify_jkda.go verify_jkda_test.go config/env_test.go
后果:从干净检出 git checkout HEAD 拿到的是 T-004 的 net/http 传输层——正是 progress 记录里"连真机报 EOF"的那一版。也就是说,仓库里的可复现实现不满足 T-005 验收,通过验收的证据只存在于一份未提交的工作区。按看板规则(标 DONE 前须有可运行证据入库 + 过 clean-state 检查),T-005 未真正完成。
整改:把上述文件作为 T-005 的独立 commit 提交;或在提交前先撤回 T-003/004/005 的 DONE 标记。二选一,不能让"文档说完成、仓库无实现"的漂移留存。
P1-2 传输层仅支持 http,https 完全不可用
osi/transport.go(工作区版)第 63-65 行:if target.Scheme != "http" { return ...unsupported },且请求是明文写裸 TCP conn(无 TLS)。沙箱是 http 能过,但生产 OSI 若为 https,此传输层直接无法连接。这是被裸写方案引入的能力倒退——HEAD 的 net/http 版本反而天然支持 https。
整改:在 Phase 0 收口前至少 fail-fast 明确报错并登记为"生产前必须解决"任务;理想是让 https 走 net/http、仅对需要保头大小写的 http 明文路径用裸写。
P1-3 声明 gzip 却不解压(真机一旦压缩即解析失败)
裸写请求固定发送 Accept-Encoding: gzip, deflate, br(第 110 行默认值),但响应用 http.ReadResponse + io.ReadAll 直接读——http.ReadResponse 不会自动解压(自动解压只发生在 http.Transport 自己加 gzip 头时)。当前能跑仅因沙箱返回未压缩;一旦服务端/代理按声明返回 Content-Encoding: gzip,json.Unmarshal 会拿到压缩字节而失败。未动态复验,但逻辑上是确定的定时炸弹。
整改:要么不声明压缩(发 Accept-Encoding: identity),要么按 Content-Encoding 真解压。Python requests 是自动解压的,照抄它的头却不照抄它的解压是半截移植。
P2 · 重要(尽快处理)
P2-1 t.client/roundTripper 是死代码
工作区 NewTransport 仍构造 roundTripper 和 http.Client 存入 t.client(第 37-50 行),并在其上接了 SOCKS5 DialContext——但裸写版 PostJSON 从头到尾只用 t.dialer,t.client 与 roundTripper 上的代理接线全部不被执行。初级维护者会被"这里有个 http.Client 却什么都不做"严重误导,也埋下"改了 client 以为生效实则没用"的坑。
整改:删除 t.client/roundTripper 构造,只保留 dialer+timeout;或反过来回到 net/http 由 client 承载代理。二者留一,不要并存。
P2-2 裸写方案的根因未定论,且立论未被"真机级"验证
progress 记"net/http 规范化头名 → EOF"。但 servlet 的 getHeader 本就大小写不敏感,"头名大小写导致 EOF"的因果并不牢靠,EOF 更可能来自代理/keep-alive/Content-Length 等。头大小写保留本身有测试(transport_test.go:90-122 裸 TCP 断言 \r\norgCode:,这点做得好),但"保留大小写才能连上真机"这个因果没有留下失败/成功对照的抓包证据。
整改:在 progress 或本目录补一份"net/http 版失败请求 vs 裸写版成功请求"的抓包/头部对照,坐实根因;否则这段重量级 hack 的存续缺乏依据,后续无人敢动。
P2-3 验收入口把真实身份证放上命令行
-verify-jkda-id-card <身份证> 会让真实身份证进入 shell history、ps 进程列表、init.sh 回显。属 PII 泄露面,与项目安全红线(不落真实身份证)相抵。
整改:改从环境变量或 stdin 读取待查身份证,命令行不接收 PII。
P3 · 建议(可排期)
contract.Envelope顶层BaseInfo字段冗余:真实契约里baseInfo只存在于uploadinfo内,顶层这个BaseInfo any(envelope.go:6)是早期"查询发裸 baseInfo"误解的残留,留着易被误用。建议删除。Client.Call对 nil transport 静默兜底(client.go:52-58):自动建一个无代理传输,真机(内网 host 必须走代理)会连不上却不报配置缺失。建议 nil 时直接报错,逼调用方显式注入。- UA 伪装
python-requests/2.32.4(transport.go:109 默认值):与"去掉网页拟态头"的设计取向轻微冲突,且写死版本号。若真机不校验 UA,建议用中性chis_osi/<ver>;若校验,注释写清依据。 init.sh在本机 Git Bash 跑不通(progress T-005 记:标准库路径/构建缓存权限异常)。统一验证入口在主力开发机上无法运行,等于形同虚设,建议要么修好要么在current-state显著标注"本机用 PowerShell 等价命令"。
做得好的地方(保持)
- 签名层干净正确:
SignPassword与 Pythonhashlib向量一致(008ace...),ask严格不进 headers。 - 判码按去前导零 ==
"1"实现,正确兼容实测"01";405归可重试;HTTP 5xx/429 归可重试——与docs/01 §1、docs/04 §6对齐。 - 信封结构与
docs/04 §8实测契约一致(serviceId+uploadinfo{baseInfo,manageInfo},operateUnit缺省回落orgCode)。 - 测试覆盖到位:签名向量、请求头大小写(裸 TCP)、信封字段、成功/405 分支、时间戳 13 位、URL 拼接、env 覆盖。
- 配置:
config.yaml.example全占位无密钥;OSI_*环境变量覆盖;真实config.yaml已 gitignore。
收口所需动作(建议作为 Phase 0 补完任务)
- [P1-1] 提交 T-005 全部代码为独立 commit,或撤回 DONE 标记(二选一)。
- [P1-3] 传输层去掉 gzip 声明或实现解压。
- [P1-2] https 支持或 fail-fast + 登记生产前任务。
- [P2-1] 删除
t.client死代码。 - [P2-3] 验收身份证改走 env/stdin。
- [P2-2] 补根因抓包对照。
- [P3] 删
Envelope.BaseInfo、nil-transport 改报错、UA 处理、init.sh 说明。
完成 1
3 后,Phase 0 方可视为真正达标、里程碑 M1 成立;47 可并入 T-201 之前的一轮小整改。