Files
qinglong/docs/adr/ADR-0412-durable-copilot-pre-model-terminalization-and-unknown-resolution.md
T

60 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-0412:耐久 Copilot Pre-Model 终态化与 Model Unknown Resolution
- 状态:Accepted
- 日期:2026-08-15
- 关联 RFCQL-RFC-0001 D-320、Phase 2
- 关联 ADRADR-0087、ADR-0407、ADR-0408、ADR-0409、ADR-0411
## 问题
ADR-0411 已把 Cluster Copilot failure diagnosis 组合到既有、默认关闭的 Cluster AI 进程,但成功链之外仍有两类不收敛窗口:
1. Tool `failed|timed_out`、日志 `not_found|pending|missing|retired`、执行 Tool 所需的固定预算不足、数据库观察到 deadline 或 cancellation 时,Model 尚未开始,diagnosis Run 可能永久停留在 `running`
2. Provider 已开始但结果不可确认时,通用 ModelInvocation 会耐久记录 `outcome_unknown``lost` Step。人工 `fail|cancel` resolution 会产生一个新的 resolved Step digest,原 Copilot finalizer 却仍只接受 unknown completion 时的 `lost` digest,因此正确 resolution 也无法终态化父 Run。
不能由调用者直接提交 outcome/reason,也不能用进程内异常或定时器伪造耐久终态。路由器和低配设备部署还要求该补强不能增加 package、进程、连接、队列、watcher、timer 或默认 Profile 闭包。
## 决策
1.`@qinglong/ai` 的既有 `copilot/failure-diagnosis/terminalization` 领域目录建立一个 pre-Model terminalization capability,并仅通过 `failure-diagnosis-pre-model-terminalization` 精确 subpath 发布。它不是新 package,也不从 package `src` 根平铺实现文件。
2. terminalizer 只接受三种受信触发:耐久 Tool failure completion、耐久 Tool success 加受审日志 projection、或无调用者事实的 boundary observation。repository 再从数据库读取 exact admission、Run、Tool/Model Step、Model start existence 和数据库时间;调用者不能指定 reason、outcome、Step mutation、Run version 或时间。
3. reason 与结果采用封闭映射:
- `tool_failed` → Run `failed`,取消尚未运行的 Model Step
- `tool_timed_out` → Run `timed_out`,取消 Model Step
- `log_not_found|log_pending|log_missing|log_retired` → Run/Model Step `failed`
- `tool_budget_exhausted|deadline_exceeded` → Run `timed_out`,按 Step 当前状态写 `timed_out|cancelled`
- `cancellation_requested` → Run `cancelled`,取消未开始的两个 Step。
4. 任何 Model start 已存在时都拒绝 pre-Model terminalization。Model 已经跨过外部副作用边界后,只能使用 Model completion/recovery/resolution 语义,不能把“不知道”改写为“没有执行”。
5. `pg-9021-ai-copilot-failure-diagnosis-pre-model-terminalizations` 增加一个 append-only content-free receipt ledger。`ql3_runtime` 只有 `SELECT, INSERT`,PUBLIC 和其他角色没有权限。一个 `SERIALIZABLE` 事务锁定 Run/Step,复验 admission、reason evidence、version/digest 和 Model-start absence,原子提交 StepRun mutations、RunEvents、父 Run 终态和 receiptCOMMIT response loss 通过 receipt exact replay 收敛,不重复 Tool、日志读取或 Model 调用。
6. application service 在 Tool 执行前先检查 boundary terminalizationTool failure 和非 available 日志 projection 直接进入 terminalizer;只有 available projection 才继续 unlock/Model。Tool 的固定五秒预算必须完整落在 plan deadline 内,否则在 start barrier 前终态化。并发调用继续由既有 request coalescing 收敛。
7. `outcome_unknown` 不自动重试、不自动假定失败。强认证 User 仍须通过通用 `DurableModelInvocationResolutionCoordinator` 显式选择 `fail|cancel|retry`。Copilot finalizer 对普通 completion 校验 completion 后 Step digest;对 unknown 的 `fail|cancel` 校验 resolution completion binding 和 resolution mutation 的 resolved Step digest,再终态化父 Run。`retry` 保持 in-progress,且确定性 invocation identity 不允许偷偷再调用 Provider。
8. 该 capability 继续 caller-driven,并复用既有 PostgreSQL AI Pool、Run/Step ledger、Tool completion、ModelInvocation resolution 与 Cluster composition;不新增 daemon、scan、timer、watcher、队列、cache、HTTP/CLI/UI/MCP route、Pod 或 Kubernetes API 权限。默认 Edge/Standalone 及其 AI 制品不导入 Cluster-only composition,低配部署没有新增常驻工作。
## 被否决方案
1. **由 application catch 后直接返回失败**:没有耐久 Run/Step/Event 事实,崩溃和 replay 会漂移。
2. **调用者提交 reason/outcome**:会把数据库时间、取消事实和 Tool completion authority 暴露给不可信边界。
3. **后台轮询扫描所有 diagnosis Run**:增加每副本 timer/数据库负载,并与 caller-driven 组合重复竞争。
4. **Model start 后仍走 pre-Model terminalizer**:可能把已经产生费用或外部结果的调用伪装为未执行。
5. **将 unknown completion 直接映射为 failed**:抹掉真实歧义并绕过显式人工 resolution。
6. **新增 terminalization package**:没有独立部署、依赖、权限或多 consumer 边界,只会制造薄 package。
## 验证标准
1. 单元测试覆盖 Tool failure/timed-out、四种日志状态、deadline、Tool budget、cancellation、exact replay、并发 coalescing、过早触发和 Model-start 后拒绝。
2. PostgreSQL migration 测试固定 migration ID、顺序、表约束和 `SELECT, INSERT` 最小权限;package/dependency/import/deployment 审计必须保持零 finding。
3. PostgreSQL 18 physical HA 以三个独立 diagnosis Run 证明:成功基线、日志不可用 pre-Model terminalization、unknown completion→人工 fail resolution→finalization;晋升后全部 exact replay,不重复日志读取、Tool 或 Model 外部执行。
4. 18-package clean build/test、完整 backend、14 档 Local artifact、GitNexus staged/change detection 全通过后才允许阶段性提交。
## 当前验证
1. `@qinglong/ai` 完整测试 244 pass/3 条件 skip/0 fail;新增 9 条 pre-Model 场景覆盖 Tool failure、四种日志状态、deadline、固定 Tool budget、cancellation 和 Model-start fence。
2. 18 个 QL3 package 从清空全部 `dist` 开始完成拓扑构建和全包测试,非沙箱 TLS loopback 回归全绿;backend 1,207 pass/2 条件 skip/0 fail。
3. workspace 保持 18 个 package`singleSourcePackages=[]``shallowSourcePackages=[]`。AI 192 个源码中 191 个位于嵌套领域目录;新增五个源码全部位于既有 failure-diagnosis 领域目录,package 根仍只有一个 16 行 public entrypoint。`local-command-file` 虽小但保留多 consumer 的独立 POSIX 文件安全边界,两个 migration 密集目录继续作为有顺序上限的 ledger 接受审计。
4. Edge import、Cluster dependency、package boundary 与 Cluster deployment 审计兼容且零 finding14 档 Local artifact 通过,说明 Cluster-only terminalizer 未进入默认路由设备闭包。
5. PostgreSQL 18.6 arm64 physical HA 137/137、timeline `1→2`21 条 AI migration、新 append-only ledger、最小权限、两条新增恢复链和晋升后 exact replay 全部通过。私有报告 SHA-256 为 `6eaeb20615a62d153c5a69687344f41f31351c6ecf111cfb9cbafad115538c83`,独立离线审计 `compatible=true`、零 finding。
## 后续门禁
下一 Gate 才能增加认证、Policy、audit、request identity 与 source fence 保护的 Cluster 产品 APICLI/UI/MCP 必须复用同一 capability,不得建立旁路执行器。产品入口还需补多副本并发、真实外部 Provider、费用/取消可观测性和明文负证据后再评估默认策略。