Files
qinglong/docs/adr/ADR-0237-capability-oriented-dependency-boundary-reconciliation.md

137 lines
6.9 KiB
Markdown
Raw Permalink 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-0237:面向能力的依赖边界对账
- 状态:Accepted
- 日期:2026-07-31
- 关联 RFCQL-RFC-0001 D-175、D-207、D-210、D-211、D-213、D-221
- 关联 ADRADR-0217、ADR-0220—0222、ADR-0229、ADR-0230、ADR-0236
## 背景
QingLong 3.0 的 Package 生命周期、自动化发布和 Workflow Task 纵切面完成后,仓库级
依赖审计报告 27 条 finding。它们混合了两类不同问题:
1. `cluster-admin` 的安装清单查询直接实例化
`PostgresPluginPackageInstallRepository`。该 concrete adapter 同时实现 inventory、
admission 和 install mutation port;即使调用方只使用两个查询方法,composition 已经
取得 executor authority,违反 ADR-0220 的 package-manager 只读边界;
2. 新增的 lifecycle/publication 文件与 Local Workflow 内部依赖已经由 ADR 定义,但
依赖审计的具体文件/subpath 清单仍停留在旧切片。
如果把两类 finding 都简单加入白名单,会掩盖真实权限泄漏;如果按每个共享 port 再拆
workspace package,则会重回“一文件一包”,增加路由设备的安装、构建、SBOM 和供应链
成本。
## 决策
### 1. 先区分 capability 泄漏与审计规则滞后
依赖审计 finding 不能直接以“代码已经存在”为理由放行。每条新边必须满足:
- 对应已有 RFC/ADR 的部署和 authority 方向;
- 只开放到具体 owner 文件和具体 package subpath
- 不让只读进程取得 mutation concrete adapter
- 不增加 Profile 无关的重依赖或常驻资源;
- 仍有负向测试证明相邻的宽入口和反向依赖被拒绝。
### 2. Package manager 使用独立只读 inventory reader
`cluster-postgres` 增加
`PostgresPluginPackageInstallInventoryReader`,只实现
`PluginPackageInstallInventoryRepository``findCurrent`
`listCurrentPage`。它只从 `@qinglong/cluster-postgres/package-manager` 导出;该入口
不得导出 `PostgresPluginPackageInstallRepository`reader prototype 也不得出现
admit/create/commit/recovery 方法。
`cluster-admin/pluginPackageManagement` 改为只装配该 reader。原 mutation repository
继续留在显式 `plugin-package-install`/package-executor 权限边界,既有安装与恢复语义不
修改。
### 3. Workflow Task repository port 上提为 package 内共享契约
`LocalWorkflowTaskExecutionRepository` 同时被 execution、control 和 recovery 使用,
因此不属于 `execution/` 实现区。它上提到 `local-execution/src` 的共享契约文件;
`./execution` 继续 re-export,保持公开 subpath 兼容。
审计只允许各区域导入这一条精确共享 port,不开放任意 root 文件。Scheduler 依赖
dispatch 是 ADR-0229 单 cadence 的最后一步,明确登记为
`scheduler → dispatch → execution` 的单向 DAG;反向 `execution → dispatch`
`control → recovery` 等继续拒绝。
### 4. 新纵切面使用具体文件 + 具体 subpath 清单
以下边只对对应 owner 文件开放:
- Owner CLI lifecycle command → local-admin lifecycle、SQLite install inventory 与
runtime lifecycle contract
- local-admin lifecycle service → SQLite approval/operation/lifecycle/policy authority 与
runtime approval/lifecycle/policy/security/audit contract
- local-application activation/contract → runtime automation publication contract
- Cluster lifecycle management → manager/approval/policylifecycle executor →
executor/approval/policy
- management transport → capability-free lifecycle plan DTO
- Cluster installation management → package-manager 只读入口。
未知文件、根入口、driver、executor repository 或相邻 authority 不因这些决策获得通配
权限。
### 5. 不新增 workspace package
workspace 保持 20 个 package。共享 port、只读 adapter 和审计契约都进入已有职责
owner;它们没有独立部署、发布、重依赖、凭据、故障域或 Profile 替换价值。文件数量
继续不作为拆包理由。
## 不采用方案
### 把 27 条 finding 全部加入宽白名单
拒绝。会把 manager→executor concrete adapter 泄漏永久合法化,并让后续同 package
文件获得未审 authority。
### 让只读 reader 包装或继承 mutation repository
拒绝。包装仍在 composition 内构造 mutation authority,继承则直接把 mutation 方法
暴露在 reader 对象上,都不满足 capability 最小化。
### 新建 inventory、workflow-contract 或 lifecycle workspace package
拒绝。这些能力都由既有 package/进程 owner 使用,没有独立交付价值;拆包只会增加
低配设备闭包和维护成本。
### 直接允许 control/recovery 依赖 execution 实现区
拒绝。共享 port 应属于中性契约层;允许反向实现依赖会使内部 DAG 失去约束。
## 影响
- workspace、生产依赖、migration、表、角色、进程、端口、Pool、timer、watcher、
listener 和常驻内存均不增加;
- `@qinglong/local-execution/execution` 公共导出保持兼容;
- PostgreSQL mutation repository 的已有方法和三个生产调用者不修改;
- package-manager 只增加可审计的只读 capability,不获得 install mutation authority
- 依赖审计从 27 条 finding 收敛为 0。
## 验证
1. GitNexus impact`PostgresPluginPackageInstallRepository` 为 CRITICAL3 direct、
7 upstream),因此不修改其既有方法;
`createClusterPluginPackageManagementService` 为 LOW1 direct、3 upstream);
`LocalWorkflowTaskExecutionRepository` 为 MEDIUM5 direct、20 upstream);
`auditSourceImports` 为 LOW1 direct);
2. cluster-postgres、cluster-admin 与 local-execution strict TypeScript closure check
通过;
3. 依赖审计报告 `findings=[]``compatible=true`20 个 importer 不变;
4. 依赖边界 38/38,通过精确 lifecycle/publication 正向边、共享 port、scheduler DAG
并继续拒绝 manager→executor concrete adapter 和内部反向依赖;
5. package-manager entrypoint 证明只读 reader 可达、mutation repository 不可达,
reader prototype 仅有 constructor/findCurrent/listCurrentPage;另以无 connect、无
mutation 的 query-only pool 实际验证 exact/list 和 `limit + 1` 参数;
6. 受影响包全量测试:cluster-postgres 249 pass/1 条真库条件 skip、cluster-admin
133 pass/1 条真实 Kubernetes 条件 skip、local-execution 30/30Cluster Admin 两个
过期 role fixture 同步拒绝三个 runtime-only function,生产 readiness 未放宽;
7. PostgreSQL `18.4 (Debian 18.4-1.pgdg13+1)` arm64 physical HA 通过
`remote_apply`、timeline 1→2、旧主先 fencing、`pg_rewind` 只读同步重入和两个 fresh
control replicasinventory 提升前为 quarantined、list 有结果、提升后存活,全部具体
gate 与 `gates.passed=true`
8. HA 临时容器、网络和卷已清理;已有且与本门无关的
`ql3-cnpg-evidence-control-plane` 未修改。