feat(ql3): admit copilot diagnosis runs

This commit is contained in:
whyour
2026-08-15 15:07:49 +08:00
parent aae96390cc
commit 0163c94be7
24 changed files with 3078 additions and 22 deletions
+10 -2
View File
@@ -6,11 +6,12 @@
- 目标版本:QingLong 3.x
- 作者:QingLong Maintainers
- 创建日期:2026-07-17
- 最后更新:2026-08-14
- 最后更新:2026-08-15
- 讨论范围:架构与演进路线,不包含最终 UI 视觉方案
最新增量证据(2026-08-14):
最新增量证据(2026-08-15):
- D-315/ADR-0407(已接受):Cluster Copilot 故障诊断不修改或重新打开终态源 Run,而是用源 Run/version、最新已结束 Attempt/status 与日志 Artifact 建立 exact fence,原子创建独立 `copilot_failure_diagnosis` Run、admission event、`ready``qinglong.run.log.excerpt@1.0.0` Tool Step、以其为父节点的 `pending` Model Step 和不可变 receipt。计划只接受 `cluster-control` 的 reviewed snapshot/binding/Policy/subject authority`approval_required`、Tool contract/输入漂移或未显式允许的模型出口均在写库前失败关闭。`ql3_ai` 新增有界 admission ledger 与仅授予 runtime 的 `SECURITY DEFINER` source snapshot,在 SERIALIZABLE 事务内重验 active Project/binding 和源 Run/Attemptresponse-loss replay 对 JSONB 做结构 exact 比较而不依赖无语义的对象键序。Copilot/Plugin 这类 StepRun 聚合从通用 Task orphan recovery 排除,后续由各自状态机恢复,不能伪造顶层 Attempt 或被错误终态化。本阶段只 admission,不执行 Tool/模型、不授予行动权;Tool encrypted completion、Model 解锁和 Copilot encrypted model completion 是下一 Gate。最终 18-package clean build/test 与 backend 1,207 pass/2 条件 skip/0 fail,四项边界审计零 finding且 workspace 仍为 18 package、无单文件/浅平 package14 档 Local Profile artifact 全通过,默认 Edge/Standalone 不引入 Cluster admission。PostgreSQL 18.4 arm64 HA 128/128、timeline `1→2`,报告 SHA-256 为 `a4ed1edec783e3f5b42507c0f8e11b94c59dbe44a57e691017d1445ec9d115e2`,证据审计与 Docker 清理通过。
- D-314/ADR-0406(已接受):Cluster Trusted Tool 的 encrypted completion 不再停留在 storage port。`@qinglong/cluster-control/trusted-tool-result-keyring` 新增只读 projected material authoritycanonical v1 manifest 只含最多 16 个 canonical 32-byte key,不含 generation、active/state/retirementprovider 只有 `resolve(keyId)` 而没有 `active()`;因此 PostgreSQL `trusted-tool-results` catalog 仍是 active/decryptable 状态唯一 authoritycompletion 会以 catalog material proof 再次校验。runtime 每次调用重新执行 direct-root、in-root atomic symlink、single-link、64 KiB、只读/不可执行/other-inaccessible mode、dev/inode/size/mtime 与双 realpath fence,不持有 Kubernetes API、cache、watcher 或 timer。新增能力位于 Cluster Control 既有 `trusted-tool/key-management/`,并把 mounted Secret 与 keyring 的 projected-file/TOCTOU 逻辑收敛到 package-private `security/privateProjectedFile` 真源;公开 mounted Secret 行为不变,不新增 package、依赖、migration、连接、route 或默认 Profile importer。定向共享回归 7/7Cluster Control 完整 234 pass/2 条条件 skip/0 fail;最终 18-package clean build/test 与 backend 1,207 pass/2 条件 skip/0 failpackage/dependency/Edge import/Cluster deployment 四项审计零 finding。workspace 仍为 18 package、无单文件或浅平 packageCluster Control 54 个源码中仅 2 个 binary entry 位于根层,52 个处于嵌套领域目录。14 档 Local Profile artifact 全部通过,默认 Edge/Standalone 保持 2,589,812/2,589,890 bytesAI 保持 3,121,108/3,121,198 bytesMCP 保持 7,315,930/7,316,038 bytes。PostgreSQL 18.4 arm64 HA 125/125、timeline `1→2`,报告 SHA-256 为 `26c817647ed984d8d4627a7cae1c95de06017a5d6d32dd3dfd01414ba029e542`,证据审计与 Docker 容器/网络/卷零残留。下一 Gate 是独立 diagnosis Run 的 Tool/Model Step admission 与 Copilot encrypted model completion,不能借用终态源 Run 或 Plugin Prompt plan。
- D-313/ADR-0405(已接受):新增 `@qinglong/ai/failure-diagnosis-prompt`,把 ADR-0403 的潜在敏感日志投影收敛为固定 system instruction + canonical JSON data envelope;日志只存在于 `log.content` JSON string value,不能通过引号、换行、伪造 role/schema 或 delimiter 拼接出新 message。builder 重新校验完整 trust/redaction/profile byte 契约,拒绝伪造 `safe`、行动权、未知字段与 byte/signal driftenvelope 不带 Run/Attempt、Artifact、path、cursor 或 content digest。部署者必须通过 `qinglong/copilot-model-egress-policy@v1` 显式允许 `potentially_sensitive` 数据进入 `on_device|external` 边界并提供输入/output token 双预算,空 allowlist 与 external 未授权均在 Model Gateway/Provider I/O 前失败关闭。输出只含 content-free egress evidence,并固定要求模型 completion 继承潜在敏感、仅加密持久化、禁止明文审计且无行动权;真正 Cluster Trusted Tool/model completion 仍需后续组合门。能力以 `ql3-ai/src/copilot/failure-diagnosis/` 三个内聚文件和精确 subpath 交付,不新增 package、依赖、迁移、连接或常驻组件。定向 12/12、AI 221 pass/3 条件 skip/0 fail;最终 18-package clean build/test 与 backend 1,207 pass/2 条件 skip/0 fail,四项结构/部署审计零 finding14 档 Local Profile artifact 全部通过。默认 Edge/Standalone 保持 2,589,812/2,589,890 bytes、315 files、56 modulesEdge/Standalone AI 保持 3,121,108/3,121,198 bytes、368 files、61 modulesMCP 保持 7,315,930/7,316,038 bytes、801 files、226 modules,证明未装配 subpath 被完全裁掉。PostgreSQL 18.4 arm64 HA 125/125、timeline `1→2`,报告 SHA-256 为 `2bbc8bdd0d90e6ec9ce82d2afcaec817679dddb82860c5d405a09d5e5458bece`,证据审计与 Docker 零残留。
- D-312/ADR-0404(已接受):`qinglong.run.log.excerpt@1.0.0` 进入显式可选的本机 `ql3-mcp` stdio 产品入口。每次调用固定经过 Owner credential authentication、exact `tool.call:qinglong.run.log.excerpt` + `artifact.read` Policy、durable audit、credential/Pepper fence confirm,再复用同一 SQLite authority 和私有 Artifact reader 完成 ADR-0403 的 Edge 4 KiB/Standalone 8 KiB 双读取安全投影。配置升级为 `qinglong/local-mcp-server@v2` 并要求显式 private `artifactRoot`,旧 v1 不猜测路径而是失败关闭。产物实证否决了 MCP 直接依赖 `local-execution` 的方案:该方案会带入 process/scheduler/croner,达到 7,469,105 bytes/816 files/228 modules;唯一 reader 实现因此归入既有 `local-command-file/artifact-read` 私有文件 authorityExecution 通过兼容 re-export 复用,workspace 仍为 18 package 且没有根层平铺。Local MCP 48/48、Local Execution 41/41、私有文件 3/3、依赖防火墙 54/54;最终 18-package clean build/test 与 backend 1,207 pass/2 条件 skip/0 fail,四项结构/部署审计零 finding14 个 Local Profile artifact 全部通过。默认 Edge/Standalone 保持 2,589,812/2,589,890 bytes、315 files、56 modulesEdge/Standalone MCP 为 7,315,930/7,316,038 bytes、801 files、226 modules、RSS 38,420,480/39,567,360 bytes,闭包不含 `local-execution``local-process``croner`。PostgreSQL 18.4 arm64 HA 125/125、timeline `1→2`,报告 SHA-256 为 `29cd77d80737a3b1ab686c998d05a78c52deffd8add3b31d8035756d5dfcc433`,证据审计与 Docker 零残留。
@@ -6937,6 +6938,13 @@ ADR-0406 已关闭其中的 Cluster result-key material 缺口:只读 projecte
Copilot execution authority 已完成;下一 Gate 必须创建独立 diagnosis Run 的 Tool/Model Step admission
再把 S3 Tool completion、ADR-0405 builder、Model Gateway 与 Copilot 专用 encrypted model completion
串成可恢复闭环。
ADR-0407 已完成该 admission Gate:源失败/超时 Run 和最新已结束 Attempt 只作为不可变 source fence
独立 diagnosis Run 在一个 SERIALIZABLE 事务内同时获得 admission event、ready Tool Step、依赖它的
pending Model Step 与 receiptCluster runtime 的 source snapshot authority 会重验 active Project/binding
和日志 Artifactresponse-loss replay 以结构语义比较 JSONB。该 Run 是 StepRun 编排聚合,不进入通用
Task orphan recovery。当前阶段仍没有执行 Tool 或模型;下一 Gate 必须先形成可信 encrypted Tool
completion,再原子解锁 Model Step,并以 ADR-0405 egress policy 和 Copilot 专用 encrypted model
completion 收敛最终 Run。
## 17. Tool Registry
@@ -0,0 +1,87 @@
# ADR-0407Cluster Copilot Failure Diagnosis Run Admission
- 状态:Accepted
- 日期:2026-08-15
- 关联 RFCQL-RFC-0001 D-315、Phase 2
- 关联 ADRADR-0163、ADR-0226、ADR-0403、ADR-0404、ADR-0405、ADR-0406
## 问题
ADR-0403~0406 已经给出有界日志摘录 Tool、显式模型出口策略和 Cluster result-key material
authority,但仍缺少把一次故障诊断变成 durable execution 的入口。源 Run 已经处于 `failed`
`timed_out` 终态,不能向它追加 Tool/Model Step,也不能复用 Plugin Package Prompt admission
冒充 Copilot 工作流。
若仅在 API 内顺序调用 Tool 和模型,进程崩溃、响应丢失或 PostgreSQL failover 会让系统无法证明
已经接受了什么、下一步应该执行什么;若 admission 直接启动模型,模型又可能在 Tool 结果尚未形成
可信 encrypted completion 时读取未经 fencing 的数据。通用 Task recovery 也不能把这种以 StepRun
编排、没有顶层 RunAttempt 的聚合 Run 当成普通孤儿任务。
## 决策
1. 故障诊断创建独立 `copilot_failure_diagnosis` Run,并以源 Run 作为 `parentRunId`。源 fence 必须精确
固定 Project、Run ID/version、`failed|timed_out` 状态、最新且已结束的 Attempt、兼容的 Attempt
状态和非空日志 Artifact;admission 不修改或重新打开源 Run。
2. 计划只接受 `cluster-control` Profile 中经过 snapshot、Policy、subject 与 binding fencing 的
`qinglong.run.log.excerpt@1.0.0` 内建只读 Tool。`approval_required`、不同 Tool/version、不同
adapter/redaction/audit contract、输入 Artifact 未绑定源 Attempt 或权限漂移全部在数据库写入前
失败关闭。
3. 模型 intent 固定 provider/model、`on_device|external` 边界、响应语言、输出 token 上限和 ADR-0405
egress policy digest。计划与 receipt 均有 domain-separated digest 和字节上限;它们声明最终模型
completion 必须加密、审计不得保存明文且 `actionAuthority=none`,本阶段不授予命令或写 Tool 权限。
4. 一个 SERIALIZABLE PostgreSQL 事务原子创建 diagnosis Run、admission event、`collect-log` Tool
StepRun、`diagnose` Model StepRun 和 admission receipt。Tool Step 初始为 `ready`Model Step 以 Tool
Step 为父节点且初始为 `pending`。本阶段只 admission,不执行 Tool/模型;后续只有可信 Tool
completion 成功后才能解锁 Model Step。
5. `ql3_ai.copilot_failure_diagnosis_admissions` 保存有界 plan/receipt JSONB 及关键列镜像。
`SECURITY DEFINER` source snapshot 函数只授予 `ql3_runtime`,并在同一事务内重新确认 active Project、
最新 active subject binding、源 Run/Attempt 状态与日志 Artifact。request identity 支持 response-loss
replay;同 request 不同事实、任何 durable 镜像漂移或部分证据缺失均冲突或失败关闭。
6. PostgreSQL JSONB 的对象键序不具有语义;replay 采用严格的结构深比较,而不是比较
`JSON.stringify` 文本。数组顺序、值类型、缺失/新增字段仍保持 exact,不能借键序修复放宽证据。
7. `copilot_failure_diagnosis``plugin_package_workflow` 都是 StepRun 编排的聚合 ownership domain
从通用 Task orphan recovery 查询中排除。它们必须由各自 StepRun 状态机恢复,不能伪造顶层
RunAttempt,也不能因不存在 Attempt 而被自动终态化。Cluster activation 在 recovery 未收敛时输出
remaining/failed 计数,便于 failover 诊断。
8. 能力只通过 `@qinglong/ai` 精确 subpath 和既有 Cluster PostgreSQL migration stream 提供;不新增
workspace package、进程、连接池、listener、timer、watcher 或 cache。默认 Edge/Standalone 及其
AI/MCP 制品不导入 PostgreSQL admission,因此低配路由设备没有新增常驻成本。
## 被否决方案
1. **把 Step 追加到源失败 Run**:破坏终态 Run 不可变和 event/version 单调性。
2. **复用 Plugin Package Prompt admission**:两者的 authority、Artifact 密文域、恢复与产品语义不同。
3. **admission 后立即调用 Tool/模型**:无法在 response loss 与主库切换后证明执行边界,也会绕过
Tool completion 对 Model Step 的依赖。
4. **为 diagnosis Run 伪造顶层 Attempt**:把 StepRun 聚合误装成 Task 执行,并让两套恢复状态机争夺
ownership。
5. **用序列化字符串比较 JSONB**PostgreSQL 会重排对象键,合法重放会被错误判为证据损坏。
6. **为 admission 新建 package 或进入 Local Profile**:没有独立进程/制品边界,并向低配设备引入
无用的 Cluster/PostgreSQL 闭包。
## 当前验证
1. admission 定向测试 6/6,覆盖 exact Tool/subject/policy/source fencing、approval 拒绝、模型出口策略、
原子创建、response-loss replay、冲突/损坏证据和 JSONB 键序等价。
2. recovery SQL 4/4、Cluster activation 6/6HA 门额外断言 diagnosis 聚合不会进入通用 recovery
candidate。
3. 18 个 QL3 package 的 clean build/test 全部通过;完整 backend 为 1,207 pass、2 条条件 skip、
0 fail。package boundary、Cluster dependency、Edge import 与 Cluster deployment 四项审计均为
compatible 且零 findingworkspace 仍为 18 个 package`singleSourcePackages=[]`
`shallowSourcePackages=[]`
4. 14 档 Local Profile artifact 全部通过,证明 Cluster-only admission 未进入默认 Edge/Standalone、
AI 或 MCP 的本地部署闭包。
5. PostgreSQL 18.4 arm64 physical HA 为 128/128 Gate、timeline `1→2`;报告 SHA-256 为
`a4ed1edec783e3f5b42507c0f8e11b94c59dbe44a57e691017d1445ec9d115e2`,独立证据审计零 finding
Docker 容器、网络与卷零残留。
## 后续门禁
1. 以 admission 中的 exact plan 启动 Tool Step,并复用 invocation Artifact、S3 reader、catalog 与
ADR-0406 result-key provider 完成加密 Tool completionresponse loss 不得重复执行 adapter。
2. 只有受信 Tool Step 成功后才原子解锁 Model Step;用 ADR-0405 builder 生成 prompt,并由 Model
Gateway 执行 provider credential/配额/价格 fence。
3. 建立 Copilot 专用 encrypted model completion、Run/Step terminalization、取消、deadline 和恢复协议,
证明明文不进入数据库、审计、日志或普通 model completion。
4. 最后开放默认关闭的 Cluster API/CLI/UI/MCP 产品入口,并补多副本并发、真实 S3、外部 Provider
fault injection 与 plaintext negative evidence。
+1
View File
@@ -410,6 +410,7 @@
| [ADR-0404](./ADR-0404-optional-local-mcp-run-log-excerpt-surface.md) | 可选本机 MCP Run 日志摘录产品入口与私有文件边界 | Accepted |
| [ADR-0405](./ADR-0405-bounded-failure-diagnosis-prompt-and-model-egress-policy.md) | 有界故障诊断 Prompt 与显式模型出口策略 | Accepted |
| [ADR-0406](./ADR-0406-cluster-projected-tool-result-key-authority.md) | Cluster Projected Tool Result Key Authority | Accepted |
| [ADR-0407](./ADR-0407-cluster-copilot-failure-diagnosis-run-admission.md) | Cluster Copilot Failure Diagnosis Run Admission | Accepted |
## 规则