aps-agent/poc/pi-fallback/P4-P5-AUDIT.md

118 lines
13 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.

# Pi Agent 兜底 P4/P5 独立审计报告(Agent-F)
> 审计员:Agent-F(独立审计)· 日期:2026-09-04
> 范围:当前仓库 P4/P5 现状核对,不改产品代码。
> 验证方式:只读源码/文档核对 + `.venv\Scripts\python.exe -m pytest` 定向 6 文件,
> 未跑全量 golden。审计只新增本文件,未 commit/push。
## 1. Git/工作区基线(已核实)
| 项 | 核实结果 |
|---|---|
| HEAD | `35131cde8855812368199530d857b8e81d34dded`(`main@35131cd`,与 origin/main 同步,未另建 fallback 分支) |
| 已提交前序 | P1 `3543208`;P2 `967ae37` + 验证设施 `801725b`(`git log` 已核实) |
| P3 提交态 | **未提交**。工作区含 P3 产品/验证改动:`fallback_lane.py`、`fallback_verify.py`、`fallback_highrisk.py`、`harness.py`、`mes.py`、`workflow.py`、`pi_bridge.py`、对应 golden 测试、P3 文档、冒烟/回归设施均 dirty/untracked |
| features.json | `server/data/features.json` 无 `fallback` 键;`feature_flags.py` `_DEFAULT_OFF_KEYS={"fallback"}`;文件缺失/损坏/非 bool 均回退 fallback=False;`/api/features` 暴露 `defaultOff` |
| Pi runtime | `poc/pi-fallback/runtime/node_modules/@mariozechner/pi-coding-agent/package.json` 为 `0.73.0`;CLI 实存于 `.../dist/cli.js`;`node_modules/` 被 `.gitignore` 忽略,git 只跟踪 runtime 的 `package.json`/`package-lock.json` |
| 产品默认路径 | `FallbackConfig.from_env()` 仍硬编码仓库根 `poc/pi-fallback/runtime/node_modules/@mariozechner/pi-coding-agent/dist/cli.js` |
| 定向验证 | 6 个兜底专项文件定向跑测 **78 passed**(fallback_lane 16 / execute 22 / highrisk 21 / p3_attack 7 / offline_booking 6 / feature_flags 6),1 个既有 Starlette 弃用 warning |
## 2. P4 质量指标现状
**现有可拿到的单次运行证据(不能算指标系统)**
- 每次 propose 有 `events.jsonl`、`orchestrator.log`、`result.json`、`outbox/report.md`、`calls.jsonl`;
执行路径另有 `execution.jsonl` / `execution.events.jsonl`、checkpoint 成对快照与 verify 报告。
- `FallbackOutcome` 已记录总步数、输出字节、总耗时、`stopReason`、`error_message`、runDir。
- 完成审计 rationale 已带 `runId`、queryDigest、`stopReason`、`steps`、`elapsedSec`、citation 计数、reportPath。
- 步骤/TOOL 审计 actor 明确为 `pi-fallback:<runId>`;完成审计 actor 为发起 actor;GATE/审批链均有 requester/decidedBy/approvalStep。
- 失败原因粒度已足够:`unavailable:*`、`breaker:*`、`forged_citation`、`error:empty_report`、`plan_invalid`、`reconcile_not_ready` 等。
**P4 方案要求但缺失的**
- 无 `tests/golden/test_fallback_p4_quality.py`、无 P4 质量 corpus(“30+ 场景”)与成功/失败基线。
- 无成功率、误写率、确认轮次、token 成本四指标的聚合/导出入口;目前只有逐 run 审计与原始日志。
- 无 per-step 耗时:`execution.jsonl` 的 `step_executed` / `sandbox_step_executed` 只有 seq/intent/auditTarget,没有起止时间戳;只有 run 总耗时。
- 确认轮次没有与 fallback run 关联的统计器:审批仓 history 有 `dwellMs`、`waitingMs`、approvals 可溯源,但没有 fallback 维度 join/聚合,也没有“驳回后重新出卡轮次”指标。
- Pi 事件流中的 usage/token/cost 未被解析;目前只有 `output_bytes` 近似,代码注释与 fallback.md 也自认 token 预算未做。
- 无兜底触发率周报(方案 F9)和成本告警(方案 F4 的日预算/audit_alerts)。
## 3. 注入防护现状(P1/P2/P3 已覆盖 vs ≥20 例缺口)
### 已落确定性/真实复证的具体覆盖
1. `tests/golden/test_fallback_lane.py`(P1/P2 基础墙):
- `test_unregistered_intent_still_denied`
- `test_forged_callid_rejected`
- `test_fs_read_path_escape_blocked`
- `test_write_guard_*`(模板/只读/写面圈禁)
- `test_breaker_timeout_explicit_failure` / `test_breaker_max_steps`
2. `tests/golden/test_fallback_execute.py`(P2 E 系列与计划锁攻击):
- E-1:`test_plan_with_p3_intent_refused`、`test_plan_with_unregistered_intent_refused`
- E-2/E-3/E-4:`test_assisted_out_of_plan_tool_trips_breaker_and_rolls_back`、`test_assisted_params_out_of_bounds_trips_breaker`、`test_assisted_extra_step_trips_breaker`
- E-5:`test_injection_pi_claims_user_confirmed`
- E-6:`test_world_drift_between_stage_and_approve_refused`、`test_forged_plan_fingerprint_refused`
- E-7:`test_injection_brief_wraps_untrusted_data`
- 相邻:`test_plan_artifact_digest_mismatch_refused`、`test_confirm_card_expired`、`test_readonly_mode_tool_map_unchanged`
3. `tests/golden/test_fallback_highrisk.py`(P3 H-1..H-21):白名单缺失/损坏/未知键/未知字段/未登记 intent 全拒、P3 意图默认拒绝、审批窗口改白名单拒绝、S4 写意图/越界拒绝、S6/S7 治理链。这类主要是治理/攻击回归,不是 prompt 注入 corpus。
4. `tests/golden/test_fallback_p3_attack.py`(A-7/B-8 共 7 例):乱序双批信封完整性、伪造指纹、篡改冻结参数、重放、跨 run 重锚隔离、非兄弟漂移、伪造兄弟 runId。
5. `tests/golden/test_fallback_offline_booking.py`(O-1..O-6):离线落账滥用/形态拒绝、PENDING_SYNC 呈现;属于离线滥用门禁,不是 prompt 注入。
6. PoC 真实子进程剧本(非 golden):`poc/pi-fallback/tests/attack_path_escape.py`、`attack_bash_whitelist.py`、`attack_runaway.py`、`attack_forged_callid.py`、`attack_p2_writegate.py`;P2-VALIDATION 报告 21/21,P3 smoke 亦复证。
### 距离“≥20 例统一注入集”的缺口
- **不存在 `tests/golden/test_fallback_p4_injection.py`,也不存在方案 P4 要求的 20 例可复算清单**。
- 若把恶意模型/计划偏离/篡改/围栏类测试函数全部合算,数量接近 20+,但这是多个用途的混合集,不是统一的“用户可控输入藏指令/prompt 注入”黄金集;纯 named prompt-injection 用例目前只有 E-5/E-7 及 P3 七例攻击类,无法宣称满足方案口径。
- **用户文件进 run inbox 尚未产品化**:S3/S6 冒烟与攻击 c 都是 watcher/脚本把 CSV 投进新建 run 的 `inbox/`;P2-VALIDATION §6 已明确这是“验证设施,不是产品能力声明”。因此“工单备注藏指令/CSV 藏指令/文件名/附件元数据”的端到端注入面只能模拟,不能作为产品验收。
- 尚无统一的场景矩阵覆盖:CSV/工单备注、文件名与路径、历史会话注入、伪造“用户已确认”、伪造审批/动作文件、跨 run/跨租户重放、引用伪造成果、输出契约 partial/failed/blocked 绕过、中英文注入变体、brief 边界逃逸等。
## 4. 离线/无模型降级现状
| 场景 | 现有代码路径 | 测试覆盖 |
|---|---|---|
| fallback 默认关 | `fallback_feature_enabled()` 消费 features;异常/缺键/非 bool → False | `test_fallback_default_off_when_config_missing`、`test_fallback_explicit_true_enables`、`test_fallback_non_bool_stays_off`、`test_flag_off_preserves_original_behavior`、`test_feature_flags.py` 5 态 |
| runner/pi CLI 不可用 | `propose_reply` 在真实 runner 构建异常时归并为 `FallbackOutcome(stop_reason="unavailable:...")` → 原话术+显式失败审计 | `test_runtime_unavailable_falls_back_to_canned_reply`、`test_runner_exception_fails_explicit` |
| 模型协商 | `resolve_model()`:显式 `APS_FALLBACK_MODEL` > `LLM_BASE_URL/KEY` > `GET /models`(5s、300s 缓存);失败时 `build_pi_runner` 抛 `FallbackUnavailable` | **无 resolve_model/协商失败/降级选第一模型的直接 golden**;既有测试清空 LLM env 后走 fake runner,只覆盖到 runner unavailable 边界 |
| 熔断 | timeout、max_steps、max_output 三闸 + 执行段独立预算 | timeout/max_steps 有直测;`max_output` 代码存在但**未发现直接 golden** |
| MES 断连/补录 | S6 出卡/执行双端 `_probe_mes_connectivity`;显式 `offlineBooking=True` + 断连事实双成立才本地落账并打 `PENDING_SYNC`;恢复后对账呈现 | H 系列 + `test_fallback_offline_booking.py` O-1..O-6;S6 真实 smoke 文档记录 24/24(未在本轮重跑真实冒烟) |
**缺口/冲突点**
- 详细方案 F5 写着“无模型时 fallback 开关强制关闭且 UI 明示原因”,但当前实现是**逐次显式失败回话术**,没有在无模型/模型协商失败时自动把 `features.json` fallback 置为关,也没有专门的 UI 状态位;需要 Agent-A/主管定夺这是产品差异还是 F5 措辞可接受。
- 无“GET /models 超时/HTTP 异常/空清单/LLM_MODEL 不在清单改取第一模型”的直接确定性测试,也未锁模型缓存 300s 行为。
- max_output 熔断缺少确定性测试;执行段预算闸是否被独立测试覆盖也要一并补锁。
## 5. P5 发布现状
- **Pi runtime 仍在 poc 下**:本机安装 `0.73.0`,runtime `node_modules` 被 ignore,git 只保存 package 元数据;产品默认路径硬编码回 poc。
- **桌面打包不含 fallback**:`apps/desktop/package.json` `extraResources` 只含 `web/dist` 与 PyInstaller `sidecar`;`packaging/aps-sidecar.spec` 只收 Python/submodules/ortools/scipy,未含 Node/pi 运行时;未发现可选组件下载、升级清单、Docker/K8s 的 pi-runtime 打包。
- **Web/服务端部署也未含 Pi runtime 解析/分发**:除源码默认 poc 路径外,未见 `APS_FALLBACK_PI_CLI` 的安装/部署清单或 sidecar 环境注入。
- **无 runbook**:`docs/development/` 下未发现 `pi-fallback-runbook.md`;现有 runbook 为康尼数据、离线安装等,不覆盖 Pi runtime 安装、模型网关配置、断网/无模型处置、S4/S6/S7 现场操作与升级。
- P4/P5 目标输出目前除本审计外均不存在:未见 `P4-P5-DESIGN.md`、`test_fallback_p4_quality.py`、`test_fallback_p4_injection.py`、`test_fallback_p4_offline.py`、`P5-RELEASE-NOTES.md`。
- 文档同步只到 P3/FB-03;fallback.md/CHANGELOG 顶部无 P4/P5 章节。
## 6. 给 A/B/C/D 的明确缺口清单
### HIGH
1. **Agent-A:P4/P5 文件级设计缺失**——质量指标 schema、30+ 场景矩阵、注入 20 例分类、离线演练矩阵、P5 发布门禁和 runtime 分发形态都还没有可执行设计;当前 GOAL-P4 只有协调板。
2. **Agent-B:P4 质量设施缺失**——无聚合指标/corpus/golden;需补成功率、误写率、确认轮次、耗时、token/成本统计,并定义“误写率 0、成功率 ≥85%”的可复算门禁。
3. **Agent-C:统一注入 golden 集不足**——无 `test_fallback_p4_injection.py` 的 ≥20 例;且“用户文件进 inbox”尚未产品化,工单备注/CSV/文件名/历史会话类端到端注入无法作为真实验收。
4. **Agent-C:离线/无模型降级没锁死**——resolve_model 失败/超时/选模型降级、max_output 熔断缺直接确定性测试;方案 F5 的“无模型 force-off + UI 明示”与当前行为不一致,需要先定语义再补测试。
5. **Agent-D:P5 发布路径未动**——Pi runtime 仍只在 poc;桌面包/服务端无 runtime 分发、无可选组件、无 `docs/development/pi-fallback-runbook.md`;发布前至少要有可复跑 runbook + 打包清单 + 验收步骤。
### MED
6. **Agent-A/B:执行与确认指标精度不足**——`execution.jsonl` 无 per-step 时间戳;审批轮次只存在通用 approval history,未与 fallback run 建立指标 join;需补字段或建聚合层。
7. **Agent-B:token/成本预算缺失**——没有从 Pi events 解析 usage,也没有日预算/告警;方案 F4 只实现了输出字节近似与三闸。
8. **Agent-E/主管:P3 状态文件互相矛盾**——`P3-VALIDATION.md` 头部写“GO / §7 复证”,但文件本身没有 §7,§5 仍保留“**P3 条件 NO-GO**”总结论;`GOAL-P3.md` 留言板也停在 Agent-N NO-GO,没有 Agent-O 记录。需要同轮收口,否则 P4/P5 基线口径不可信。
### LOW
9. **Agent-A/E:历史 full-golden 数字口径陈旧**——方案 P5 写“1071+ 基线”,P1/P2/P3 文档分别出现 1084、1090、1501 等不同统计和已知失败清单;P4/P5 需要先定义当前 target 版本与回归文件清单,不能继续引用旧数字。
10. **Agent-C/D:文档与边界声明**——fallback.md/P1-DESIGN 已知边界(token 预算、SSE、Docker 可选、自动补推)要随 P4/P5 决定正式闭合或继续显式标记,避免发布时被当作已完成能力。
## 7. 结论
P1–P3 的产品/测试治理基础扎实,78 个兜底专项 golden 定向复跑全绿;但 **P4/P5 尚未开工**:无质量指标设施、无统一 ≥20 注入黄金集、无模型协商/离线 force-off 直接测试、无 runtime 分发与 runbook。当前 P3 产品代码未提交,P3-VALIDATION 内部还存在 GO/NO-GO 冲突,不能作为 P4/P5 干净基线直接封板。