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

57 lines
5.2 KiB
Markdown
Raw Normal View History

# P1-VALIDATION — P1 只读兜底 · 全量验证与文档收尾记录(Agent-F)
> 测试文档员:Agent-F · 日期:2026-09-02 · 协调板:`GOAL-P1.md` · 前置:`P1-DESIGN.md` / `P1-IMPL-NOTES.md`
> 未 git commit / push;全部验证用 `.venv\Scripts\python.exe`(Windows,Git Bash)。
## 1. 本轮(Agent-F)实际改动
| # | 文件 | 新建/修改 | 内容 |
|---|------|----------|------|
| 1 | `server/integrations/pi_bridge.py` | 修改 | **唯一代码改动**:`_TASK_TEMPLATE` 只读约束第 2 条撤销「引用必须标注 callId」,改为「数字必须来自快照 + 凭证由围墙外签发不可获知、不得编造、出现不存在的凭证编号即判伪造成果整轮失败」(设计张力处置,见 §3)。零逻辑变更 |
| 2 | `docs/architecture/harness.md` | 修改 | 权力矩阵追加 `agent.fallback.propose` P1 行;`/api/features` 条目补 `defaultOff` 语义说明;变更记录表加 2026-09-02 FB-01 行 |
| 3 | `docs/architecture/fallback.md` | **新建** | 智能兜底 P1 落地态文档(定位/组件/开关默认关语义/运行目录/三重熔断/围墙与工具桥只读面/callId 凭证与已知限制处置/审计/P1 边界/验证指针),并登记进 `docs/architecture/README.md` 索引 |
| 4 | `docs/CHANGELOG.md` | 修改 | 顶部新增 2026-09-02「FB-01 智能兜底 P1(只读)」条目(体例照 FF-01) |
## 2. 验证命令 + 真实输出摘要
| 验证 | 命令 | 真实结果 |
|------|------|----------|
| 新增/修改测试(改动后复跑) | `pytest tests/golden/test_fallback_lane.py tests/golden/test_feature_flags.py -q` | **19 passed**(13 兜底 + 6 开关),1.71s |
| 受影响切片复跑(IMPL-NOTES §3 两组,13 文件) | `pytest test_contract_sync test_assistant test_guidance test_folder_pack test_tool_runtime test_gov_api test_chat_ensure_session test_closed_loop_gateway test_automation_gateway test_automation_gears test_dialog_clarify test_harness_p3 test_tool_runtime_gateway -q` | **83 passed**,6.56s(= 回归 42 + 聊天网关门禁 41;IMPL-NOTES 的「102」系其 61 含了当轮新增 19 例的合并计数,83 与之一致) |
| 文档/端点门禁 | `pytest test_doc_drift test_health_version test_openapi_schema test_rebuild_pipeline -q` | **20 passed**,11.19s;文档改动后 `test_doc_drift` 单独复跑 **5 passed** |
| **全量黄金** | `ls tests/golden/test_*.py` 分 4 批 × `pytest -q`(单批 38–128s,规避 300s 窗口) | **1084 passed / 1 failed**(批 1: 246 / 批 2: 296 / 批 3: 280 / 批 4: 262+1 failed),合计 ~333s |
| ruff | `ruff check pi_bridge.py fallback_lane.py test_fallback_lane.py` | **All checks passed!** |
| 既有失败核实 | `git diff --stat HEAD -- server/knowledge/ tests/golden/test_preference_features.py` | **零 diff**;该用例 dueDate 写死 2026-08-03/04,今天 2026-09-02 半周期窗口已过 → `urgencyRatio 0.0≠0.5`。**既有日期炸弹,与本轮无关**,未顺手修(超出范围,建议另开轮次改相对 today 生成) |
## 3. 设计张力处置(IMPL-NOTES 遗留风险 #2)
**张力**:callId 凭证由编排器在围墙外从事件流**事后签发**,真实 Pi 进程内 LLM 无法获知其值;
原任务简报强制「引用数据时标注 [callId: ...]」→ 真实 Pi 要么不引用(凭证制度空转),
要么幻觉出格式吻合的 UUID(必判 forged_citation,真实成果被误杀)。
**处置(最小方案,已实施)**:只改任务简报模板,撤销强制标注指令,改为明示
「凭证不可获知、不得编造;报告中出现不存在的凭证编号即判伪造成果整轮失败」。
**安全性质核验**(未破坏):
- `validate_report_citations()` 硬失败语义一字未动;
- `test_forged_callid_rejected` 继续绿(编造 callId → valid=False → 整轮 FAILED);
- 引用从「强制义务」降级为「防伪绊线」(出现即必须是真);报告数字可靠性改由
「唯一数据来源 = inbox 只读快照」保证(快照之外无数据可读)。
- 未选「校验降级 warning」方案:那会改 `propose_reply` 判败逻辑并打破安全测试断言。
已写入 `docs/architecture/fallback.md`(凭证语义节)与 CHANGELOG 边界。
## 4. 未验证 / 遗留清单
1. **真实 pi 端到端冒烟未做**(本轮全 fake runner,无 node/pi/真实 LLM):需带 key 环境按
P0 方法补一次「开关开 + 真实 runner」冒烟;冒烟时注意简报新文案下真实 pi 不应再
产出 callId 引用。
2. **test_preference_features 日期炸弹**:既有失败,与本轮无关,未修(建议另开轮次,
dueDate 改相对 today 生成)。
3. **模型协商缓存是进程级单值**(`_MODEL_CACHE`,TTL 300s):多 base_url 切换需等 TTL 或重启
(IMPL-NOTES 遗留 #6,P1 单现场可接受)。
4. **P1 边界外全部未做**:写操作 / 确认卡执行 / pi 进程内实时工具 / 异步回投 / 桌面打包 /
SSE 转发 / token 预算闸 / S2·S3·S9(详见 fallback.md 边界节)。
5. **模型名协商依赖 GET /models 可达**:端点不支持 /models 的网关会判 unavailable
(显式失败回话术,可用 `APS_FALLBACK_MODEL` 显式指定绕过)。