mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
60 lines
4.6 KiB
Markdown
60 lines
4.6 KiB
Markdown
# ADR-0354:精确、双授权的本机 MCP Approval 预览
|
||
|
||
- 状态:Accepted
|
||
- 日期:2026-08-10
|
||
- 关联 RFC:QL-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
|
||
- 关联 ADR:ADR-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 fence;PostgreSQL 实现同一 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 审计 compatible;MCP 对 Artifact subpath 的一次越权 import 被门禁发现并通过
|
||
document-only port 消除,而不是放宽规则。
|
||
- 十二档 artifact compatible。Standalone Application AI 为 6,261,021 bytes/637 files,余 30,435 bytes;Standalone MCP
|
||
为 9,857,149 bytes/947 files/203 modules,RSS 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。
|