# Decisions: single-react-aci-tool-contracts ## 规模与入口 - 分档:standard。 - 入口:ISS-014 阶段 1,前置 `single-react-design-freeze` 已 Archive 并由 Git commit `58c3910` 固化。 - 目标:冻结三类 evidence Tool 的 Agent-facing ACI 契约,不接入新运行链路。 ## Context - `devflow/index.md` 命中 `single-react-design-freeze`、`modular-rag-pipeline` 和 `evidence-trace-hardening`。 - `devflow/glossary/CONTEXT.md` 已定义 Diagnosis Harness、Invocation Status、Evidence Status 与 Evidence Tools。 - 阶段 0 已确认 `tool_call_id` 使用框架 ID、两套状态语义分离、阶段串行门禁和阶段 6B 才公开切换。 - 未发现根目录旧 `CONTEXT.md` 与 glossary 冲突。 ## Question Pool | 维度 | 问题 | 模式 | 证据与结论 | 状态 | |---|---|---|---|---| | 术语 | invocation lifecycle 与 evidence result 是否使用同一状态? | evidence-driven | ISS-014 5.2、阶段 0 contract 明确分离;分别复用 `InvocationStatus` 与 `EvidenceStatus`。 | 已解决并汇报 | | 术语 | `tool_call_id` 由谁生成、从哪里取得? | evidence-driven | Spring AI `AssistantMessage.ToolCall.id()` 与 Alibaba `ToolCallRequest.getToolCallId()` 提供框架 ID;普通 `ToolContext` 不自动加入该 ID。Harness 不生成第二套 ID。 | 已解决并汇报 | | 边界 | 阶段 1 是否直接改旧 RAG/日志执行签名与返回值? | evidence-driven | ISS-014 阶段 1 只冻结 Contract,投影在阶段 3B、公开切换在阶段 6B;本阶段只新增契约代码和测试。 | 已解决并汇报 | | 边界 | 日志阶段是否实现真实 CLS/MCP 或保留 Topic discovery? | evidence-driven | ISS-014 8.1 明确继续 Mock、删除 Agent 侧 discovery、真实适配器不在本 Issue 提前设计。 | 已解决并汇报 | | 验收 | 如何证明契约已冻结且有界? | evidence-driven | 对三类独立 DTO 做精确 JSON、不可变集合、状态和描述泄漏测试;不以旧 Tool 集成测试代替。 | 已解决并汇报 | | 技术 | 框架 ID 能否在后续 Harness 边界取得? | evidence-driven | 本地依赖 Spring AI Alibaba 1.1.2.0 暴露 `ToolInterceptor.interceptToolCall(ToolCallRequest, ToolCallHandler)`,request 含 `toolCallId`。 | 已解决并汇报 | ## Grill 结论 - 术语、边界、验收三类问题均已由代码、依赖 API、阶段 0 档案和 ISS-014 证明。 - 没有需要新增用户偏好或风险取舍的 `user-interview` 问题;不代理确认任何新方向。 - `grill-with-docs` 要求的代码可证问题已先查证;结论已向用户汇报。 - Proposal 已回写框架 ID 接入点、旧运行链路不切换、Mock 边界和 L2 接口影响。 ## 已确认决策 - DTO 放在 Harness 的 Tool Contract 边界,复用阶段 0 的共享状态枚举,不在旧 `dto` 包继续堆叠协议。 - 三类结果只携带 `evidence_status`,canonical invocation 的 `status` 保持独立;阶段 1 通过测试冻结枚举,不提前定义存储实现。 - Tool description 使用代码常量冻结,后续 Tool adapter 注册时复用;旧 `@Tool` 注解本阶段不改,避免提前改变运行行为。 - RAG 输入仅保留 `query`;日志输入仅保留逻辑 `topic/query/lookback_minutes`;MySQL 输入仅保留逻辑 `data_source/sql/params`。 - 日志 `source_kind` 首版固定支持 `MOCK` 契约值,但保留 enum 扩展位置给后续真实适配器 change 审查。 ## 能力与工具限制 - Discover 能力来源:`sm-flow` + `grill-with-docs`。 - 仓库要求的 `codebase-retrieval` 和 LSP 工具在当前工具集中不可用;已用 `rg` 引用搜索、源码阅读和本地依赖 `javap` 补足事实核对。该限制不改变契约方向,但后续 Apply 仍需通过编译和引用测试验证。 ## Cross-artifact 对齐 | 链路 | 状态 | 结论 | |---|---|---| | brief 目标/范围/非目标 -> proposal | 已对齐 | 三类 DTO、状态、框架 ID、短描述和不切旧运行链路均有对应。 | | proposal 范围/约束/承诺 -> design | 已对齐 | 包边界、ID 来源、record/defensive copy、三类 Schema 和迁移顺序均已设计。 | | design 决策/接口影响/风险 -> specs/tasks | 已对齐 | L2 边界、字段、状态、描述、Mock provenance 和运行不切换均有可验证 requirement 与任务。 | | specs 可观察行为 -> tasks | 已对齐 | 每类 Contract 都有实现与独立测试,另有状态、回归和 diff scope 验证。 | ## Architecture Audit - 能力来源:`zoom-out`,以项目 glossary 的 Diagnosis Harness、Evidence Tools、Invocation Status 和 Evidence Status 术语审计。 - 当前输入到输出链路仍为 `ChatController/ChatService` 或 `AiOpsService -> ReactAgent -> LookupKnowledgeTool/QueryLogsTools -> 旧结果`,新契约没有运行消费者。 - 未来链路为 `Diagnosis Agent -> Alibaba ToolInterceptor/Harness -> typed Request -> adapter/store/projector -> bounded Result -> Agent observation`,阶段 1 只占有 typed contract 边界。 - 数据所有权保持明确:框架拥有 `tool_call_id`,canonical invocation 拥有生命周期,Tool-specific result 拥有证据语义与有界内容。 - 主要耦合风险是新旧契约短期并存被误当成已迁移;通过独立包、无旧调用方修改和后续阶段门禁控制,无 ADR 冲突。 ## Commit Gate Preflight - proposal、design、specs、tasks 文件完整,OpenSpec CLI 状态为 complete。 - strict validation:`openspec validate single-react-aci-tool-contracts --strict` 通过。 - question pool 中没有未汇报的 evidence-driven 结论或未确认的 user-interview 问题。 - 接口影响为 L2,当前运行消费者零变更;阶段 6B 的 L4 切换保持独立。 - cross-artifact 四段对齐无 gap,架构审计未发现需要回写的新实现约束。 - Apply 已由用户对 ISS-014 全阶段的持续授权覆盖;仍严格限制在本 Committed OpenSpec tasks 内。 ## Pre-apply Research ### 参考实现 - `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`:确认旧 RAG 暴露 `LookupResult`、ContextPack 和检索 Trace,本阶段不改。 - `src/main/java/com/superbiz/agent/agent/tool/QueryLogsTools.java`:确认旧日志输入包含 region/logTopic/limit、存在 Topic discovery 和 mutable nested DTO,本阶段不改。 - `src/test/java/com/superbiz/agent/tool/LookupKnowledgeToolTest.java`:现有 RAG 行为回归基线。 - `src/test/java/com/superbiz/agent/agent/tool/QueryLogsToolsTest.java`:现有 Mock 日志行为回归基线。 - `src/main/java/com/superbiz/agent/harness/contract/*.java`:Java 17 record、Jackson snake_case 和共享状态枚举风格。 ### 技术栈清单 - 请求/响应标准:Java 17 record + Jackson `@JsonProperty`,集合构造时 defensive copy。 - Tool 定义:当前使用 Spring AI `@Tool`,新名称/描述先以常量冻结,后续 adapter 注册复用。 - 框架调用 ID:Spring AI Alibaba `ToolCallRequest.getToolCallId()`;普通 `ToolContext` 不作为 ID 来源。 - 异常与校验:本阶段只冻结结构;Schema、ID、权限、范围和状态组合错误由后续 Pre-Tool/Projector 显式返回安全 `ERROR`。 - MQ/Consumer/加密验签:本 change 不涉及。 ### 新建类型 - `AgentToolContracts` 与 contract defensive-copy helper。 - RAG Request/Result/Evidence。 - Log Topic/SourceKind/Request/Result/Scope/Pattern/Event。 - MySQL Request/Result。 - 三个独立 contract test classes。 ### 影响半径 - 新增包当前应无生产调用方;旧 Chat/AIOps、Tool、Controller、Repository 和配置文件均不修改。 - 通过 focused compile/tests 和 `rg`/diff scope 证明边界。 ## Apply 结果 - 冲突分类:未发现 OpenSpec 遗漏、代码偏离或方向不确定项。 - 新增共享 ACI Tool 名称/描述、defensive-copy helper 和三类 typed Request/Result records。 - 新增三个独立契约测试,覆盖精确 JSON、状态分离、框架 ID 原样保留、不可变集合、Mock provenance 和基础设施字段排除。 - 首模块对齐:共享/RAG/日志/MySQL contract 与 design/tasks 全部完成;旧 runtime 接入保持 TODO,归属后续 3B/3C/6B changes。 ## Apply 验证 - 编译:`mvn -q -DskipTests compile` 通过。 - 新契约:`mvn -q '-Dtest=RagToolContractTest,QueryLogsToolContractTest,MysqlToolContractTest' test` 通过。 - 旧行为回归:`mvn -q '-Dtest=HarnessContractTest,LookupKnowledgeToolTest,QueryLogsToolsTest' test` 通过。 - 静态 scope:新 contract 生产类型当前无旧运行消费者;受保护的 Tool、Chat/AIOps、Controller、Repository 和配置文件 diff 为空。