@@ -0,0 +1,117 @@
# Decisions: single-react-chat-application-usecase
## Discover Status
- Checkpoint: Discover
- Capability source: `sm-flow` + `grill-with-docs` ; `codebase-retrieval` 、LSP 和 GitNexus MCP 当前不可用,使用既有 GitNexus 结论、`rg` 引用核对和源码阅读降级。
- Scale: complex。跨模型路由、三类执行器、Run/session 生命周期、数据库 migration、PreviousTurn 和阶段 6B consumer boundary。
- `devflow/index.md` 命中阶段 0-5、session-run-trace-isolation、RAG contracts 和 release guards;无 ADR 冲突。
## Question Pool
| # | 维度 | 问题 | 模式 | 状态 |
|---|---|---|---|---|
| Q1 | 术语 | Chat Application Use Case 与 Controller、Harness、Agent 的职责边界是什么? | evidence-driven | 已解决 |
| Q2 | 路由 | Router 输入、输出和可重试失败范围是什么? | evidence-driven | 已解决 |
| Q3 | 路由 | Router 最终失败是否允许默认进入 Diagnosis? | evidence-driven | 已解决 |
| Q4 | 执行器 | 三种 intent 分别允许哪些模型和 Tool 行为? | evidence-driven | 已解决 |
| Q5 | Knowledge | 单次 RAG 调用如何验证模型引用且不公开 Tool Call ID? | evidence-driven | 已解决 |
| Q6 | PreviousTurn | 上一回合的真理源、筛选条件和截断边界是什么? | evidence-driven | 已解决 |
| Q7 | 生命周期 | 何时读取上一回合、创建当前 Run、记录 intent 和终态? | evidence-driven | 已解决 |
| Q8 | 持久化 | diagnosis_run 需要新增哪些字段,哪些内部内容禁止进入 published_result? | evidence-driven | 已解决 |
| Q9 | 6B 边界 | 如何让 Controller 切换时不重写应用用例? | evidence-driven | 已解决 |
| Q10 | 接口 | 数据库/内部接口影响等级和回滚要求是什么? | evidence-driven | 已解决 |
| Q11 | 验收 | 如何证明原始 Query、sessionId/runId 和失败终态一致传播? | evidence-driven | 已解决 |
## Evidence-driven
| 结论 | 证据来源 | 是否已汇报用户 |
|---|---|---|
| Controller 只负责协议;Application Use Case 拥有 session/run、routing、executor、persistence, Harness 拥有预算/取消/释放,Agent 拥有诊断语义。 | ISS-014 3、4.2、阶段 6A/6B | 已汇报 |
| Router 输入只含 query/last_intent/last_user_query,输出只允许三枚举;无 Tool/记忆/ReAct。 | ISS-014 4.5 | 已汇报 |
| timeout/transport/非法输出可重试一次;第二次失败返回安全入口错误,不进入 Diagnosis。 | ISS-014 重试策略、`HarnessRetryPolicies.intentRouter()` | 已汇报 |
| SYSTEM_CHAT 无 Tool; KNOWLEDGE_QUERY 只调用一次 lookup; DIAGNOSIS 进入 Agent + Guards。 | ISS-014 4.5 | 已汇报 |
| PreviousTurn 只来自同 Session 最近 `DIAGNOSIS + SUCCESS + published_result` ,不使用 Redis 历史。 | ISS-014 4.6 | 已汇报 |
| `PublishedResult` /`PreviousTurn` 已冻结为 query/conclusion/scope/limitations/source_documents,不含 Tool ID/raw/Draft/reason。 | 阶段 0 contracts、`PublishedResult` 、`PreviousTurn` | 已汇报 |
| 当前 `DiagnosisRun` /V011 尚无 intent/release_outcome/published_result,需要 V012 和 repository query。 | `DiagnosisRun.java` 、`V011__add_session_run_isolation.sql` | 已汇报 |
| 上一回合必须在保存当前 PENDING Run 前读取,否则 latest query 会命中当前请求。 | repository 当前 latest method + 生命周期顺序推导 | 已汇报 |
| 6B 需要 metadata/status/cancel, 6A 应提供 observer 和显式 RunContext,而不包含 SSE 类型。 | ISS-014 4.7、阶段 6B | 已汇报 |
## User-interview
- 无新增 user-interview。三类路由、数据库字段、PreviousTurn、失败语义、阶段边界和自动 Apply/Archive/commit 均由 ISS-014 与用户持续授权冻结。
## Key Decisions
- 在创建当前 Run 前读取 latest safe routing context 和 PreviousTurn,随后 `startRun -> persist RUNNING -> observer metadata -> route` 。
- Application output 使用 typed content union, Diagnosis success 转为无 Tool ID 的 public report view; Fallback output 不携带完整 snapshot。
- Knowledge path 生成一次 direct canonical Tool Call ID(该路径没有框架 Tool Call),只调用 `lookup_knowledge` ,严格验证 `KnowledgeAnswerDraft` 的 exact call ID 和 document subset,再移除 ID 发布。
- 所有普通单轮模型调用复用阶段 5 的受控 `GuardModelCall` ,从而共享 Core 模型/Token/timeout/cancel 边界;不引入新模型路由。
- `PublishedResult` 仅在 Diagnosis SUCCESS 且 conclusion 非空时写入;Fallback/Failed/Cancelled/System/Knowledge 不生成 PreviousTurn 真理源。
- 数据库变更使用 V012 可前向迁移;回滚为先停止新应用用例,再删除新索引/列,不影响 V011 既有字段。
- 不创建 ADR:这些是 ISS-014 已冻结设计的落地,不是新的跨项目不可逆决策。
## OpenSpec Backfill
- 需进入 proposal/design/spec/tasks:路由隔离/重试、三执行器、original query、PreviousTurn filter/bounds、observer/cancel、Run terminal persistence、V012/L3、公开隔离。
- 非目标:Controller/SSE/前端切换、旧链路删除、live E2E。
## Cross-artifact Alignment
| 上游 -> 下游 | 检查内容 | 状态 |
|---|---|---|
| ISS-014/brief -> proposal | 三路由、previous turn、Run lifecycle、内部-only 和阶段 6B handoff | 已对齐 |
| proposal -> design | typed executors、observer、JPA/V012、异常/终态、L3 migration/rollback | 已对齐 |
| design -> specs/tasks | 每项所有权/安全边界均有可观察 requirement 和实现测试切片 | 已对齐 |
| specs -> tasks | 9 组 requirements 覆盖 Router/executors、store/policy、application、verification | 已对齐 |
## Architecture Audit
- 能力来源:`zoom-out` ,使用 Chat Session、Diagnosis Run、RunContext、Diagnosis Agent、EvidenceGuard、SemanticGuard 和 PublishedResult 术语。
- 链路为 `request -> application use case -> run store/router -> fixed executor -> Harness/Agent/Tool -> typed public content -> run finish` ; Controller 不拥有模型/工具/Run。
- ChatRunStore 拥有 MySQL 映射,Core 拥有运行状态,Application 拥有 dispatch/终态,path executor 拥有单一路径行为;PreviousTurn policy 是唯一安全历史投影。
- 最大风险是 prior/current Run 顺序和 DB/lifecycle 双终态,design/tasks 已固定 prior read before start、single finish path 和 focused failure/cancel tests。
- V012 是 L3 additive schema; migration、entity、repository、rollback 独立章节完整,公开入口阶段 6A 零变化。
## Interface Impact
- 级别:L3 database/collaboration interface。
- 新增 `diagnosis_run.intent/release_outcome/published_result` 和索引;修改 Entity/Repository,新增 internal application/store/output contract。
- 消费者:阶段 6B Controller/SSE adapter、MySQL/Flyway;旧 ChatService 在本阶段不消费新字段。
- 迁移/回滚:V012 nullable additive;回滚先切旧入口,再删除 index/columns。
## Commit Gate Preflight
- proposal、design、specs、tasks 完整,`openspec status` complete, change strict validation 通过。
- Question pool 全部已解决并汇报,无 user-interview、未判级接口或未接受架构风险。
- Cross-artifact 四段对齐无 gap; V012/L3、prior read ordering、terminal persistence 和 6B handoff 已进入 design/spec/tasks。
- Apply/Archive/commit 使用用户持续授权;公开协议和前端必须保持零 diff。
- `.committed` 已创建,可进入 Apply。
## Pre-apply Research
- `DiagnosisHarnessCore` /`RunContext` : Run ID、budget、cancel 和 first-terminal-wins。
- `GuardModelCall` /`HarnessRetryExecutor` :单轮模型 timeout/usage 和 Router 两次 attempt。
- `HarnessEvidenceTools` /`RagToolResult` : Knowledge 唯一 lookup 路径和有界 projection。
- `DiagnosisAgentUseCase` /`DiagnosisReleaseUseCase` : Diagnosis Draft 与安全 release boundary。
- `DiagnosisRun` /`DiagnosisRunRepository` /`V011` :现有 Run schema 和写入模式。
- `ChatService.ensureChatSession/startDiagnosisRun` :只参考 session metadata/JPA 写法,不复用旧 routing、多 Agent 或 ThreadLocal。
- 技术栈:Spring AI direct Prompt、Jackson strict JSON、JPA repository、Flyway additive migration、protocol-neutral observer;无 MQ/新依赖。
## Apply Progress
- Router/System/Knowledge contracts 与 executors 已完成,tasks 1.1-1.4 完成。
- 5 个 `ApplicationExecutorsTest` 通过:同输入 retry、最终 routing failure、System direct call、Knowledge exact references/no ID、NO_EVIDENCE/model skip。
- TODO: PublishedResult/JPA/V012、Diagnosis executor、总应用用例和综合验证。
- REVIEW:修正 `JpaChatRunStore` 多构造器 Spring 注入歧义;prior/start/intent/finish 持久化异常统一为稳定 `RUN_PERSISTENCE_FAILED` ,并在安全完成时更新 ChatSession 活跃时间/消息对数。均为代码偏离修复,无需变更 OpenSpec。
- PublishedResult/JPA/V012、Diagnosis executor、protocol-neutral Run control 与总 ChatApplicationUseCase 已完成,tasks 2.1-3.4 完成。
- 13 个 stage 6A focused tests 通过;TODO 仅剩综合回归、static scope 和 OpenSpec verification。
- 综合回归曾在 `SemanticGuardTest.attemptTimeoutCancelsBothPermittedModelCalls` 出现负载相关失败。诊断确认生产代码对每次 timeout 均调用 `Future.cancel(true)` ,但第二个 Future 可能在任务线程启动前已取消,此时不存在可接收 interrupt 的线程。分类为测试假设偏差,不是 OpenSpec 或生产代码偏离;回归断言改为两次 TIMEOUT attempt、两次模型预算预留,以及至少一个已运行调用收到 interrupt。
## Final Review
- Stage 6A focused tests 与阶段 2-5 regression 共 18 suites / 76 tests, 0 failure/error/skipped; Maven compile 通过。
- OpenSpec strict validation 通过;V012、Entity、Repository 的三个字段和 previous-turn filter 对齐。
- 公开 Controller、前端和 endpoint 零 diff; Router/System executor 无 Tool、ReactAgent、ThreadLocal 或手写 loop。
- `PublishedResult` 只包含 `user_query/published_conclusion/scope/limitations/source_documents` ,负向序列化测试通过。
- 本阶段不运行 live E2E,按 ISS-014 门禁留到阶段 7。