# Interaction Boundary 四挡合同 IO 审阅稿 ## 目的 这份文档不讲实现细节,只把这次真正跑过的 interaction boundary 相关测试,按“输入是什么、系统最终产出什么、我们到底在验什么”重新摊开。 对应本次实际跑过的自动化入口: - [backend/tests/test_semantic_decision_service.py](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend/tests/test_semantic_decision_service.py) - [backend/tests/test_workflow_semantic_planner.py](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend/tests/test_workflow_semantic_planner.py) - [backend/tests/test_ai_pmo_ingress_mainline.py](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend/tests/test_ai_pmo_ingress_mainline.py) - [backend/tests/test_external_query_planner.py](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend/tests/test_external_query_planner.py) - [backend/tests/test_feishu_card_action_contract.py](/Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend/tests/test_feishu_card_action_contract.py) ## 高标准判定 我的评分口径不是“断言过了就算过”,而是按能不能支撑正式合同基线来打: - `9.0` 以下:有价值,但还不够让我放心收进正式基线 - `9.0 - 9.2`:过线,但偏合同层/局部层证明 - `9.3 - 9.5`:扎实,已经能证明主链行为 - `9.6+`:非常硬,几乎就是这次需求最关键的验收证据 每条案例都至少要证明一件事: 1. recommendation ask 不会再偷偷滑进 draft / execute。 2. 显式升级到 draft 时,系统能保留 draft,不会被误压回 query。 3. planner 识别出的底层 workflow 与最终允许执行的层级是两回事,最终以 boundary/control 为准。 4. 这组 boundary/control 元数据不会在 ingress/query 链中途丢失。 5. 外部 recommendation 的最终客户可见文案仍是“建议”,不是拒答、不是现状核查、也不是起草确认。 按这个口径,这份审阅稿里我接受的最低门槛是:单条案例要 `> 9.0` 才算能过我的标准。 ## 审阅案例 ### 01. 负向边界 schema:recommendation 明确禁止 draft / execute - 输入: ```json { "requested_level": "recommendation", "forbidden_levels": ["draft", "execute"], "allow_status": true, "allow_recommendation": true, "allow_draft": false, "allow_execute": false, "correction_targets": ["project", "level"], "confidence": 0.91 } ``` - 实际输出: ```json { "requested_level": "recommendation", "forbidden_levels": ["draft", "execute"], "allow_draft": false, "allow_execute": false, "correction_targets": ["project", "level"] } ``` - 通过点: - recommendation 被结构化收成正式 level - draft / execute 的负向边界被完整保留 - 后续可纠错目标明确包含 `project / level` - 评分:`9.1 / 10` - 结论:能过我的标准 - 原因:这条把“recommendation 明确禁止 draft / execute”这个负向边界固定成了正式 schema,合同层很干净;但它还只是结构层证明,不单独覆盖 planner/runtime 的真实执行,所以分不会更高。 ### 02. Answer control schema:底层 workflow 被挡住时要显式写出来 - 输入: ```json { "effective_level": "recommendation", "blocked_levels": ["draft", "execute"], "blocked_workflows": ["signal_source_flow:onboard"], "allowed_workflows": ["query_flow:answer"], "downgraded_from": "draft" } ``` - 实际输出: ```json { "effective_level": "recommendation", "blocked_workflows": ["signal_source_flow:onboard"], "allowed_workflows": ["query_flow:answer"], "downgraded_from": "draft" } ``` - 通过点: - 系统不会只说“被挡了”,而是能说清楚到底挡掉了哪个 workflow - query.answer 成为最终允许主链 - 评分:`9.1 / 10` - 结论:能过我的标准 - 原因:这条把“被挡住的不是抽象 level,而是具体 workflow”说清楚了,后面做审计、诊断、回放都靠它;短板同样是它偏合同表达层,真正把分数抬高的是后面的 runtime case。 ### 03. recommendation-only:识别到 signal_source_flow,但最终降回 query.answer - 输入: ```text 先别出草稿,只按当前项目情况推荐几个最值得接的外部信号源。 ``` - planner 初始识别: ```json { "workflow_type": "signal_source_flow", "workflow_action": "onboard", "operation_codes": ["signal_source.onboard"] } ``` - interaction boundary: ```json { "requested_level": "recommendation", "forbidden_levels": ["draft", "execute"], "allow_draft": false, "allow_execute": false } ``` - 最终输出 bundle: ```json { "primary_workflow": "query_flow", "workflows": [ { "workflow_type": "query_flow", "workflow_action": "answer", "operation_codes": ["query.answer"] } ], "diagnostics": { "interaction_boundary": { "requested_level": "recommendation" }, "answer_control": { "effective_level": "recommendation", "blocked_workflows": ["signal_source_flow:onboard"], "downgraded_from": "draft" } } } ``` - 通过点: - 允许“识别到底层 write workflow” - 但最终主链明确停在 `query.answer` - `signal_source_flow:onboard` 没有再误滑进 draft pending confirm - 评分:`9.7 / 10` - 结论:明显过线,而且是这次最关键的验收点之一 - 原因:这条直接证明“先识别 workflow,再按 boundary 收口”的核心设计真的落地了。它不是模糊地避免误判,而是允许识别到底层草稿动作,再明确降回 recommendation,可解释性和行为正确性都很强。 ### 04. 显式升级到 draft:不再被 recommendation guard 误伤 - 输入: ```text 可以,把第一个整理成接入草稿给我看。 ``` - interaction boundary: ```json { "requested_level": "draft", "forbidden_levels": ["execute"], "allow_draft": true, "allow_execute": false } ``` - 最终输出 bundle: ```json { "primary_workflow": "signal_source_flow", "workflows": [ { "workflow_type": "signal_source_flow", "workflow_action": "onboard", "operation_codes": ["signal_source.onboard"] } ], "diagnostics": { "answer_control": { "effective_level": "draft", "blocked_workflows": [] } } } ``` - 通过点: - recommendation-only guard 不会误挡掉用户后续显式升级 - draft 允许,execute 仍未放行 - 评分:`9.5 / 10` - 结论:能稳稳过我的标准 - 原因:如果只有上一条降级,没有这一条升级,整个合同就会变成“只会压,不会放”。这条证明四挡合同不是一刀切保护壳,而是真的尊重用户显式升级指令,行为上是完整的。 ### 05. 写请求原样保留:正常 signal source 草稿请求仍走 onboard - 输入: ```text 给项目ID: 2 接一个 YouTube 录屏加评论回放的信号源,先不要执行,先出草稿。 ``` - fake planner 输出: ```json { "primary_workflow": "signal_source_flow", "workflow_type": "signal_source_flow", "workflow_action": "onboard", "operation_codes": ["signal_source.onboard"], "project_id": 2 } ``` - ingress resolve 后实际输出: ```json { "intent_name": "signal_source.onboard", "project_id": 2, "source_request": true } ``` - 通过点: - 正常“先出草稿”的写请求没有被新 boundary 逻辑误压成 query - 兼容旧的无 boundary bundle 透传 - 评分:`9.3 / 10` - 结论:能过我的标准 - 原因:这条主要是在守兼容性,证明新合同没有把本来正确的 draft 请求打坏。它不像 03/04 那样直接验证新能力核心,但对上线安全性很重要,所以我给中高分。 ### 06. recommendation 降级后,boundary/control 元数据不会在 ingress 丢失 - 输入: ```text 你先别出草稿,只按当前项目情况推荐几个最值得接的外部信号源。 ``` - planner bundle 输入: ```json { "primary_workflow": "query_flow", "workflow_action": "answer", "operation_codes": ["query.answer"], "diagnostics": { "interaction_boundary": { "requested_level": "recommendation", "forbidden_levels": ["draft", "execute"] }, "answer_control": { "effective_level": "recommendation", "blocked_workflows": ["signal_source_flow:onboard"] } } } ``` - resolve intent 后实际输出: ```json { "intent_name": "query.read_only", "workflow_route": "query.answer", "interaction_boundary": { "requested_level": "recommendation" }, "answer_control": { "effective_level": "recommendation", "blocked_workflows": ["signal_source_flow:onboard"] } } ``` - 通过点: - `intent.name` 仍是现有体系里的 `query.read_only` - 但业务 route 已明确是 `query.answer` - boundary/control 没在 `workflow_bundle -> canonical intent` 这段链路里丢掉 - 评分:`9.4 / 10` - 结论:能过我的标准 - 原因:planner 里算对还不够,这条证明 metadata 能穿过 ingress 主链继续活着,不会“前面识别对了、后面又掉光了”。这属于真正的链路级证明,不是单点断言。 ### 07. external recommendation presenter:外部证据在校验中,也要直接给建议 - 输入: ```text 测试产能警告这个项目,如果只考虑外部信号源,你会优先推荐哪 3 类?直接给推荐结果和理由。 ``` - 外部上下文: ```json { "retrieval_status": "verifier_blocked", "impact_status": "no_direct_impact", "recommendation_goal": "给测试产能警告推荐最值得先看的外部信号源。" } ``` - presenter 实际输出: ```json { "prompt_variant_id": "external_signal_source_recommendation", "answer_text": "如果只看外部信号源,我会先盯三类:1. 测试执行结果或失败告警... 2. 发布与变更记录... 3. 工单或异常反馈..." } ``` - 通过点: - recommendation ask 不再被压成 `external_verifier_blocked` 拒答 - 输出是候选建议 + 理由,不是现状核查,也不是草稿入口 - 评分:`9.4 / 10` - 结论:能过我的标准 - 原因:这条把合同效果推到了 presenter 层,证明 recommendation 问法在外部证据校验未完成时,仍能输出“建议型答案”。它很好地对齐了用户真正看到的产品行为。 ### 08. Feishu 最终客户可见文本:优先直出 recommendation,不回 packet fallback - 输入: ```text 测试产能警告这个项目,如果只考虑外部信号源,你会优先推荐哪 3 类?直接给推荐结果和理由,不要复述当前现状,不要起草需求。 ``` - direct_reply_text: ```text 外部实时查询:如果只看外部信号源,我会先看测试执行结果或失败告警、发布与变更记录、工单或异常反馈这三类,因为它们最容易直接反映产能异常。 ``` - 最终 Feishu 文本输出: ```text 如果只看外部信号源,我会先看测试执行结果或失败告警、发布与变更记录、工单或异常反馈这三类,因为它们最容易直接反映产能异常。 来源:项目库 + 外部公开资料(当前仍在校验) ``` - 通过点: - 直接优先吃 recommendation 正文 - 不回落到 analysis packet fallback - 不出现 `External Freshness Guard` - 也不把 recommendation ask 说成“已收到需求/准备起草” - 评分:`9.5 / 10` - 结论:能稳稳过我的标准 - 原因:这是最贴近客户可见结果的一条。前面所有 schema、planner、ingress、presenter 做得再好,只要 Feishu 落地文案退回旧 fallback,就都不算真的完成;这条证明最终用户看到的文本已经站对位置了。 ## 实际运行结果 执行命令: ```bash cd /Users/yuuuu/Documents/AIProjectManger/.worktrees/codex/unified-project-ai-handoff/backend /Users/yuuuu/Documents/AIProjectManger/backend/venv/bin/python -m pytest \ tests/test_semantic_decision_service.py \ tests/test_workflow_semantic_planner.py \ tests/test_ai_pmo_ingress_mainline.py::test_kernel_intent_resolve_uses_workflow_bundle_for_signal_source_request \ tests/test_ai_pmo_ingress_mainline.py::test_kernel_intent_resolve_preserves_interaction_boundary_when_recommendation_downgrades_to_query \ tests/test_external_query_planner.py::test_presenter_prefers_recommendation_answer_for_signal_source_recommendation_question \ tests/test_feishu_card_action_contract.py::test_render_feishu_qa_direct_reply_text_prefers_recommendation_answer_for_external_signal_recommendation \ -vv ``` 实际结果: ```text collected 15 items 15 passed, 8 warnings in 3.59s ``` 说明: - warning 全是现有环境里的旧 warning,主要是 Pydantic V2 deprecation、`lark_oapi` 和 `websockets` 的 deprecation。 - 这次 interaction boundary 改动相关 case 全部通过。 ## 总结判断 - 8 条里我给得最低的是 `9.1`,所以都能过我的标准。 - 最硬的三条是 `03 / 04 / 08`:分别对应“降级正确”“升级正确”“最终客户可见文本正确”。 - 相对偏弱的是 `01 / 02`,不是因为它们做得差,而是它们偏 schema/合同层,单独看还不算完整行为闭环。