# 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 单提交控制。