## Context 阶段 3 已将复杂 Chat 单轨切换到 Diagnosis StateGraph,并以 119 个 focused tests 证明生产入口、路由、Node、Trace 和 Eval。当前测试实现按阶段累积:`DiagnosisGraphRoutingTest` 是完整 Fake workflow,`DiagnosisRealGraphIntegrationTest` 验证真实 Node assembly,多个专用 Node/protocol tests 锁定局部契约,`ChatServiceGraphIntegrationTest` 验证 Run 生命周期;另有 `VerifierInputHookTest` 仍锁定已退出生产路径的 raw/full-trace/ThreadLocal payload。 ISS-011 阶段 4只改变测试架构。生产源码、API、DTO、DB、Prompt 和路由均不得修改。目标是建立三个权威入口,同时保留小而精确的专用 tests,避免把全部覆盖合并成难维护的大类。 ## Goals / Non-Goals **Goals:** - 用 `DiagnosisGraphWorkflowTest` 表达所有条件边、有限重试、终止和 event 顺序。 - 用 `DiagnosisGraphNodeContractTest` 表达真实 Node assembly 的输入投影、config identity、Gatekeeper/verified evidence、status/verdict 和安全材料边界。 - 用 `ChatServiceGraphIntegrationTest` 表达 public ChatResult、Run/Trace/evaluation、SUCCESS/FAILED 和 multi-run 隔离。 - 建立 Issue 阶段 4路径矩阵,补齐 partial-pass REJECT、tool-failure-but-valid-output、invalid Verifier 无伪 verdict 等高价值缺口。 - 删除 `VerifierInputHookTest`,并证明其仍有价值的 parser/Gatekeeper/投影行为已由独立 tests承接。 **Non-Goals:** - 不修改生产实现或为了测试引入额外 public seam。 - 不删除生产 `VerifierInputHook`/`VerifierContextHolder` 类型;阶段 5清理。 - 不强制删除所有细粒度 Node/protocol tests。 - 不运行 Maven live E2E、日志或真实数据库验收。 ## Decisions ### 1. 重命名现有权威类,不复制路由测试 将 `DiagnosisGraphRoutingTest` 原样演进为 `DiagnosisGraphWorkflowTest`。它已经使用 `ScriptedDiagnosisGraphActions` 驱动真实 CompiledGraph,覆盖 counter、edge、sequence 和 trace;复制一份新类只会形成两个路由真理源。 替代方案是保留旧类再加 facade/suite class,但 Maven/JUnit suite 依赖和重复发现没有新增验证价值,因此拒绝。 ### 2. 真实 Node assembly integration 成为 Node Contract 权威入口 将 `DiagnosisRealGraphIntegrationTest` 演进为 `DiagnosisGraphNodeContractTest`。该类跨 Planner/Executor/Gatekeeper/VerifiedInput/Verifier/Composer 观察 invoker input、Gatekeeper调用次数、完整 snapshot 和 safe fallback,最符合“节点输入输出契约”的架构边界。 专用 `PlannerNodeAdapterTest`、`VerifiedInputNodeTest` 等继续保留,用于精确定位单组件失败;Node Contract 不复制它们全部断言,只补跨节点组合缺口。 ### 3. 覆盖矩阵按行为归属,不按历史类迁移 - Workflow:PASS、Planner/Verifier/Composer retry 与 exhaustion、Executor status、Gatekeeper outcome、evidence retry、Verifier REJECT、终止/trace。 - Node Contract:adapter/config、合法 no-evidence/工具失败说明、partial-pass REJECT、verified-only projection、ceiling、完整 snapshot revalidation、Composer/Fallback材料。 - Chat Integration:Run start/complete/fail、metrics/Eval、orchestration trace、self-evaluation、cleanup、multi-run。 同一安全边界可以有 unit + integration 两层证据,但不得复制大段 fixture;复用现有 helpers 和 constants。 ### 4. 删除 Hook test,不迁移旧 payload `VerifierInputHookTest` 的 raw Executor、full tool trace、ThreadLocal 和 Hook Gatekeeper payload 与阶段 3 verified-only生产协议冲突。其 parser sanitization 由 `ExecutorEvidenceParserTest`,引用真实性由 `ExecutorGatekeeperServiceTest`,Graph status/audit 由 `GatekeeperNodeTest`,passed-binding projection 由 `VerifiedInputNodeTest` 覆盖。 阶段 4删除测试但保留生产类型,避免把阶段 5清理提前混入测试重构。若阶段 5删除类型,已经没有测试迁移阻力。 ### 5. 测试失败按三类处理,默认 production diff=0 若新矩阵发现失败:规格缺口则先修正 OpenSpec;生产实现偏离既有 specs 才允许修复生产代码;测试命名/fixture 偏差只修测试。阶段 4正常验收要求 `src/main` 无 diff,从而保持提交职责单一。 ## Interface Impact - 等级:L1 test-only。 - 外部行为、API、DTO、DB、Prompt、Graph State 和消费者:无变化。 - 测试发现生产偏差时才可能升级影响级别,并必须回写 OpenSpec;当前没有此类发现。 - 回滚:revert 测试重构提交;不涉及数据或运行时迁移。 ## Risks / Trade-offs - [类重命名让历史链接失效] → devflow/archive 记录 old→new 映射,Git rename 可追踪历史。 - [三个权威类变成巨型文件] → 保留细粒度专用 unit tests,权威类只承载跨组件/路径矩阵。 - [删除 Hook test 丢失安全边界] → 删除前运行 parser/Gatekeeper/VerifiedInput保留集合并在 acceptance 记录映射。 - [仅有测试名没有真实矩阵] → tasks 明确补 3 个跨节点缺口并对照 Issue 全列表审计。 - [repository/integration tests 写本地日志被误认为 live E2E] → 验收明确区分 Maven tests 与 Maven 应用启动;阶段 4不检查日志/数据库。 ## Migration Plan 1. Rename Routing→Workflow 和 RealGraphIntegration→NodeContract,不改变测试逻辑,先跑 GREEN。 2. 以 Issue 矩阵审计现有 method coverage,补 partial-pass REJECT、tool failure但合法结构、Verifier failure无伪 verdict 等缺口。 3. 删除 `VerifierInputHookTest`,运行对应 parser/Gatekeeper/VerifiedInput回归证明安全覆盖未丢失。 4. 扩展/复核 ChatService integration 与保留 Controller/Trace/Repository/Composer/Eval tests。 5. 运行 test compilation、OpenSpec/static gates,归档并独立提交。 回滚只需 revert 阶段 4提交,不影响生产运行。 ## Open Questions 无。测试职责、旧 Hook test 退役和 E2E 阶段边界均由代码证据、阶段 0 spec 与用户规则确定。