aps-agent/poc/pi-fallback/P3-VALIDATION.md

16 KiB
Raw Permalink Blame History

P3-VALIDATION — 高风险场景 S4/S6/S7 + 白名单治理 最终验证报告

验证员:Agent-N · 日期:2026-09-04 · 协调板:GOAL-P3.md 硬约束遵守:未 git commit/push;Python 一律 .venv\Scripts\python.exe;LLM key 只经 server 子进程 env 从 .env 流入(不读不打印不落盘,kimi-k2.6);server 起杀单命令内完成、 超时保护、收尾无残留;临时 APS_HOME 零污染 server/data/(git status 双冒烟后均 clean); _saga_cp.json 每次跑测后 git checkout -- 还原;既有失败一律 stash 基线对照核实。 本轮未修改任何产品代码文件。

缺陷修复复证:Agent-O · 2026-09-04(§7)——FB-03-BUG-1 已修复并复证, S6 冒烟复跑 24/24,P3 判定转 GO。

0. TL;DR —— P3 判定:GO(FB-03-BUG-1 修复复证通过,§7)

条件 NO-GO → GO。修复前轮次记录:治理面(白名单 fail-closed、角色门禁、 逐笔卡、双人链、对账、审计、脱敏、攻击面)全部验证通过;但 S6 冒烟抓到一个 golden 层物理摸不到的段 C 产品缺陷(下述,已修复):

FB-03-BUG-1:S6 补录写在真实 MES 断连下 100% 失败回滚。 mes.apply_report(mes.py:1543)在本地落账之前无条件 client.post_report() 同步推送 MES;断连注入(设计 §0.8 官方手法: MES_HTTP_BASE_URL 指不可达地址)下 MesHttpError 上抛 → execute_plan 步骤异常 → 整体失败回滚。即「断连补录」场景在其定义的真实条件下,补录动作物理不可用。 golden 层全部经 MockMesClient(post_report 永远成功)+ monkeypatch seam, 结构上摸不到此路径——与 P1 冒烟 Bug A 同类的「只有真实子进程能暴露」缺陷。 这是设计层语义缺口(补录应本地落账 + 待同步标记,还是同步推送容忍失败), 非一行笔误,按硬验证约束未自行修复,留待设计/实施轮决策。

治理机制在失败面前全部正常工作(显式失败文案 + 自动回滚 + 失败现场快照 + 审计齐全) ——缺陷不扩面、不破窗,但段 C 主链路不通,故判条件 NO-GO。

1. 全量回归(分批,真实数字)

项 数字 说明
golden 全量(191 文件逐跑,可续跑驱动器 regression_driver.py) 1501 passed / 18 failed / 10 errors / 0 skipped / 0 超时 结果落盘 regression_results.jsonl(191 条逐文件记录)
stash 基线对照(9 个失败文件在 HEAD 复跑) 9/9 文件失败形态逐例一致 regression_baseline.jsonl;全部为既有失败(native sidecar 探测环境依赖 11 例:desktop_sidecar/shadow_price/sobol;folder_schedule 系列 6 例;mes_http 8 errors + mes_readiness 2+4 + trace_external_http 2 errors 等 MES/HTTP fixture 既有失败),与 P3 零相关
四文件联合(highrisk+execute+lane+feature_flags) 65 passed(复跑确认) 与 M 自验一致
攻击专项并入后五文件联合 72 passed 无跨文件污染
文档门禁(doc_drift/registry/contract_sync/openapi_schema) 25 passed 与 P2 口径一致
ruff M 的 8 文件 59 = 59 零新增(与 HEAD 多重集比对复算一致);本轮新增文件(攻击测试/驱动器/冒烟脚本)修复后攻击测试与驱动器零违规,冒烟脚本 9/7 条 ≤ s3 先例 11 条同款模式 —

异常观察(如实登记,非 P3 引入):test_cp_engine.py::test_cp_infeasible_solver_meta_ exposes_native_assumption_core 在大组合批(20 文件同进程、高负载)中 FAILED 一次, 单独跑与 13 文件组合复跑均 PASS(161 passed),未再复现;断言内容是 native 求解器 IIS 标志,P3 不触碰求解器路径,判为负载敏感的既有偶发。

2. 偏差⑦⑧ 攻击面专项(确定性测试层)

