mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
118 lines
6.4 KiB
Markdown
118 lines
6.4 KiB
Markdown
# ADR-0142:认证后 Plugin Package 管理 Facade 与 Profile ceremony
|
||
|
||
- 状态:Accepted(transport-neutral 管理 facade、SQLite 真实端到端闭环与
|
||
local/cluster Profile 组合已实现;本机 CLI 由 ADR-0143 完成,Cluster transport
|
||
边界由 ADR-0144 冻结,identity/keyset 与 HTTP process 由 ADR-0145 完成;
|
||
durable quota 由 ADR-0146 完成,ADR-0149 已完成原子 resource generation
|
||
identity/source;真实双 User/UI 与资源语义 materializer 待完成)
|
||
- 日期:2026-07-25
|
||
- 关联 RFC:QL-RFC-0001 D-05、D-08、D-09、D-85、D-130 至 D-140
|
||
|
||
## 上下文
|
||
|
||
ADR-0141 已完成 immutable proposal、durable Approval、execution/start barrier、
|
||
Package 原子 admission 和调用方驱动 dispatcher,但这些能力仍是彼此独立的显式
|
||
authority。若 HTTP、CLI、UI 或自动化入口自行拼接这些 repository,很容易出现:
|
||
|
||
1. 在解析完整 Package action 前查询 Policy,或绕过 `package.manage`;
|
||
2. 由 transport 提交 Project/RoleBinding fence,而不是读取当前 Policy snapshot;
|
||
3. local 与 cluster ceremony 漂移为“全部允许自批”或“全部强制四眼”;
|
||
4. consumption 复用用户输入的 consumer identity;
|
||
5. proposal、request、decision、consume 和 dispatch 各自生成不稳定幂等身份;
|
||
6. 为每种 transport 或 Profile 新建 workspace package。
|
||
|
||
公开 transport 现在还不能直接开放,但必须先建立唯一的 use-case 组合边界,后续
|
||
adapter 才不会再次复制安全协议。
|
||
|
||
## 决策
|
||
|
||
### 1. 共享 use-case 留在 runtime-core 显式子路径
|
||
|
||
新增 `@qinglong/runtime-core/plugin-package-management`,不新增 workspace package、
|
||
第三方依赖、timer、watcher、socket 或数据库连接。Facade 只接受已经认证且仍 active
|
||
的 `SecurityPrincipal`,并固定提供:
|
||
|
||
- `propose`:规范化完整 install action,执行 `package.manage` Policy,使用返回的
|
||
fence 创建 immutable proposal,再创建 digest-bound ApprovalRequest;
|
||
- `decide`:重新读取 request,以当前 principal 对 `approval.decide` 执行 Policy,
|
||
再提交强认证 decision;
|
||
- `consume`:只使用构造时注入的 system consumer authority,重新读取 requester 的
|
||
`package.manage` Policy fence,再原子生成 dispatch/execution baseline;
|
||
- `inspect`:只读取 proposal 与 request durable fact;
|
||
- `dispatch`:调用既有 bounded dispatcher,不安装后台循环。
|
||
|
||
Facade 不接收调用方提供的 Policy fence、consumer subject、action digest 或 preview
|
||
digest;这些事实必须分别来自 Policy engine、固定 composition 和 canonical proposal。
|
||
|
||
### 2. 幂等身份由请求显式携带
|
||
|
||
写操作必须携带稳定的 action/request/decision/consumption/dispatch/audit identity
|
||
以及对应发生时间。相同 identity 与相同语义可 exact replay;不同内容复用 actionRef
|
||
或 approvalRequestId 必须冲突。Facade 不在响应丢失后静默生成新 identity。
|
||
|
||
默认 Approval lifetime 为 15 分钟,可由受信 composition 缩短或在领域允许的 24 小时
|
||
上限内调整。已超出 lifetime 的新 `propose` 调用在任何 mutation 前拒绝。
|
||
|
||
### 3. Profile 固定 ceremony,不让 transport 选择
|
||
|
||
- `@qinglong/local-admin/package-management` 固定
|
||
`human_confirmation`,复用唯一 `LocalSqliteOperationAuthority`,edge/standalone
|
||
dispatcher 默认批量仍为 1/4;
|
||
- `@qinglong/cluster-admin/plugin-package-management` 固定
|
||
`separation_of_duty`,使用 admin-only PostgreSQL repository,dispatcher 默认批量
|
||
仍为 16;
|
||
- 两个入口都不从 package root、常驻 runtime、cluster-control 或 worker 导出。
|
||
|
||
local 新增 `@qinglong/local-sqlite/project-policy` 窄 adapter,cluster 只给现有
|
||
`PostgresProjectPolicyRepository` 增加显式 `project-policy` export。没有新增表、
|
||
migration、连接或 importer。
|
||
|
||
### 4. 公开 transport 继续失败关闭
|
||
|
||
本 ADR 的“认证后”表示 facade 不接受匿名/过期 principal,并不表示 bearer token、
|
||
本机 credential file、MFA/hardware assertion 或 HTTP session 已在这里完成验证。
|
||
真实 transport adapter 必须在调用 facade 前完成:
|
||
|
||
- bounded request/body/command-file 解析;
|
||
- credential 或本机 console proof;
|
||
- rate limit、取消和 response mapping;
|
||
- secret 不进入 argv/stdout/audit;
|
||
- transport response-loss 的 idempotency key 保留。
|
||
|
||
因此当前不能把内部 subpath 注册为 2.x Controller route,也不能宣称 UI 或
|
||
cluster admin transport 已生产开放。本机私有 command-file CLI 由 ADR-0143 完成;
|
||
ADR-0145 提供的 cluster HTTP process 和 Kubernetes operation 仍默认关闭,生产
|
||
ingress 继续受 keyset anti-rollback、真实双 User 与 live ingress 门约束。
|
||
|
||
## 影响
|
||
|
||
- Package 管理 use-case 不再由每种 transport 自行拼 repository;
|
||
- workspace importer 仍为 21,runtime-core 只增加一个纯协调 source;
|
||
- edge 禁用 Package 时不会加载 facade 或任何 Package storage;
|
||
- cluster-control/runtime/worker 仍无 proposal、decision、consume 或 admission 写权限;
|
||
- ADR-0143 已在同一 facade 上实现短生命周期本机 CLI;独立 cluster admin API
|
||
已由 ADR-0144 冻结双 authority 边界,仍无需改变领域和 Package 数据库协议。
|
||
|
||
## 验证
|
||
|
||
1. runtime-core 250/250,其中新增四眼审批、operator mutation-before-deny 与
|
||
authorization-before-quota 门禁;
|
||
2. local-admin 54/54,其中真实 Node 24 SQLite 流程覆盖
|
||
`propose → self-confirm → consume → dispatch → queued admission`;
|
||
3. 弱认证 decision 与过期 propose 在 mutation 前失败,失败 decision 不产生 Audit;
|
||
4. 完整流程产生 proposal/request/decision/consume/admit 五类 durable Audit;
|
||
5. cluster-admin 63 pass/1 条件 skip,构造不打开 PostgreSQL且 ceremony 常量固定为
|
||
`separation_of_duty`;
|
||
6. 26 项 source-boundary test 与 cluster dependency audit
|
||
`findings: []`、`compatible: true`;
|
||
7. importer 仍为 21;新增能力均为既有 package 的显式 subpath。
|
||
|
||
## 后续门禁
|
||
|
||
- 为 keyset generation/revocation 增加跨全副本重启的 durable anti-rollback;
|
||
- response-loss 下相同 transport idempotency key 的完整端到端重放;
|
||
- PostgreSQL 真库 separation-of-duty/concurrent decision/consume;
|
||
- ADR-0149 已完成 generation publisher/source;继续实现
|
||
Task/Workflow/Prompt/Tool 语义 materializer;
|
||
- UI 只消费低敏 preview/status,不持有数据库或 dispatcher authority。
|