9.5 KiB
Context
阶段 6B 后,POST /api/chat 已经只调用新 ChatApplicationUseCase,但仓库仍有四类遗留:一是 bundled frontend 可达的 /api/ai_ops Supervisor/Planner/Executor 链;二是只有测试引用的 ChatService、Redis Session API、Verifier/Gatekeeper/ThreadLocal;三是被新 Harness adapter 复用但仍带旧 @Tool 和 DB recorder 副作用的 RAG/log backend;四是仍描述旧架构的文档和 demo。
新 Harness 已以 Redis canonical invocation 保存当前 Run 完整 Tool 调用并用 EvidenceGuard 验真,但 ToolBoundary 没有写长期 tool_invocation audit。当前 AgentLoggingHook 又会持久化/日志输出模型正文、Tool arguments 和 thought,且回退到 Session ThreadLocal。阶段 7 必须同时删除旧链和收紧审计,否则代码结构与最终 E2E 都不能满足 ISS-014。
这是 L4 协议/前端删除和跨模块物理重构。历史数据库表与历史数据保持不变;现有 chat_session JPA 元数据仍由 JpaChatRunStore 使用,不属于 Redis conversation Session 遗留。
Goals / Non-Goals
Goals:
- 业务代码只剩一个拥有 Tool loop 的 Diagnosis ReAct Agent,公开诊断只剩
/api/chat。 - 删除旧 Chat/AiOps/Session 编排、Hook、ThreadLocal、prompts、Tool compatibility annotations 和过时测试。
- RAG/log backend 只通过 Harness adapters 调用,不自行写旧 ToolInvocation。
- AgentStep 与 ToolInvocation durable audit 按 exact Run 持久化有界脱敏 metadata。
- 文档、issues、OpenSpec strict 状态与最终代码一致。
- 真实启动应用并完成 SSE、日志、MySQL exact-run E2E。
Non-Goals:
- 不改变 Intent Router、Diagnosis Draft、EvidenceGuard、SemanticGuard、Fallback 或 SSE 五事件语义。
- 不删除历史表/数据,不做 schema destructive migration。
- 不实现真实 CLS 或生产业务 MySQL datasource live 连接。
- 不改 RAG 算法、Trace API response schema 或 UI 视觉设计。
Decisions
1. 删除 legacy AiOps 和 Redis Session surface,不迁移第二条诊断链
删除 AiOpsController、AiOpsService、AIOps DTO/config/rule evaluation、三个 prompts、前端按钮/consumer 和相应 tests。删除 ChatSessionController、Redis SessionManager/SessionContext 和 tests。告警诊断通过 /api/chat 提交自然语言或结构化文本,由同一个 Intent Router 进入 Diagnosis。
替代方案是把 /api/ai_ops 适配到新 use case;拒绝,因为它保留第二个公开诊断协议和前端双轨,违反 ISS-014 唯一入口与无兼容分支目标。chat_session entity/repository 不删除,因为它是当前 Run 目录与 PreviousTurn 生命周期的一部分。
2. 旧 Chat orchestration 按闭包删除
删除 ChatService 及其 Sequential Planner/Executor/Verifier/Composer tests、旧 prompts、Verifier/Gatekeeper helpers、Skill metadata hook、Token ThreadLocal wrapper、旧 Tool trace summary/recorder。删除顺序为公开 caller -> service/orchestration -> helper/hook/context -> resources/tests,并在每层后编译/引用扫描。
SelfEvaluationMergeService、DiagnosisTraceService、repositories 和 eval 基础设施若仍有非旧链调用则保留。替代仅取消 Spring annotation 而保留死类;拒绝,因为阶段 7 明确要求物理清理。
3. RAG/log 是 backend,不是 Agent-facing Tool
保留 LookupKnowledgeTool.lookupKnowledge 的检索管线和 QueryLogsTools.queryLogs 的 Mock/边界实现,供 RagToolAdapter/QueryLogsToolAdapter 调用;移除所有 @Tool/@ToolParam、旧 topic discovery contract、Session ThreadLocal、session dedup 和 ToolInvocationRecorder。Agent-facing schema/description 只来自 HarnessEvidenceTools 与 AgentToolContracts。
替代完全重写 RAG/log;拒绝,因为阶段 3B 已验证 adapter/projector contract,阶段 7 只需清除双 contract 与副作用。
4. Agent audit 使用 Harness-native metadata-only Hook
新增 Harness audit hook,强制从 RunnableConfig 读取 exact sessionId/runId。before-model 只保存 message count/roles;after-model 只保存是否有文本、是否有 Tool call、Tool names 和 duration,不保存 message content、model output text、Tool arguments、Prompt 或 Thought。缺少 metadata 时跳过持久化并记录安全 warning,不回退 ThreadLocal。
替代继续修补 AgentLoggingHook;拒绝,因为旧类包含 verifier 特例、Token ThreadLocal、正文日志和 thought persistence,保留会让旧边界继续存在。
5. ToolBoundary 通过安全 port 写 durable audit
新增 ToolInvocationAuditSink 和不可变 audit event。ToolBoundary.execute 在 canonical 结果确定后调用 sink;event 只包含 sessionId、runId、toolCallId、toolName、InvocationStatus、EvidenceStatus、stable error code、duration、request/agent-result byte count。audit 调用 fail-open:JPA 审计失败写 warning,但不改变已经确定的 Tool observation;canonical Redis store 仍按原设计 fail-closed。
JPA adapter 复用现有 tool_invocation 表:input_params 只保存 tool_call_id/request_bytes,output_preview 只保存 status/evidence_status,output_length 保存 agent result bytes,error_message 只保存 stable error code。禁止 raw response、完整 request、SQL、日志正文和模型内容。
替代让旧 backend recorder 继续双写;拒绝,因为它依赖 ThreadLocal、不同 Tool 各自实现且可能保存大 payload。替代审计失败阻断业务;拒绝,因为 durable audit 不是 canonical evidence truth source。
6. 文档与 issue 以当前单链架构为准
重写当前 MVP、Agent、Harness、Trace/Demo 文档中的旧双入口与多 Agent 描述;ISS-012/ISS-013 标记由 ISS-014 吸收并归档。历史架构文档保留在 archive,不篡改历史。
7. 最终 E2E 使用 exact metadata identity
启动 Spring Boot 后向 /api/chat 发送固定 payment-timeout 诊断,严格解析 named SSE,取得 metadata sessionId/runId 并要求 content|failure -> done。检查 logs/ 不含 Prompt/Thought/raw Tool payload/stack leakage;使用 scripts/query_mysql.py 按 exact runId 查询 diagnosis_run、agent_step、tool_invocation,核对 intent/outcome/status、唯一 Diagnosis Agent、Tool 名称/次数、同一 identity 和最终 safe content。
query_logs 使用 Mock,query_mysql 使用配置的隔离 datasource contract;不声称真实 CLS/生产业务库 live。若真实模型选择非 Diagnosis intent,则使用明确诊断 query 重试一次,不伪造数据库结果。
Module and Ownership Audit
Browser POST /api/chat
-> ChatController / ChatSseSession
-> ChatApplicationUseCase
-> Intent Router
-> System / Knowledge / Diagnosis executor
-> Diagnosis Harness
-> Diagnosis Agent (only Tool loop)
-> HarnessEvidenceTools
-> ToolBoundary
-> Redis canonical invocation (full, TTL)
-> Durable audit sink (bounded metadata)
-> EvidenceGuard / SemanticGuard / Release
-> named SSE safe content
-> diagnosis_run + agent_step + tool_invocation exact-run Trace
- Application owns Session/Run/PreviousTurn;Controller 不拥有业务状态。
- Core owns budget/cancel/lifecycle;Diagnosis Agent owns diagnosis authorship;Guards own verification/release。
- Redis canonical invocation owns short-lived complete Tool truth;MySQL ToolInvocation owns long-lived metadata audit。
chat_sessionis current JPA run directory;Redis SessionContext is legacy conversation memory and is removed。- 最大耦合风险是复用 backend 时旧 annotations/recorder 被 Spring 自动发现;static scan + context startup 覆盖。
Interface Impact
- Level: L4 breaking HTTP/frontend contract。
- Removed:
POST /api/ai_ops、POST /api/chat/clear、GET /api/chat/session/{sessionId}、GET /api/chat/session/{sessionId}/runs、legacy AiOps message-wrapper SSE。 - Retained:
POST /api/chatnamed SSE、Trace/feedback/document/search APIs。 - Consumer migration: bundled frontend 同 commit 删除 AiOps 按钮和 consumer;外部调用方迁移到
/api/chat。 - Rollback: 整体回滚阶段 7 commit;不单独恢复旧 endpoint 或 old Tool discovery。
Risks / Trade-offs
- [外部 AiOps caller 失败] -> L4 文档明确迁移到
/api/chat,不提供双轨。 - [删除 bean 导致 context 启动失败] -> compile、focused context test、全量 tests、真实 Spring startup 分层验证。
- [backend 仍被 ToolCallbackProvider 发现] -> 删除 annotations/imports 并静态扫描旧 Tool 名/description。
- [audit 泄漏敏感内容] -> typed metadata-only event + serialization tests + DB query preview inspection。
- [audit 写失败丢 Trace 明细] -> warning + Run 主记录仍完成;验收环境要求 audit row 存在,生产运行可观测 failure。
- [live 环境依赖不可用] -> 先检查服务与启动日志,分类环境/实现失败;不降低为假 E2E。
Migration Plan
- 删除 frontend/Controller/Service 可达旧入口和旧 orchestration 闭包。
- 解耦 RAG/log backend,替换 Agent/Tool durable audit。
- 删除剩余 dead resources/tests/config,跑 compile/focused/full regression 和 static scans。
- 更新 docs/issues/OpenSpec,并修复已知 strict validation。
- 启动应用,执行 final SSE/log/DB E2E,记录 exact identity evidence。
- 同一 commit 部署所有删除与文档;回滚整体回滚该 commit。
Open Questions
- None。live 默认值是否需要校准由 E2E 数据决定,但不会改变 architecture direction。