# Session / Run / Trace Isolation ## 背景 同一个 `sessionId` 以前同时代表多轮 Chat 上下文和一次持久化诊断 Trace。端到端验证发现,同一 `sessionId` 连续两轮 Chat 时,Redis 多轮上下文是正确的,但 MySQL 中 `diagnosis_session` 会被后一轮覆盖,`agent_step` 和 `tool_invocation` 会按同一个 `session_id` 混在一起。 这会导致 Trace 回放、Verifier/Evaluation 读数、Feedback 绑定和 `case_library` 来源都可能跨轮污染。 ## 目标 - 将会话态和运行态拆开:`chat_session` 保存会话元数据,`diagnosis_run` 保存一次诊断运行。 - 引入正式 API 字段 `runId`,作为一次可回放诊断执行的边界。 - `agent_step` 和 `tool_invocation` 保留原 Trace 明细角色,新增 `run_id` 并按 run 隔离读写。 - Trace、Feedback、CaseLibrary、AIOps、demo 脚本和 Trace UI 都支持 run-aware 流程。 - 保留旧 `diagnosis_session` 作为历史兼容和回滚表。 - 完成 Maven E2E、DB 检查、日志检查和 baseline drift 验证。 ## 范围 - Flyway/JPA 增加 `chat_session`、`diagnosis_run`,并给 `agent_step`、`tool_invocation` 增加 `run_id`。 - Chat 每次有效执行创建一个新的 `diagnosis_run`,响应返回 `sessionId + runId`。 - Trace API 支持 latest-run fallback 和 exact-run 查询:`GET /api/diagnosis/{sessionId}/trace?runId=...`。 - 新增 run list API:`GET /api/chat/session/{sessionId}/runs`。 - Feedback 优先绑定 `runId`,缺省时短期 fallback 到 latest run 并返回 `fallbackToLatestRun=true`。 - AIOps 每次有效执行创建并透出 `runId`,SSE 保持 `message` event name 并发送 `type=metadata`。 - MVP demo、Trace UI、表文档和架构文档统一为 `chat_session -> diagnosis_run -> trace detail(run_id)`。 ## 非目标 - 不新增 `diagnosis_trace` 或 `trace_event` 主表。 - 不实现完整 run-list UI。 - 不删除旧 `diagnosis_session`。 - 不改变 Redis 对话历史窗口策略。 - 不把完整多轮正文历史持久化到 MySQL。 - 不尝试把历史混合 trace 还原成真实多轮边界。 ## 关联 - OpenSpec: `openspec/changes/archive/2026-07-10-session-run-trace-isolation` - Change slug: `session-run-trace-isolation` - 分档: complex