Files

8.9 KiB
Raw Permalink Blame History

Decisions: single-react-harness-run-context

规模与入口

  • 分档:complex。
  • 入口:ISS-014 阶段 2;阶段 0/1 已分别由 Git commit 58c3910、4274f33 固化并 Archive。
  • 目标:建立后续 Tool、Agent、Guard 和入口共同依赖的显式 Harness 运行边界,不接旧 ChatService。

Context

  • devflow/index.md 命中 design freeze、ACI contracts 和 session/run trace isolation。
  • 当前 SessionContextHolder、VerifierContextHolder、TokenUsageHolder 使用 ThreadLocal;新 Harness 禁止复用。
  • 当前 ChatService 自行生成 runId、写 diagnosis_run、执行两轮 retry loop 并在 finally 清理 ThreadLocal,职责与新 Harness 边界冲突。
  • DiagnosisRun.status 当前是字符串 PENDING/RUNNING/SUCCESS/FAILED;本阶段不修改实体或迁移,由后续应用用例映射。
  • Spring AI 1.1.7 SpringAiRetryProperties 的配置前缀是 spring.ai.retry,默认 maxAttempts=10。

Question Pool

维度 问题 模式 证据与结论 状态
术语 “不可变 RunContext”是否意味着预算/取消也不能变化? evidence-driven ISS 要求上下文不可变同时要求计数/取消/终态;采用结构不可变 record + 线程安全单 Run 状态句柄。 已解决并汇报
术语 Run 与 DiagnosisRun 是否在阶段 2 直接持久化绑定? evidence-driven 阶段 2 只建 Core,阶段 6A 才接应用用例;本阶段生命周期为内存执行真理,不改 JPA。 已解决并汇报
边界 是否迁移旧 ThreadLocal/ChatService 调用? evidence-driven ISS 1109-1111 明确禁止 ThreadLocal 和旧 ChatService 临时适配;只新增零消费者 Core。 已解决并汇报
边界 取消是否承诺立即中断同步模型调用? evidence-driven 阶段 0 已确认分层取消;阻止后续边界并执行资源回调,不承诺不可证明的硬中断。 已解决并汇报
验收 唯一终态如何证明? evidence-driven atomic first-terminal-wins lifecycle,并用取消/预算/异常/成功竞态测试证明后续终态不能覆盖。 已解决并汇报
验收 异步传播如何证明不依赖 ThreadLocal? evidence-driven Fake Tool 在 CompletableFuture 线程只接收显式 RunContext,并验证相同 session/run/state handles。 已解决并汇报
技术 隐藏重试如何关闭? evidence-driven 本地依赖 SpringAiRetryProperties 证实 spring.ai.retry.max-attempts 默认 10;配置改为 1 并加配置测试。 已解决并汇报
技术 尚未校准的预算默认值如何处理? evidence-driven ISS 要求集中配置且不伪造数值;Core 接受显式 limits,不内置默认预算,后续 Spring wiring 决定配置值。 已解决并汇报
技术 Tool Call Key 是否生成 Tool ID? evidence-driven 阶段 0/1 冻结框架 ID;Factory 仅验证安全 segment 并拼接,不生成或改写。 已解决并汇报

Grill 结论

  • 术语、边界、验收和技术问题均可由已确认 ISS、现有代码和本地依赖 API 证明。
  • 没有新的产品偏好、公开协议或风险接受度问题需要 user-interview;短期关闭旧 SDK retry 的影响已在 proposal 明示。
  • grill-with-docs 的代码可证问题已先查证并向用户汇报;所有结论均已回写 proposal。

能力与工具限制

  • Discover 能力来源:sm-flow + grill-with-docs。
  • 当前工具集没有 codebase-retrieval 和 LSP;使用 rg、源码阅读、本地依赖 jar/javap、编译和 focused tests 补足调用链与 API 核对。

Cross-artifact 对齐

链路 状态 结论
brief 目标/范围/非目标 -> proposal 已对齐 显式 context、Core、预算/取消/终态、retry、key/capacity、隐藏 retry 和不接旧 runtime 全部覆盖。
proposal 范围/约束/承诺 -> design 已对齐 类职责、并发语义、first-wins、配置变化、迁移和回滚均有明确设计。
design 决策/接口影响/风险 -> specs/tasks 已对齐 每个状态边界都有 scenario,配置行为变化和 zero-consumer 边界有独立任务与验证。
specs 可观察行为 -> tasks 已对齐 8 条 requirements 分解为 primitives、budget、Core、retry、key、配置和三层验证。

