Files
T
zhuyongxin 38f781b157 feat(harness): complete protocol repair stop and archive ISS-016
Add repairable INVALID_PROGRESS_PROTOCOL observations, independent
PROGRESS_PROTOCOL_VIOLATED saturation, and controlled release paths.
Archive the OpenSpec change after syncing main specs and devflow.
2026-07-27 19:10:07 +08:00

83 lines
7.8 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.
## Why
Diagnosis Agent 面对知识库未知、日志为空或查询条件不足的问题时,当前只能依赖 Tool、Token 和轮次预算停止。模型可能不断改写查询继续调用 Tool,最终以 `BUDGET_EXHAUSTED` 或 `INTERNAL_FAILURE` 结束;用户只能看到通用错误,无法看到已经完成的检查和证据缺口。
系统需要把“没有足够证据得出结论”视为正常、可发布的诊断结果,同时用确定性的 Harness 规则阻止无信息增益的空转,并继续由 EvidenceGuard 和 SemanticGuard 拦截无证据结论。
## What Changes
- 在 Run 内增加最小进展状态:`GAINED / NO_GAIN`、连续无增益计数、`COLLECTING / SATURATED` 和内部 `stop_reason`。
- 通过模型原生 Tool Calling 注册统一 Tool Call Envelope;模型继续调用 Tool 时,在下一次调用中回传上一轮 `information_gain`,Harness 校验并消费控制字段,业务 Tool 请求保持原结构。
- Harness 对 `NO_EVIDENCE` 和重复的 `tool_name + normalized_scope` 确定性赋值 `NO_GAIN`;其他成功非空结果由模型判断 `GAINED / NO_GAIN`。
- 配置 `harness.chat.stop-after-consecutive-no-gain`,默认值为 `2`,达到阈值后拒绝新的业务 Tool 执行并要求结束。
- 将 Canonical Tool Result 分为 Harness Control View 和白名单 Model Observation;保留 RAG `relevance_level`,不把内部计数、预算、检索轨迹或 raw response 放进模型上下文。
- Tool Loop 结束时从当前 Run 已完成的 canonical 调用一次性投影 `ProgressSnapshot`,用于发布已检查来源、scope、客观结果和证据缺口。
- 统一 `DiagnosisReleaseUseCase` 对正常 Draft、信息饱和和预算终止的发布决策;`conclusion=null` 不触发 EvidenceRepair,有结论时才执行完整 EvidenceGuard、EvidenceRepair 和 SemanticGuard。
- 最终 Draft 违反结构化输出契约时继续拒绝该 Draft;若当前 Run 已有可验真的 ProgressSnapshot,则仅从 canonical 过程确定性发布 `INSUFFICIENT_EVIDENCE`,没有安全进展时仍 fail closed。
- 复用现有 `SafeFallback` 和 SSE/前端协议,增加或规范 `INSUFFICIENT_EVIDENCE`、`MISSING_REQUIRED_CONTEXT`,迁移当前位于 `ChatApplicationUseCase` 的预算兜底意图。
- 精简中文 Diagnosis Prompt,明确模型不必须得出根因、允许零次 Tool 调用、正确但对当前推导无用的内容属于 `NO_GAIN`,且合法放弃是成功完成。
- 增加最小模型调用审计:按组件和轮次记录 input/output/total Token,回填 Diagnosis AgentStep Token,并在 Run 结束时与预算总账对账;不记录 Prompt、模型正文或推理内容。
- 对进入 Harness 后被协议、饱和或重复 scope 门禁拒绝的 Tool 请求记录安全 Trace,使预算 Tool 计数、实际执行和拒绝决策可区分;不记录 Tool 参数或原始响应。
- 对 `INVALID_PROGRESS_PROTOCOL` 增加可修正的模型观察:明确缺失/错序的协议字段、期望上一轮 Tool Call ID 和允许的 `information_gain` 值;连续协议错误达到阈值后转为受控停止,避免模型反复空转。
## Capabilities
### New Capabilities
- `diagnosis-information-gain-stop-contract`: 定义 Tool 信息增益回传、Harness 饱和停止、进展投影和安全发布行为。
### Modified Capabilities
- `single-react-diagnosis-agent`: Tool Schema 改为服务端注册的统一 Envelope,Prompt 和 Agent 结束行为支持合法放弃。
- `canonical-tool-invocation-store`: canonical 结果继续作为 Tool 真相源,并支持当前 Run 在结束时投影进展,不新增第二套持久化真相。
- `aci-evidence-tool-contracts`: RAG 投影保留 `relevance_level`,Tool 结果拆分控制视图和模型白名单视图。
- `single-react-evidence-semantic-guards`: 无结论 Draft 不进入结论修复链;有结论仍执行完整证据与语义保护。
- `single-react-chat-application-usecase`: 预算与饱和的业务 Fallback 由 Diagnosis Release 统一决策。
## Scope
- Diagnosis Agent Prompt、Tool Schema/Interceptor、三个 Tool contract 的 Agent-facing 包装。
- RunContext 进展 tracker、确定性 scope 规范化和连续无增益停止门禁。
- RAG/日志/MySQL canonical 控制视图与模型观察投影。
- Diagnosis Agent 执行结果、ProgressSnapshot、Release、Fallback 和 Trace。
- Draft 合同失败的脱敏 Trace 与“有安全进展才允许降级”的 Executor/Release 边界。
- 模型调用 Token 明细、Run 对账摘要和 Tool 请求拒绝 Trace。
- Spring 配置绑定、focused tests、回归测试和真实 SSE/日志/数据库 E2E。
## Non-goals
- 不引入 `new_count`、`next_action`、多级质量分数、`UNKNOWN` 或独立 Judge 模型。
- 不做自然语言语义去重,只比较确定性的 `tool_name + normalized_scope`。
- 不让 Tool 或 Harness 判断业务根因,不把 `REFERENCE` 自动等同于 `NO_GAIN`。
- 不增加 `CONFIRMED / INSUFFICIENT_EVIDENCE / NEED_MORE_INFO` 第二套诊断生命周期状态。
- 不修改公开 HTTP/SSE 事件结构,不新增前端页面或新的用户可见进度协议。
- 不重新引入 Planner/Executor/Verifier/Composer 多 Agent 链路,不处理 ISS-015 的 Reasoning 原文审计治理。
## Context Constraints
- Tool 通过 `DiagnosisAgentFactory.tools(...)` 的原生 Tool Calling 通道注册,Prompt 不写 Tool 名称、Schema 或 Schema 占位符。
- `CanonicalInvocationStore` 是当前 Run 完整 Tool 调用真相源;Run 内 tracker 只维护控制状态和完成调用索引,不复制 raw response。
- `RunContext` 继续使用“结构不可变 + 线程安全可变 handle”的既有模式;阈值在 Run 启动时固定。
- 现有 `SafeFallback.observed_facts / verified_sources / limitations / next_steps` 和前端渲染能力必须复用。
- 协议错误不等同于 Tool 内容 `NO_GAIN`;它使用独立 `PROGRESS_PROTOCOL_VIOLATED` stop reason,并且只在有可发布 ProgressSnapshot 时进入安全 Fallback。
- 当前未提交的预算 Fallback 修改保留用户价值,但业务 Release 决策需要从 `ChatApplicationUseCase` 迁移到 `DiagnosisReleaseUseCase`。
- 当前环境缺少 `codebase-retrieval` 和 LSP;本次影响核查使用 `rg` 引用搜索、源码和测试阅读降级完成。用户已明确允许忽略 GitNexus。
## Interface Impact
- 级别:L3 协作接口。
- 变更对象:模型可见的三个 Tool input schema、Tool Call 解析、Diagnosis Agent 到 Release 的内部执行结果。
- 兼容性:业务 Tool request、Tool backend、公开 HTTP/SSE 和持久化表结构保持不变;旧的模型 Tool 参数形状不再被 Agent-facing schema 接受。
- 消费者:`DiagnosisAgentFactory`、`HarnessEvidenceTools`、`HarnessToolInterceptor`、三个 adapter 及 scripted Tool-loop tests。
- 回滚:整体回滚本 change;不提供双 Tool Schema 或兼容分支。
## Risks
- 框架 Tool Schema 生成或 ToolInterceptor 参数处理不符合 Envelope 假设,导致模型无法正确回传或业务 request 未被剥离。
- STOP_REQUIRED 若未形成受控结束,模型可能继续请求 Tool,或 Agent 调用异常绕过统一 Release。
- 仅返回通用 `INVALID_PROGRESS_PROTOCOL` 可能不足以让模型自修复;必须返回字段级 repair hint,同时设置连续错误兜底。
- 最后一轮结果可能没有下一次 Tool Call 来回传模型评价;该情况只能表示模型主动结束,不能伪造 `GAINED / NO_GAIN`。
- ProgressSnapshot 若读取不完整或混入 raw payload,会造成过程缺失或上下文/隐私边界倒退。
- `conclusion=null` 与现有 EvidenceGuard 的 `ANALYSIS_MISSING` 规则冲突,需要明确区分“验证引用真实性”和“验证结论完整性”。
- 现有脏工作区包含相关预算 Fallback 改动,实施时必须迁移其意图并避免覆盖其他历史修改。