新建 tests/golden/test_fallback_p3_attack.py(7 例,全部确定性,fake runner 零网络): 7 passed;并入联合 72 passed;ruff 零违规。

# 用例 攻击面 结果
A-7-1 第二张卡信封完整 + 乱序审批(先批第二张) 偏差⑦核心回归:修复前第二张卡 100% 信封自破 PASS:两卡 verify_confirmation_envelope 均过,乱序双批全成功落账
A-7-2 伪造指纹推进(直改 beforeFingerprint 落盘,不重算信封) 旧卡伪造 PASS:信封「完整性校验失败」→ 执行拒绝,零写入
A-7-3 篡改冻结参数(progressPct 80→100 落盘) 参数伪造 PASS:paramsHash「参数摘要不一致」→ 拒绝,未按篡改值落账
A-7-4 重放已执行确认卡(同 confirmId 二次 confirm) 重放 PASS:「该确认卡已失效」,未重复落账,成功总账仅 1 条
B-8-1 双 run 交叉:执行 run A 第一笔 偏差⑧边界:跨 run 卡不得被重锚 PASS:A 兄弟卡重锚后可批;run B 卡指纹停留原值 → 漂移检测拦截(DENIED 审计在链)
B-8-2 重锚后审批窗口内制造非兄弟业务改动 偏差⑧核心攻击:非兄弟改动借重锚混过检测 PASS:被漂移检测拦下,第二笔未落账,第一笔不受影响
B-8-3 篡改非兄弟卡 runId 蹭重锚(落盘) 伪造兄弟 PASS:重锚按匹配条件推进了它(机制如实运作),但 paramsHash 破损 → 信封层物理拒绝;真兄弟卡不受影响

附带发现(防御纵深,如实登记):审批仓 transaction() 每次从磁盘 _refresh(), 纯内存篡改(不落盘)会在 decide 前被刷新抹掉——本轮首轮攻击测试按内存篡改构造时 三例「攻击」被该机制自动中和(攻击测试改写为落盘篡改后才构成真实攻击面)。内存→盘 的信任方向正确(decide 信盘不信内存)。

3. S6 真实冒烟(smoke/smoke_s6_reconcile.py,五阶段分跑)

真实 server + 真实 Pi + 真实 kimi-k2.6 + 真实 MES HTTP 适配器(断连 = 未监听端口; 恢复 = 冒烟内嵌最小假 MES HTTP 服务,真实协议在环)。现场 smoke/site4/ 保留供查验; 结构化结果 smoke/s6_results.json;原始 SSE/回复/server 日志同目录。 总计 19/24 PASS,5 个失败全部同源(FB-03-BUG-1)。

