Chat Diagnosis StateGraph Routing Skeleton Decisions
Question Pool
| # |
维度 |
问题 |
模式 |
状态 |
| Q1 |
术语 |
阶段 1 的 Graph State、event、trace 含义从哪里继承? |
evidence-driven |
已解决 |
| Q2 |
边界 |
阶段 1 是否接入 ChatService 或真实 Agent/Service? |
evidence-driven |
已解决 |
| Q3 |
技术 |
锁定 1.1.2.0 是否支持所需 Node/Edge、策略和 recursion limit? |
evidence-driven |
已解决 |
| Q4 |
技术 |
Node action port 是否需要 RunnableConfig? |
evidence-driven |
已解决 |
| Q5 |
验收 |
阶段 1 是否有必要添加单元测试? |
evidence-driven + user rule |
已解决 |
| Q6 |
接口 |
新骨架的接口影响等级与消费者是什么? |
evidence-driven |
已解决 |
| Q7 |
循环 |
recursion limit 应取多少,是否替代业务计数? |
evidence-driven |
已解决 |
| Q8 |
阶段 |
是否在本 change 实现真实 nodes、DB、Trace API 或旧代码清理? |
user-interview(已由六阶段口径确认) |
已解决 |
Evidence-driven
| 结论 |
证据来源 |
是否已汇报用户 |
| 阶段 1 必须完整继承阶段 0 baseline |
archived design/spec/ADR |
已汇报 |
| 本阶段只做 Fake Node 骨架,不接真实模型 |
ISS-011 阶段 1/2 边界 |
已汇报 |
| 1.1.2.0 支持 AsyncNodeActionWithConfig、AsyncEdgeActionWithConfig、conditional edges、Replace/Append、recursionLimit 和 threadId |
本地 JAR javap / javap -c |
已汇报 |
| AppendStrategy 将 list/collection 追加为有序列表,可用于 node terminal events |
本地 AppendStrategy bytecode |
已汇报 |
| 路由是新增行为且分支多,单元测试有必要 |
阶段 1 完成标准与用户“必要则加”规则 |
已汇报 |
| 最坏合法路径少于 20 次 Node 执行,limit 32 有安全余量 |
冻结路由矩阵的路径计数 |
已汇报 |
| 当前仓库没有 Graph 包或实现 |
rg / package 目录核查 |
已汇报 |
| 生产代码将直接 import Graph Core,必须从传递依赖提升为 BOM 管理的直接依赖 |
pom 与 dependency tree / 架构审计 |
已汇报 |
User-interview
| 问题原文 |
用户原话 |
确认状态 |
OpenSpec 回写 |
| 阶段 1 是否应独立执行 sm-flow? |
“iss-011里每个阶段,都是一个sm-flow” |
已确认 |
本 change 独立边界 |
| 阶段 1 是否执行 E2E? |
“端到端只在最后阶段全部完成后才验证” |
已确认 |
Out of Scope / Acceptance |
| 阶段 1 是否添加单元测试? |
“如果有必要添加单元测试验收的话,就加” |
已确认规则;本阶段判定必要 |
Acceptance |
| 是否可提前实现阶段 2–5? |
“每个阶段需要归档完并提交才能进入下一个阶段” |
已确认不可提前 |
Out of Scope |
Context And Handoff
- 前置 archive:
openspec/changes/archive/2026-07-17-chat-diagnosis-stategraph-design-freeze/
- 前置 commit:
581daff
- 当前 change:
chat-diagnosis-stategraph-routing-skeleton
- 后续 change:
chat-diagnosis-stategraph-real-nodes,只能在本阶段 archive + commit 后创建。
Technical Decisions
Package and API
- 新包:
com.superbiz.agent.graph.diagnosis。
pom.xml 显式声明 Graph Core,版本继续由现有 BOM 管理。
- Graph 工厂接收 config-aware Node action ports,不依赖 Spring Bean 或真实 Agent。
- Fake actions 只放
src/test。
- 状态读取集中在 typed helper/router,避免各 edge 复制字符串解析。
Retry ownership
- Planner/Verifier/Composer Node wrapper 根据进入节点前的上次技术失败状态增加各自 retry count。
- 第一次失败时 count=0,允许 self-loop;重入后 count=1,第二次失败直接 Fallback。
- Evidence Retry Node 将 run-level evidence count 增加一次并重置 planner retry count。
- Edge 只选择 route,不隐式修改状态。
Event and trace
- 每个 Fake/后续真实 Node 返回一个 event list,AppendStrategy 负责累积。
- event 包含 node/outcome/reasonCode/attempt,不包含 payload。
- trace builder 由相邻 events 生成 transition;final node/reason 来自最后 event。
- events 为空时拒绝构造 trace,避免伪造路径。
Interface impact
- 等级:L2 internal interface。
- 新消费者:阶段 2 Node adapters、阶段 3 ChatService orchestrator、阶段 4 tests。
- 外部 API/DB/运行路径:无变化。
- 回滚:revert 本阶段提交即可;因为未接生产入口,没有数据迁移。
- 兼容:后续 action adapters 必须实现已冻结 ports,不得传递父 State 全量数据。
Risks Accepted
- Stage 1 skeleton 会暂时存在但未被生产调用,这是阶段边界要求,不是死代码最终状态。
- 真实 Agent 状态映射尚未验证,由阶段 2 独立 change 负责。
- Maven E2E 不运行,生产路径完全未改变。
Apply Evidence
- Task 1.1:显式声明 BOM 管理的 Graph Core;新增 26 个 state keys、状态枚举、拓扑/route/reason 常量、默认 Replace + events Append 策略和安全 typed reads。
- Task 1.2:新增不可变 event/transition/trace records,构造期拒绝空 routing metadata 和非法计数,map 输出只有冻结字段。
- Task 2.1:新增八个 non-null config-aware action ports,Fake/真实 Node 共用同一 Graph 接入面。
- Task 2.2:新增纯 router;所有未知/缺失状态 fail closed,LOW_CONFID guard 只读 facts_checked,不构造 retry context。
- Task 2.3:Graph Factory 注册八节点和全部条件边;wrapper 独占 retry/evidence control state,compile recursion limit=32。
- 首模块 Maven compile:passed(31s),锁定 1.1.2.0 API 假设成立。
- Task 3.1:trace builder 从 event 单向派生 transitions/final reason/degraded/evidence count,空或异类 events 显式失败。
- Task 4.1:新增严格 FIFO Fake Node fixture,记录 sequence/calls/threadId,每 attempt 只追加一个 terminal event,意外调用立即失败。
- Task 4.2:真实 CompiledGraph normal/Planner/Executor/Gatekeeper focused tests 首轮通过(Maven exit 0,约 67s)。
- Task 4.3:Verifier/evidence/Composer 路由与独立计数测试通过(Maven exit 0,约 12s)。
- Task 4.4:routing + trace focused suite 通过(Maven exit 0,约 28s),覆盖事件顺序、degraded、map 白名单、不可变性和非法输入。
- Task 5.1:35 tests(29 routing + 6 trace)全通过;Maven test compilation、change strict 1/1、主 specs 12/12、diff check 均通过。
- Task 5.2:现有 production refs=0,新 Graph 对真实 Service/DB/Trace refs=0,23 个 changed paths 全部命中阶段白名单;Maven E2E/log/DB 按用户口径保留到阶段 5。
- Review:补齐所有正常节点 threadId 传播、Verifier REJECT→Composer 和 completed-without-verdict fail-closed 用例;增强后 focused suite exit 0。
Cross-Artifact 对齐检查
| 上游 → 下游 |
检查内容 |
状态 |
| brief/prd → proposal |
阶段 1 目标、Fake Node 边界、测试口径和 E2E 非目标 |
已对齐 |
| proposal → 设计产物 |
direct dependency、状态、ports、router、counter、trace、测试架构 |
已对齐 |
| 设计产物 → specs/tasks |
所有可观察路由、终止、安全默认和实现模块 |
已对齐 |
| specs → tasks |
编译、全路由、trace、focused tests、生产隔离检查 |
已对齐 |
Gap:无。
Architecture Audit
输入是 run-scoped 初始 state 与 RunnableConfig,处理链是 CompiledGraph → config-aware action ports → deterministic router/counters,输出是最终 state 与纯路由 trace;阶段 1 没有 Controller/Service/DB 消费者。Graph State 由单次 invoke 所有,events 只由 Node append,transitions 只由 builder 派生,避免双写。阶段 2 只实现 action ports,阶段 3 才将 orchestrator 交给 ChatService,因此当前未接生产入口是刻意生命周期边界。审计发现的唯一缺口是 Graph Core 直接依赖所有权,已回写 proposal/design/tasks。与阶段 0 archive 无冲突,L2 风险可由 Fake Node CompiledGraph tests 和 revert 单提交控制。