Architecture Audit

  • 能力来源:zoom-out,使用 glossary 的 RunContext、Run Lifecycle、Run Budget、Harness Retry Policy 和 Diagnosis Run 术语。
  • 输入链路为未来 application use case 创建 RunContext,处理链路由 Core/Retry/Key/Capacity 通过显式参数消费,输出为唯一 RunTermination;当前 runtime 不接入。
  • RunContext 拥有单 Run 内存状态,应用用例拥有数据库映射,Tool store 拥有 Redis invocation;数据所有权没有重叠。
  • Core 不保存全局 Run map、不调用 Agent/数据库/Redis、不实现循环编排,因此不会演变为工作流引擎。
  • 最大风险是关闭 SDK retry 对旧路径的短期行为影响;已作为显式配置变更进入 proposal/spec/test 和回滚说明,无 ADR 冲突。

Commit Gate Preflight

  • proposal、design、specs、tasks 完整,OpenSpec status complete,strict validation 通过。
  • question pool 无未汇报 evidence-driven 结论、无未确认 user-interview 问题。
  • 接口影响 L2;spring.ai.retry.max-attempts=1 的有意内部行为变化已明确影响和回滚边界。
  • cross-artifact 四段对齐无 gap,架构审计约束已进入 design/spec/tasks。
  • Apply 持续授权已存在;执行范围严格限制为新 Harness foundation、配置 override 和 focused tests。

Pre-apply Research

参考实现与反例

  • SessionContextHolder:ThreadLocal session/run fallback,新 Harness 明确禁止复用。
  • TokenUsageHolder / TokenTrackingChatModel:当前只记录 total token 且依赖 ThreadLocal,后续 model boundary 应改为显式 RunBudget;本阶段不改旧类。
  • ChatService.executeChatComplex:当前业务方法内创建 Run、两轮 retry、写终态和清理 ThreadLocal,是后续替换对象,不是 Core 参考实现。
  • DiagnosisRun:现有持久化字段和字符串状态;本阶段只确认映射边界,不修改实体或 Repository。
  • Spring AI 1.1.7 SpringAiRetryProperties:spring.ai.retry 前缀、默认 maxAttempts=10,支持精确配置 override。

技术栈清单

  • Java 17 record 表达结构不可变 context/limits/snapshot/policy/attempt。
  • AtomicReference 实现 first-reason/first-terminal-wins;AtomicLong 实现 capacity CAS;同步临界区维护复合预算一致性。
  • Clock 和 Supplier<String> 注入保证 deadline/ID 可测试,不引入 scheduler 或全局 registry。
  • SLF4J 只记录取消 callback 异常,不记录用户输入、Tool payload 或凭据。
  • SnakeYAML 直接解析 classpath application.yml 验证 retry override,不启动外部 MySQL/Redis/Milvus/模型。

新建基础设施

  • harness.core:RunContext、Cancellation、Lifecycle、Budget、Capacity、Core 和类型化异常/状态。
  • harness.retry:RetryFailure/Policy/Policies/Attempt/Executor/Exception 与函数接口。
  • harness.tool.store.ToolCallKeyFactory:纯 Key 构造,不访问 Redis。
  • focused unit tests 与 Fake Model/Tool;无需新 Maven 依赖。

影响半径

  • 新生产包在本阶段保持零消费者。
  • 唯一现有运行配置变化为 spring.ai.retry.max-attempts=1;Model 路由、provider、Controller、JPA 和 Redis 配置保持不变。

Apply 结果

  • 冲突分类:未发现 OpenSpec 遗漏、代码偏离或方向不确定项;一次自审发现 RetryExecutor 需要无条件拦截预算/取消异常,已回写代码并通过回归测试。
  • 新增 RunContext、Cancellation、Lifecycle、Budget、Capacity、DiagnosisHarnessCore、typed Retry 和 ToolCallKeyFactory;未接旧 Chat/AIOps/Controller/Redis/JPA。
  • Spring AI 全局 retry 已由默认 10 压为 1;Harness strict policies 只允许 Router/SemanticGuard 技术失败一次显式重试。
  • 首模块对齐:Run state/budget/Core/retry/key/config 与 design/tasks 全部完成;Tool interceptor/store/Agent/应用用例仍留给后续阶段。

Apply 验证

  • 编译:mvn -q -DskipTests compile:通过。
  • Core focused:mvn -q '-Dtest=RunContextTest,RunBudgetTest,DiagnosisHarnessCoreTest,HarnessRetryExecutorTest,ToolCallKeyFactoryTest,SpringAiRetryConfigurationTest' test:通过(加固后复跑通过)。
  • 综合回归:mvn -q '-Dtest=HarnessContractTest,RagToolContractTest,QueryLogsToolContractTest,MysqlToolContractTest,RunContextTest,RunBudgetTest,DiagnosisHarnessCoreTest,HarnessRetryExecutorTest,ToolCallKeyFactoryTest,SpringAiRetryConfigurationTest,ChatControllerTest' test:通过。
  • 静态 scope:新 Harness 包无 ThreadLocal/current-holder/Redis 引用;旧 Chat/AIOps/Controller/JPA 调用链 diff 为空;模型路由/provider 未改。
  • OpenSpec:openspec validate single-react-harness-run-context --strict:通过。