Files
qinglong/docs/adr/ADR-0354-exact-local-mcp-approval-preview.md
T

60 lines
4.6 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-0354:精确、双授权的本机 MCP Approval 预览
- 状态:Accepted
- 日期:2026-08-10
- 关联 RFCQL-RFC-0001 D-05、D-06、D-08、D-13、D-17、D-28、D-75、D-85、D-87、D-157、D-257、D-259、D-260、D-263、D-265、D-266
- 关联 ADRADR-0138、ADR-0347、ADR-0351、ADR-0353
## 背景
`qinglong.approval.list` 可以说明动作处于 pending、approved、rejected 或 consumed,但故意不返回 preview。AI Client
若无法看见经过 redaction contract 生成的动作摘要,就不能做有意义的人工转交;若直接取得完整 Approval 或 Tool
Invocation Artifact,又会泄露 action reference、digest、主体与密文入口。现有 Approval 和 Tool preview 表已经分别保存
同一个 Project/action binding,缺口是最窄的精确关联读端口,而不是新表、Artifact 解密或审批写流程。
## 决策
1. 增加 `qinglong.approval.get@1.0.0`,输入只允许 `requestId`Project 只能来自私有 MCP 配置。
2. 调用固定要求 exact `tool.call:qinglong.approval.get``approval.read``artifact.read`。两个既有只读权限缺一不可;
之后仍须 durable Security Audit 和 credential fence confirm。
3. SQLite/PostgreSQL 先按 Project+request ID 读取并复验 canonical Approval、request digest 与更新时间镜像;只有
`tool.invoke` 才按 `projectId/actionRef/actionDigest/previewDigest` 四元组 LEFT JOIN 已有 preview 表。
4. Adapter 必须规范化完整 preview Artifact,并复验 artifact/project/action/digest/redaction/size/time 的所有镜像;任何
漂移映射为稳定 unavailable。无匹配 preview 是合法的 `previewAvailable=false`,不得猜测或扫描。
5. Runtime read port 只携带 Approval record 与已经验证的 preview document。MCP package 不得 import Tool Invocation Artifact
subpath,不得取得 artifact ID、repository、input ciphertext、key、nonce、auth tag、任一 digest 或解密 authority。
6. 输出只含 Approval list 已公开的低敏元数据、`previewAvailable`,以及有界 title、summary、最多 16 个 field 和 8 个
warning。`redacted` field 省略 value;不返回 Project、action reference、主体 ID、fence 或决定/消费/派发证据。
7. 不新增 package、dependency、migration、连接、listener、timer、watcher、cache 或写 authority。SQLite 复用 MCP 的唯一
connection/operation queue/close fencePostgreSQL 实现同一 port 供未来 Cluster 产品组合使用,但本 ADR 不建立 Cluster MCP。
## Package 粒度裁决
公共 read contract 属于 Runtime Core 的现有 `approved-action/` domain;双方言完整 Artifact 关联归各自 storage adapter
单一 MCP 消费者的字段投影归现有 `local-mcp-server/tool-projection/`。因此只新增一个嵌套 projection 文件,没有新 workspace
package。当前为 17 package/999 source、973 nested、26 root,无单源或 shallow package。
## 被否决方案
1. 只要求 `approval.read`:把索引观察权限隐式扩大为 Artifact 内容权限。
2. MCP 直接使用 Artifact repository:会把密文存储面和未来解密能力带入协议进程。
3. Client 提供 action reference/digest 或 artifact ID:暴露内部证据,并形成跨请求枚举面。
4. 把 preview 复制进 Approval 表:需要 migration、重复事实和双写一致性协议。
5. 为 detail/source/projection 新建 package:没有独立制品、依赖、authority 或版本生命周期收益。
6. 同时开放 approve/consume:缺少强人类 ceremony、事务 start barrier 与写恢复产品门。
## 验证
- Runtime Core 451/451、Local SQLite 208/208、Local MCP 38/38、PostgreSQL 290 pass/1 条件 skip。
- 真实 SQLite migration/row corruption、PostgreSQL 参数化关联、in-memory MCP admission 与真实 stdio/API Credential/Audit 均覆盖。
- package boundary、dependency 和 edge import 审计 compatibleMCP 对 Artifact subpath 的一次越权 import 被门禁发现并通过
document-only port 消除,而不是放宽规则。
- 十二档 artifact compatible。Standalone Application AI 为 6,261,021 bytes/637 files,余 30,435 bytesStandalone MCP
为 9,857,149 bytes/947 files/203 modulesRSS 40,632,320 bytes。
- PostgreSQL 18.4 arm64 HA `gates.passed=true`,结束后 QingLong 临时 Docker 容器、卷、网络均为零。
## 后续约束
人工 approve/reject、consume/dispatch 和实际 Tool execution 必须分别定义强认证、职责分离、幂等命令、原子审计、start
barrier 与响应丢失恢复协议。不得因为 preview 已可读就把任何写能力加入当前 MCP read authority。