Chat Diagnosis StateGraph Real Nodes Decisions
Question Pool
| # |
维度 |
问题 |
模式 |
状态 |
| Q1 |
边界 |
阶段 2 是否切换 ChatService/DB/Trace? |
user-interview(六阶段已确认) |
已解决 |
| Q2 |
复用 |
新 Nodes 如何避免复制 Hook/ChatService 解析与安全渲染? |
evidence-driven |
已解决 |
| Q3 |
Agent |
Adapter 如何调用真实 ReactAgent 并保留 Hook/ToolCallback/run config? |
evidence-driven |
已解决 |
| Q4 |
Gatekeeper |
显式 Node 如何保证当前 run、单次调用和 fail-closed 标准化? |
evidence-driven |
已解决 |
| Q5 |
安全 |
passed checked bindings 如何投影为 verified output/evidence? |
evidence-driven |
已解决 |
| Q6 |
补证据 |
哪些 facts 可触发 evidence retry,completed queries 如何表达? |
evidence-driven |
已解决 |
| Q7 |
Fallback |
前置验证失败与 Composer 后置失败可分别使用哪些材料? |
evidence-driven |
已解决 |
| Q8 |
Prompt |
阶段 2 是否立即修改共享 Verifier Prompt? |
evidence-driven |
已解决 |
| Q9 |
验收 |
阶段 2 是否需要单元/集成测试与 E2E? |
evidence-driven + user rule |
已解决 |
Evidence-driven
| 结论 |
证据来源 |
是否已汇报用户 |
| ReactAgent.call(input, config) 返回 AssistantMessage,现有 AgentLoggingHook 从 config metadata 读取 sessionId/runId |
本地 1.1.2.0 javap、AgentLoggingHook |
已汇报 |
| Executor parser 当前在 VerifierInputHook,Verifier/Composer parser 与 renderer 当前在 ChatService |
定向源码阅读和 references |
已汇报 |
| checked_bindings 提供 claim_id/tool_name/source_invocation_id/raw_path/matched_text/status |
ExecutorGatekeeperService |
已汇报 |
| Gatekeeper.validateRun 使用 run-scoped ToolInvocation repository |
ExecutorGatekeeperService tests/code |
已汇报 |
| Graph path不能注册旧 VerifierInputHook,否则 Gatekeeper 会双执行且输入包含 full tool trace |
阶段 0 ADR、Hook 源码 |
已汇报 |
| evidence retry 只允许 critical no_evidence/indirect_support |
阶段 0 design/ISS-011 |
已汇报 |
| 阶段 1 router 未检查 is_critical,属于实现偏离 |
Router 源码与阶段 0 baseline 对照 |
已汇报 |
| 共享 Prompt 暂时仍服务旧 Sequential path,本阶段直接修改会提前破坏生产 payload |
ChatService agent builder + VerifierInputHook + prompt |
已汇报 |
| Node 输入/安全边界新增且旧解析会重构,单元和 focused regression 必要;E2E 不必要 |
阶段边界和用户规则 |
已汇报 |
User-interview
| 问题原文 |
用户原话 |
确认状态 |
OpenSpec 回写 |
| 阶段 2 是否独立 sm-flow? |
“iss-011里每个阶段,都是一个sm-flow” |
已确认 |
独立 change |
| 是否可提前切生产入口? |
“每个阶段需要归档完并提交才能进入下一个阶段” |
已确认不可提前阶段 3 |
Out of Scope |
| 阶段 2 是否执行 E2E? |
“端到端只在最后阶段全部完成后才验证” |
已确认不执行 |
Acceptance |
| 是否添加单元测试? |
“如果有必要添加单元测试验收的话,就加” |
已确认规则;本阶段判定必要 |
Acceptance |
Context And Handoff
- 阶段 0 archive/commit:design baseline /
581daff
- 阶段 1 archive/commit:routing skeleton /
42ba204
- 当前 change:
chat-diagnosis-stategraph-real-nodes
- 后续 change:
chat-diagnosis-stategraph-chatservice-cutover,只能在本阶段 archive + commit 后创建。
Technical Decisions
Shared protocol components
- 抽取 Executor、Verifier、Composer 解析器,旧 Hook/ChatService 委托新组件。
- 抽取 Composer safe input builder / renderer,旧 ChatService 保持相同输出。
- JSON sanitization 只存在一份共享实现,不在每个 Node copy。
- 抽取过程是行为保持 refactor;现有 focused tests 是回归门禁。
Agent adapter boundary
DiagnosisAgentInvoker 是最小 port:invoke(String, RunnableConfig) -> String。
ReactAgentDiagnosisInvoker 只包装 ReactAgent.call(...).getText()。
- Planner/Executor/Verifier/Composer adapters 各自拥有白名单 input projector、parser 和 status event。
- tests 使用 fake invoker,另有 ReactAgent wrapper test。
Legacy Hook coexistence
- 旧 Sequential path 在阶段 3 前仍通过 VerifierInputHook 执行 Gatekeeper。
- Graph Verifier Agent 不注册该 Hook;显式 Gatekeeper Node 是 Graph 中唯一 validation 入口。
- Parser/enricher 可共享,但 Hook 的 legacy payload/prompt 暂不改变。
- 阶段 3 切换生产入口并同步 Verifier Prompt;阶段 5 删除旧隐式结构。
Gatekeeper normalization
- raw pass → PASS。
- raw fail + severity low_confid → LOW_CONFID。
- raw fail + severity reject → REJECT。
- 缺失、unknown、异常或不一致 → REJECT。
- verified_binding_count 只统计 checked_bindings.status=pass。
Verified projection
- 通过项按 claim_id + source_invocation_id + tool_name + raw_path 与原 binding 精确匹配。
- verified_executor_output 只包含 answer_version 与至少一条 passed binding 的 filtered claims;合法零 claim 保持空列表。
- verified_evidence 只含 claim_id/source_invocation_id/tool_name/raw_path/matched_text。
- hypotheses、失败 binding、未引用 ToolInvocation、raw Executor output 不投影。
Evidence retry
- extractor 要求
is_critical=true 且 verification 为 no_evidence/indirect_support。
- gap 字段:claim_id(从
claim-id: text 提取或空)、fact、verification、reason。
- completed queries 由 verified evidence 的 tool/invocation/path 去重生成。
- prior verified output/evidence 原样只读进入 retry_context。
- 约束固定:max_retry=1、do_not_repeat_successful_queries、only_execute_incremental_queries、preserve_prior_verified_claims。
- Executor 输入声明“增量执行、完整输出”,Java 不合并 claims。
Interface impact
- 等级:L2 internal interface;共享 parser 委托保持旧行为。
- 新消费者:阶段 3 Graph orchestrator/Agent factory。
- 当前外部 API/DB/生产路由:无变化。
- 回滚:revert 本阶段提交;旧 Sequential path仍完整。
- 有意修正:Router 只允许 critical gap,属于对冻结基线的代码修复。
Risks Accepted
- 真实模型尚未执行;Node contract 通过 fake invoker/real service tests证明,阶段 5 才 E2E。
- Prompt 输入说明与 Graph input 的最终同步推迟到阶段 3,避免当前旧生产 Hook 提前不兼容。
- 旧 Hook 暂时仍存在,但不进入 Graph action graph;阶段 5 必须删除。
Architecture Audit
Module and ownership map
Diagnosis Context + RunnableConfig → Agent adapters / deterministic Nodes → owned Graph State fields → DiagnosisGraphRouter → next Node or END → final_answer + orchestration_events。阶段 2 只提供这条可构造链,阶段 3 才由 ChatService 创建 Run、构造 Agent 实例并调用 Graph。
| 模块 |
数据所有权 |
允许依赖 |
diagnosis.protocol |
JSON contract、纯解析结果、安全 input/rendering |
Jackson 与纯 DTO;不依赖 Graph/Hook/ChatService/ThreadLocal |
graph.diagnosis Agent adapters |
白名单输入、Agent attempt status/event |
protocol、注入的 invoker、Graph API |
| Gatekeeper Node |
raw Gatekeeper result、normalized status/count |
ExecutorGatekeeperService、当前 run config |
| Verified Input / Retry Prepare |
verified projection、critical gaps、retry context |
raw result 的只读投影与 protocol DTO |
| Router / Factory |
条件边、有限计数、调用次序 |
Graph State;不解析 Agent raw output |
| legacy Hook / ChatService |
阶段 3 前的生产 Sequential 流程 |
只委托 protocol;不得消费真实 Graph action set |
Lifecycle and coupling audit
Graph State 和 events 都是 invocation-scoped,runId 只从当前 RunnableConfig 获取,Nodes 不持有跨 Run 可变状态。旧路径与 Graph 路径阶段性共享的只有无状态 protocol 组件和 Gatekeeper service,不共享 ThreadLocal 或 Agent output。ReactAgent/invoker 必须构造注入,阶段 2 不复制 ChatService Prompt/Agent factory。唯一有意的阶段性耦合是 legacy consumers 改为委托 protocol,这由旧 focused tests 和完整 revert 保护。阶段 3 前生产入口、DB、Trace、Prompt 均保持隔离。
Cross-artifact alignment
| 对齐链 |
结果 |
证据 |
| brief/proposal 目标、范围、非目标 → proposal |
已对齐 |
独立阶段边界、真实 Nodes、无生产切换均明确 |
| proposal 承诺与约束 → design |
已对齐 |
invoker、共享组件、Gatekeeper、投影、retry、Fallback、L2 均有决策 |
| design 架构/接口结论 → specs/tasks |
已对齐 |
中立 protocol 包、构造注入、fail-closed 和生产隔离均有任务/行为 |
| specs 可观察行为 → tasks 可执行切片 |
已对齐 |
每个 requirement 至少由一个实现任务和一个测试/验收任务覆盖 |
Audit result
审计发现共享协议组件包所有权与 Agent 实例装配边界需要显式化,已回写 design/tasks。未发现状态字段、路由计数、run 生命周期或阶段边界的新冲突。接口影响维持 L2,消费者都在本 change 与下一阶段明确范围内。剩余风险是共享抽取的旧行为漂移和 binding 投影泄漏,均有 focused regression 与 mixed-binding tests。架构风险可接受,无未解决问题。
Commit Gate
- proposal/design/specs/tasks:全部存在,OpenSpec status
isComplete=true。
- 当前 change strict validation:通过。
- 主 specs strict validation:13 passed,0 failed。
- 规格结构:9 requirements、22 scenarios;tasks:27 个 checkbox 切片。
- Cross-artifact:4/4 已对齐,gap=0。
- 接口影响:L2,已在 design 独立章节记录消费者、兼容和回滚。
- Question pool:所有 evidence-driven 已汇报;所有 user-interview 已确认;无未决项。
- Preflight scope:
git diff --check 通过;Commit checkpoint 未修改业务代码。
- 结论:Draft OpenSpec 达到可执行状态,创建
.committed。
Apply Authorization
- 用户原话:“直接实现吧,不用找我授权了”。
- 解释:阶段 2–5 后续 checkpoint 可在前置门禁通过后直接继续,不再因 Apply 或 Archive 授权暂停。
- 不扩大范围:每阶段仍须独立 OpenSpec、验收归档、Git commit;阶段 0–4 不做 E2E,阶段 5 才统一执行。
Pre-apply Research
Reference implementations read
src/main/java/com/superbiz/agent/hook/VerifierInputHook.java:Executor JSON sanitization、parse status、tool-name normalization、唯一 invocation 回填与 legacy Gatekeeper payload。
src/main/java/com/superbiz/agent/service/ChatService.java:Verifier claim/fact parser、Gatekeeper ceiling、Composer allowed-material builder、Composer parser/safe renderer、旧 retry context。
src/main/java/com/superbiz/agent/service/ExecutorGatekeeperService.java:validateRun、severity normalization source、checked binding 与 matched_text 结构。
src/main/java/com/superbiz/agent/graph/diagnosis/DiagnosisGraphFactory.java:config-aware action ports、technical retry/evidence retry counter 所有权和 recursion limit。
src/main/java/com/superbiz/agent/graph/diagnosis/OrchestrationEvent.java 与 src/test/java/com/superbiz/agent/graph/diagnosis/ScriptedDiagnosisGraphActions.java:每 attempt 单 event 形态。
src/main/java/com/superbiz/agent/hook/AgentLoggingHook.java:RunnableConfig metadata 中 sessionId/runId 的审计读取方式。
src/test/java/com/superbiz/agent/hook/VerifierInputHookTest.java、ChatServiceSequentialAgentTest.java、DiagnosisGraphRoutingTest.java:JUnit 5、Mockito 边界替身和 CompiledGraph observable behavior 测试风格。
- 本地
1.1.2.0 JAR javap:ReactAgent.call(String,RunnableConfig) 与 RunnableConfig.threadId/metadata 公共 API。
Technology inventory
| 类别 |
项目标准 / 本阶段使用 |
| JSON contract |
Jackson ObjectMapper、LinkedHashMap 保持稳定字段顺序;共享 sanitization 只存在一份 |
| Graph Node |
AsyncNodeActionWithConfig 返回 CompletableFuture<Map<String,Object>>;state 默认 Replace、events Append |
| Agent boundary |
构造注入的 DiagnosisAgentInvoker;ReactAgent wrapper 透传同一个 RunnableConfig |
| Run scope |
config.metadata("runId") 为 Gatekeeper 唯一运行边界;缺失即 fail closed |
| Error handling |
合法 contract/invalid output/temporary/permanent 分离;unknown exception 不推断为可重试 |
| Tests |
JUnit 5;只在 ReactAgent、repository 等系统边界使用 fake/mock;Node/CompiledGraph 走公开 action/graph 接口 |
| Request/response |
本阶段不改 Controller/DTO/API,不适用 |
| MQ/Consumer |
本阶段不涉及,不适用 |
| DB/Trace/Prompt |
本阶段禁止修改,阶段 3 处理 |
Reuse and new infrastructure
- 新建中立
com.superbiz.agent.diagnosis.protocol:JsonPayloadSupport、Executor/Verifier/Composer protocol、safe input/rendering、EvidenceGapExtractor;不得依赖 Graph/Hook/ChatService/ThreadLocal。
- 新建
graph.diagnosis Node 层:invoker wrapper、failure classifier、四个 Agent adapters、Gatekeeper、Verified Input、Retry Prepare、Fallback 和 action assembly。
- 不新建 Prompt/Agent factory;阶段 3 通过构造注入已有 ReactAgent 实例。
- 不新增 Maven dependency、数据库迁移、配置项或生产 consumer。
Pre-apply conclusion
参考实现、API 签名、异常和测试标准已足以指导实现;未发现 devflow/OpenSpec 冲突。进入 TDD tracer bullet,先锁定共享 Executor parser 的合法 no-evidence 与 malformed 行为。
Apply Completion And Verification
Assembly alignment
- 首个共享 protocol 模块与最终真实 Graph action assembly 均逐项对照 design/specs:invoker 显式透传 RunnableConfig,Gatekeeper 单次 fail-closed,Verified Input 精确投影,Verifier/Composer 固定输入重试,critical evidence retry 与两类 Fallback 边界全部落地。
DiagnosisGraphFactory 继续独占技术重试计数、evidence retry 计数和 Planner mode/reset;Node 不重复拥有编排计数。
- 新增源码中无
ThreadLocal、VerifierInputHook、tool_trace_summary、raw_executor、TODO 或 FIXME;protocol 包无 Graph/Hook/ChatService 反向依赖。
ChatService 无 Diagnosis Graph/CompiledGraph 引用,生产切换保持在阶段 3;DB migration、Trace DTO/entity/repository 和 prompts 均无 diff。
Automated verification
- 新 protocol/Node/真实 CompiledGraph/Router/Trace focused suite:通过。
- 旧
ChatServiceSequentialAgentTest、VerifierInputHookTest、ExecutorGatekeeperServiceTest 回归:通过。
- 合计 100 tests,0 failures,0 errors,0 skipped。
mvn -q -DskipTests test-compile:通过。
openspec validate chat-diagnosis-stategraph-real-nodes --strict:通过。
openspec validate --specs --strict:13 passed,0 failed。
git diff --check:通过;仅报告 Git 既有 LF/CRLF 转换提示,无 whitespace error。
Deferred final verification
- 阶段 2 按用户确认不运行 Maven live E2E,不启动应用,不检查
logs/,不查询数据库。
- 上述端到端、日志和
scripts/query_mysql.py 数据库核验统一保留到阶段 5 全部实现完成后执行。