# Harness 证据安全链学习笔记:从收敛控制到唯一发布点 **更新日期**:2026-08-06 **主题**:progress → guard → release 三域联动——双通道验证架构 + 状态流转全景 + 关键字段来源与使用 **配套**:[progress 代码学习笔记](Harness%20progress%20代码学习笔记-从拦截器五道门到唯一发布点.md)、[Retry 重试机制](Retry重试机制-显式可计量的attempt循环.md)、[执行控制笔记](Harness执行控制笔记-终态检查与取消广播.md) ## 1. 一句话定位 **证据安全链 = progress(执行期收敛控制)→ guard(验证)→ release(唯一发布点)**: 任何对外发布的内容,必须能追溯到 canonical 账本的已验证事实;任何无法证明的内容,只能以有界、诚实的 SafeFallback 降级形态出现。 ## 2. 主链路图 ```mermaid flowchart LR subgraph 执行期["Agent 执行期(core 控资源 + progress 控收敛)"] TC["HarnessToolInterceptor
工具调用完成"] TC -->|"完整记录"| CS["Canonical Store
(唯一真相源, TTL 2h)"] TC -->|"identity"| TR["Progress Tracker
(toolCallId+toolName+scope)"] end subgraph 停止["Agent 结束(所有出口触发投影)"] TR -->|"回读验真"| PP["DiagnosisProgressProjector"] PP --> PS["ProgressSnapshot
(observedFacts+limitations+stopReason)"] end subgraph 裁决["Release 裁决(唯一发布点)"] EX["DiagnosisAgentExecution
(draft / stopped)"] EX --> RC["releaseConclusion
(有结论)"] RC -->|"tool_call_ids"| EG["EvidenceGuard
机械验引用"] EG -->|"失败"| ER["EvidenceRepair
只修引用→复查"] EG -->|"通过"| VES["VerifiedEvidenceSnapshot"] VES --> SG["SemanticGuard
判支持度"] SG -->|"SUPPORTED"| SUCCESS["SUCCESS
(唯一出口)"] SG -->|"UNSUPPORTED/不可用"| FB["SafeFallback 降级"] EG -->|"仍失败"| FB EX -->|"stopped / 无结论"| FB PS -->|"降级原料"| FB end CS -.->|"回读"| EG CS -.->|"回读"| PP ``` ## 3. 双通道验证架构(核心) 两条并行的「账本背书」通道,合起来覆盖所有结局: | | progress 快照 | guard 快照 | |---|---|---| | 类 | `DiagnosisProgressSnapshot` | `VerifiedEvidenceSnapshot` | | 组装时机 | agent 结束那一刻(所有出口) | release 验引用通过后 | | 原料 | Tracker 的调用 identity | draft 里模型写的 tool_call_ids | | 回读者 | `DiagnosisProgressProjector` | `EvidenceGuard` | | 需要 draft | **不需要** | **必须** | | 服务谁 | 受控停止/无结论/非法 draft 降级 | 有结论 draft 证据链 + SemanticGuard | | 共同点 | 都从 canonical 回读、三重校验、去重有界、绝不输出 raw | 同左 | **设计意义**:agent 没给出合法 draft(预算打断、输出烂)时,靠 progress 快照降级;给出合法 draft 时,靠 guard 快照支撑。**任何情况下对外发布都有据可依。** ## 4. 状态流转全景(技术终态 vs 用户终态) ### 4.1 六层状态(从内到外) | 层 | 类型 | 值 | 回答的问题 | |---|---|---|---| | core 生命周期 | `RunState` | RUNNING / SUCCESS / FAILED / CANCELLED / TIMED_OUT / BUDGET_EXHAUSTED | Run 技术上是否还允许继续执行 | | progress 收集停止 | `DiagnosisStopReason` | INFORMATION_SATURATED / BUDGET_LIMIT_REACHED / PROGRESS_PROTOCOL_VIOLATED | 证据收集为何受控停止 | | release 发布裁决 | `ReleaseOutcome` | SUCCESS / FALLBACK / FAILED / CANCELLED | 用户侧内容结局是什么 | | release 降级细分 | `FallbackType` | EVIDENCE_VALIDATION_FAILED / SEMANTIC_UNSUPPORTED / SEMANTIC_UNAVAILABLE / BUDGET_EXHAUSTED / INSUFFICIENT_EVIDENCE / MISSING_REQUIRED_CONTEXT | FALLBACK 为什么降级 | | SSE 进度 | `ChatApplicationStatus` | ROUTING / DIAGNOSIS_RUNNING / SAFETY_VALIDATING ... | 当前走到哪一阶段(不是结局) | | 对外失败码 | `ChatFailureCode` | RUN_CANCELLED / INTERNAL_FAILURE / ... | 失败时给客户端的粗粒度原因 | ### 4.2 关键映射规则(代码事实) ```text RunState.BUDGET_EXHAUSTED + progress.hasObservedFacts()==true → ReleaseOutcome.FALLBACK(FallbackType.INSUFFICIENT_EVIDENCE) RunState.BUDGET_EXHAUSTED + 无 facts → FAILED(fail closed:没有安全内容可发布) RunState.CANCELLED → ReleaseOutcome.CANCELLED + ChatFailureCode.RUN_CANCELLED 内部失败(completeFailure)→ RunState.FAILED + ReleaseOutcome.FAILED + INTERNAL_FAILURE guard 全过 → RunState.SUCCESS + ReleaseOutcome.SUCCESS(唯一出口) 预算耗尽且子路径已产出 FALLBACK → 不二次 completeSuccess ``` ### 4.3 两个正交维度的区分(高频面试点) - **RunState** 回答「Run 技术上是否还在跑、因何技术终态停下」; - **ReleaseOutcome** 回答「用户侧内容形态:正常报告 / 安全降级 / 失败 / 取消」; - 常见组合:`RunState=BUDGET_EXHAUSTED` 且有安全进展 → `ReleaseOutcome=FALLBACK`;无进展 → `FAILED`。 ### 4.4 终态异常透传 `DiagnosisReleaseUseCase.propagateTerminal`:`RunAbortedException` / `BudgetExceededException` / `RetryFailure.CANCELLED|BUDGET_EXHAUSTED` **原样上抛**,不吞、不伪装成业务 FALLBACK——取消和预算耗尽是 Run 的技术终态事实,用户侧必须知道「被取消了」而不是「诊断结论是不足」。 ## 5. 关键字段的来源与使用 ### 5.1 CanonicalToolInvocation(唯一真相源,执行时落库) | 字段 | 来源 | 使用 | |---|---|---| | tool_call_id + run_id | ToolBoundary 执行时生成 | key = runId + toolCallId(两个投影器都按它回读) | | request / raw_response | 工具请求与原始返回 | 审计/验真,不外发 | | agent_result | Projector 投影后的有界结果 | Agent 可见的唯一形态;EvidenceGuard 重读它 | | status | PROJECTING → READY / ERROR(单向迁移) | isReferencableBy 要求 READY | | evidence_status | FOUND / NO_EVIDENCE / ERROR | kind.accepts() 匹配、投影一致性校验 | | error_code | 仅 ERROR 携带 | 稳定错误码 | | started_at / completed_at | 生命周期时间戳 | TTL / 审计 | ### 5.2 DiagnosisProgressSnapshot(progress 快照,agent 结束时组装) | 字段 | 来源 | 使用 | |---|---|---| | verifiedSources | Projector 回读 canonical,去重 | 降级时展示「查过哪些来源」 | | observedFacts | 同上(≤12 条,摘要 320 字,空查询也算) | 「查了查到什么」;`hasObservedFacts()` 安全阀 | | limitations | 无法验真/截断的诚实说明 | 降级时展示限制 | | stopReason | Tracker 状态 | release 检查白名单后决定降级 | ### 5.3 VerifiedEvidenceSnapshot(guard 快照,验真通过后组装) | 字段 | 来源 | 使用 | |---|---|---| | analyses[] | EvidenceGuard 重读 canonical agent_result 重建 | SemanticGuard.review 输入 | | verifiedSources() | 方法去重(sourceType+source+scope) | SUCCESS 的 published_result.source_documents、FALLBACK 的来源 | ### 5.4 SafeFallback(降级载荷,release 降级出口构造) | 字段 | 来源 | 使用 | |---|---|---| | type | SafeFallbackFactory 按场景 | 用户/审计区分降级原因 | | conclusion | 恒 null | 降级绝不发布根因结论 | | verified_sources / observed_facts | progress 或 guard 快照投影 | 保留已验证事实供用户继续排查 | | limitations / next_steps | 工厂按场景拼装 | 诚实说明 + 下一步 | | failure_stage | DIAGNOSIS_INPUT / DIAGNOSIS_COLLECTION / EVIDENCE_VALIDATION / SEMANTIC_VALIDATION | 定位失败阶段 | | validation_issues | EvidenceViolation 映射 | EVIDENCE_VALIDATION_FAILED 时的违规明细 | ## 6. 设计要点(贯穿全链的规律) 1. **fail closed 贯穿每一层**:guard 验引用默认拒绝、读投影严格反序列化、release 无 facts 抛异常、SafeFallback 无事实拒绝构造——「不确定 → 默认拒绝,没查到永不伪装成结果」。 2. **负向证据被完整建模**:progress 空查询投影成事实、NEGATIVE_OBSERVATION 配 NO_EVIDENCE、降级诚实声明「查到了但不够」。 3. **canonical 唯一真相源**:链上不存在第二份工具真相;两个投影器共用同一套三重校验。 4. **全链路可审计回放**:EVIDENCE_GUARD_INITIAL/RECHECK、SEMANTIC_ATTEMPT/DECISION、EVIDENCE_REPAIR_ATTEMPT、RELEASE_DECISION 全落 trace。 5. **语义不变性**:EvidenceRepair 只修引用不修结论(prompt 锁死 + hasSameUserVisibleSemantics 校验)。 6. **命名债务**:`FallbackType.BUDGET_EXHAUSTED` 枚举保留,但预算停实际发布 `INSUFFICIENT_EVIDENCE`(注释自认)。 7. **重复验证**:同一 tool_call_id 被多条 analysis 引用会重复验 N 次(引用级独立校验的代价,账本查询便宜可接受)。 ## 7. 面试话术(30 秒) > "Harness 的证据安全链是 progress → guard → release 三段联动。**执行期**:progress 管信息增益收敛(预算归 core),工具调用实时落 canonical 账本、Tracker 只记 identity;**验证期**:agent 结束后 release 编排——有结论的 draft 先进 EvidenceGuard 机械验引用(每个 tool_call_id 从账本回读、READY 且 kind 匹配,失败则 EvidenceRepair 只修引用再验),通过后 SemanticGuard 判结论是否被证据支持;**发布期**:SUPPORTED 是唯一 SUCCESS 出口,其余全部经 SafeFallbackFactory 构造有界诚实的降级。关键设计是**双通道**:没有合法 draft 时靠 progress 快照(observedFacts)降级,有 draft 时靠 guard 快照支撑——任何情况对外发布都有据可依;以及**状态正交**:RunState 回答技术终态(预算耗尽/取消),ReleaseOutcome 回答用户结局(降级/失败),取消和预算耗尽经 propagateTerminal 原样上抛,绝不伪装成业务降级。" ## 8. 代码位置索引 | 组件 | 文件 | |---|---| | EvidenceGuard / EvidenceViolationCode | `src/main/java/com/superbiz/agent/harness/guard/evidence/` | | SemanticGuard / GuardModelCall | `src/main/java/com/superbiz/agent/harness/guard/semantic/` | | DiagnosisReleaseUseCase / EvidenceRepair / SafeFallbackFactory | `src/main/java/com/superbiz/agent/harness/release/` | | DiagnosisProgressProjector / Tracker / Snapshot | `src/main/java/com/superbiz/agent/harness/progress/` | | CanonicalToolInvocation / Store | `src/main/java/com/superbiz/agent/harness/tool/store/` | | RunState | `src/main/java/com/superbiz/agent/harness/core/RunState.java` | | DiagnosisStopReason | `src/main/java/com/superbiz/agent/harness/progress/DiagnosisStopReason.java` | | ReleaseOutcome / FallbackType / SafeFallback | `src/main/java/com/superbiz/agent/harness/contract/` | | ChatApplicationStatus / ChatFailureCode | `src/main/java/com/superbiz/agent/harness/application/` |