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.
This commit is contained in:
+82
@@ -0,0 +1,82 @@
|
||||
## 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 改动,实施时必须迁移其意图并避免覆盖其他历史修改。
|
||||
Reference in New Issue
Block a user