# 验收点 结果 证据
A 断连注入 PASS readiness probe connectivity=failed + MES_HTTP_CONNECT_FAILED(注:本机系统代理会劫持 httpx 本地请求包装成 UPSTREAM_ERROR,冒烟环境层 NO_PROXY 修正后如实呈现 CONNECT_FAILED)
B 断连前现场 PASS 种子 2 张已下发工单 + mesLinks ×2 + 车间导出 CSV(watcher 投 inbox)
C 断连对话 → S6 兜底 PASS ×3 intent=assistant.reply;inbox/integration-status.md 含 connectivity=failed + 「未连接」;真实 Pi 产出 scenario=S6 计划 2 步(frozen、mes.report、正确 woId 9001/9002、进度 100/60 与 CSV 一致)
D1/D2 逐笔卡 + 机器再生成摘要 PASS ×2 blocks 2 张卡 == 清单 2 项;摘要含「工单 woId=」「计划指纹 sha256:」全结构化
D3–D6 逐笔批准落账 FAIL ×4(FB-03-BUG-1) 两笔均「兜底执行失败(MesHttpError: [MES_HTTP_TIMEOUT] POST /work-orders/EXT-xxxx/reports (HTTP 504)),已自动回滚……你的数据未留下任何变更。失败现场已存档」——断连下 post_report 必抛 → 回滚。治理面工作正常:显式失败 + 回滚 + cp_before ×2/失败现场 ×2 建档
G1 断连期审计链 FAIL(同源) chain.ok=True、stage=2 齐全;exec SUCCESS=0(执行未成功,属缺陷表现而非审计缺陷)
E 恢复注入 PASS 假 MES 上线后 probe connectivity=ok
F1–F6 对账协议全链 PASS ×6 回复「对账域 2 项:一致 1 / 漂移 1 / 单边缺失 0」;报告 `
附带 probe 仍 failed 的如实回复 PASS(首轮假 MES 句柄笔误时实测到) 「MES 连接尚未恢复(探测结果:failed),对账未执行……你的数据未被改动」——H-17 语义真实链路复证
G 对照组:删白名单重发补录 PASS S6 卡 = 0、工单表逐行一致(白名单缺失 → 分类降级 P1/P2 路径,S6 入口物理关闭)
H 收尾 PASS 双端口释放、pi 零残留、git status server/data clean

冒烟脚本自身修复(环境层,非产品):假 MES handler add_header→send_header 笔误一处 (我写的设施代码,按约束修复并在此登记)。

4. S7 只读诊断冒烟(smoke/smoke_s7_ops.py)

12/12 全 PASS。 现场 smoke/site5/ 保留;结果 smoke/s7_results.json。

# 验收点 结果 证据
A ops 身份诊断(APS_AUTH_ENABLED=0 → bypass 角色含 admin ∈ S7.roles) PASS ×4 intent=assistant.reply;inbox/ops/ 四文件齐;脱敏生效:预埋 token=abc123secretTOKEN99 与 api_key=<24位> 在 logs-tail.md 中呈 ***REDACTED***、敏感串零泄漏;config-snapshot 含 features 全文 + 白名单裁决投影
B P1 草稿语义 + 只读 PASS ×3 回复「[智能兜底 · 草稿] run fb-20260904-024511-116d11」+ 真实诊断报告(引用脱敏后日志行 token=***/api_key=*** 列表格化异常项);世界指纹前后相等(050c1c6c087e);calls.jsonl 10 行(fs_read 围墙内读取,零新工具)
C 非 ops 对照(desktop planner 身份同口令) PASS 物理不可见:零新增 run 目录、回复走原话术(「我暂未识别到……对应的明确业务目标」),连入口存在都无从得知
D config.apply 双人审批链 PASS(黄金覆盖登记) H-20 确定性全覆盖(PARTIALLY_APPROVED → SOD_DENIED → 异人二批 → executionGrant → 原子替换 + .bak + 双人审计),冒烟层不重复,覆盖关系已登记 s7_results.json.acceptD
H 收尾 PASS 端口释放、pi 零残留、git clean

5. GOAL-P3 出口标准 8 项逐条

# 出口标准 结论 依据
1 P3 白名单机制(fail-closed;改白名单 = P2 确认卡) PASS H-1..H-9/H-21 全绿;冒烟对照组 G 实测「文件缺失 → S6 入口物理关闭」;A-7-2/7-3 伪造篡改被拒
2 S4 缺算法沙盒试排(草稿不碰主干) PASS(golden 层) H-10..H-12:沙盒执行前后指纹相等 + 零 WORLD_WRITE 物理断言 + 写意图混入/expected 越界拒绝;S4 真实冒烟不在设计 §9 范围(见 §6 遗留)
3 S6 集成故障补录与恢复后对账 段 A/B/D PASS;段 C FAIL(FB-03-BUG-1) → PASS(§7 复证) 修复前:冒烟 C/D1/D2/E/F 全过;D3–D6 实测断连下补录写必败回滚(同步 post_report 语义缺口)。修复后:段 C D3–D6/G1 全绿,S6 冒烟 24/24
4 S7 运维诊断入口(角色专属、只读、审计可回放) PASS H-18..H-20 + 冒烟 12/12(脱敏实测、非 ops 物理不可见实测、双人链 golden 锁定)
5 角色门禁(复用 auth,不新造权限模型) PASS server/auth 零改动;bypass(admin)/desktop(planner) 双身份实测闸 1.5 双向行为正确
6 黄金测试确定性 PASS 21/21 + 攻击专项 7/7 + 联合 72/72,全部 fake runner 零网络
7 真实冒烟(S6 全链 / S7 只读) S6 19/24(段 C 缺陷);S7 12/12 → S6 24/24(§7 复跑);S7 12/12 §3/§4/§7 逐条证据
8 文档同轮(fallback.md / harness.md / CHANGELOG) PASS 文档门禁 25 passed;CHANGELOG FB-03 条目本轮已补真实验证数字

总结论(历史现场,保留时序):P3 条件 NO-GO(Agent-N 判定)。 解除条件 = FB-03-BUG-1 修复(段 C 补录写在断连下可落账,例如本地落账 + PENDING_SYNC 待同步标记、恢复后由对账/重放闭环)+ 本冒烟 outage 阶段 D3–D6/G1 复跑转绿。该条件 已由 Agent-O 修复并复证,最终判定转 GO,见 §7;本节保留为修复前记录,不构成当前结论。

6. 未验证清单与遗留(如实登记)

  1. S4 真实冒烟未做——设计 §9 只要求 S6/S7 两个冒烟;S4 沙盒链路真实 Pi 端到端 (真实沙盒函数 + 指纹断言)未在真实子进程下验证,golden H-10..H-12 已确定性锁定。
  2. S6 段 C 修复后的复跑——缺陷修复轮需重跑 smoke_s6_reconcile.py 全五阶段 (现场构造全自动,直接可复跑)。
  3. WMS 侧补录——设计 §11.10 明确边界外,本轮未覆盖。
  4. cp_engine 组合模式偶发(§1 异常观察)——未复现,建议观察不阻断。
  5. maxItemsPerRun 截断的真实冒烟——golden H-14 锁定,真实层只测了 2 笔(未超上限)。
  6. 验证设施产物(非产品):regression_driver.py / regression_results.jsonl / regression_baseline.jsonl / smoke/smoke_s6_reconcile.py / smoke/smoke_s7_ops.py / smoke/site4 / smoke/site5 / 各 s6_*/s7_* 结果与日志文件,全部保留供查验。

7. FB-03-BUG-1 修复复证(Agent-O 收口 · 主管复核记录)

Agent-O:2026-09-04 · 收口:P3 出口标准第 3/7 项转 PASS,NO-GO 解除。 完整改动与验证记录见 docs/CHANGELOG.md 顶部「FB-03-BUG-1 修复」条目; 主管在 P4 轮复核时未重跑真实子进程冒烟,按该条目、源码差异与冒烟结果文件收口。

7.1 修复语义

mes.apply_report 新增 keyword-only offline_booking=False(默认在线路径语义逐字节不变); fallback_lane 在 S6 补录步要求 params 显式声明 offlineBooking: true,并在出卡闸与执行端 两处实时探测 _probe_mes_connectivity() == "failed"。显式声明 + 断连事实双成立后, apply_report(offline_booking=True) 跳过同步 post_report,本地落账并打 syncStatus=PENDING_SYNC 标记;确认卡摘要明示离线落账待同步。恢复后对账报告识别并呈现 待同步记录。自动补推仍为后续轮次边界。

7.2 确定性复证

新建 tests/golden/test_fallback_offline_booking.py 6 例全确定性:

  • O-1 离线成功(post_report 零调用 + PENDING_SYNC + 卡摘要明示)
  • O-2 在线路径不变(镜像报工 +1、无 syncStatus、零探测副作用)
  • O-3 出卡闸在线声明 offlineBooking 拒绝
  • O-4 执行端审批窗口内 MES 恢复 → 熔断回滚
  • O-5 PENDING_SYNC 对账呈现
  • O-6 非 bool 形态拒绝

实测 6 passed;与 highrisk/execute/lane/feature_flags/attack 联合 78 passed; 文档门禁 25 passed;ruff 与 HEAD 基线多重集比对零新增。

7.3 真实 S6 冒烟复跑(Agent-O 记录)

smoke_s6_reconcile.py 五阶段复跑 24/24 PASS(修复前 19/24)。段 C D3–D6/G1 全部转绿: 真实 Pi 按新简报协议声明 offlineBooking,两笔断连补录本地落账成功,审计与 mesLinks 打 PENDING_SYNC,恢复后对账如实呈现待同步 2 笔。现场证据保留在 poc/pi-fallback/smoke/s6_results.json(checks D3/D4/D5/D6/G1 均 ok,reconcile 含 PENDING_SYNC 2 笔与 manifest sha256)。S7 冒烟维持 12/12。

7.4 收口结论

出口标准第 3 项 PASS(§7)、第 7 项 S6 24/24 / S7 12/12;P3 判定 GO。 头部 TL;DR、§5 出口标准表与本节一致;§5 历史 NO-GO 段仅为修复前现场。