feat(ql3): establish 3.0 incubation baseline

This commit is contained in:
whyour
2026-08-12 00:25:26 +08:00
parent 4bf92dcfeb
commit c699c32461
2817 changed files with 779642 additions and 653 deletions
@@ -0,0 +1,169 @@
# ADR-0212Owner 围栏化 Local Project 生命周期
- 状态:Accepted
- 日期:2026-07-29
- 关联 RFCQL-RFC-0001 D-05、D-27、D-37、D-65、D-72、D-73、D-175、
D-198、D-201、D-202
- 关联 ADRADR-0028、ADR-0074、ADR-0086、ADR-0185、ADR-0207、
ADR-0208、ADR-0211
## 背景
ADR-0208 让既有 Project 的 RoleBinding 有了强认证产品入口,但 Project 本身仍只能
通过迁移、测试 fixture 或直接 SQL 建立。部署者无法用受支持方式:
- 创建第二个业务 Project
- 原子建立首个可接管 Owner
- 暂停一个 Project 的全部业务授权;
- 在保留历史、RoleBinding 和资源的前提下恢复 Project。
Project lifecycle 是实例级管理动作,不应由任意 secondary Project Owner 执行。
如果创建 Project 与创建首 Owner 分成两个事务,进程在中间崩溃会留下无人可管理的
active Project。若直接覆盖 Project 行,又会失去响应丢失重放和审计事实。
## 决策
### 1. 扩展既有 `ql3-policy`,不新增 workspace package
继续使用以下既有边界:
- `@qinglong/runtime-core/local-project-policy-administration`:命令、结果和错误契约;
- `@qinglong/local-sqlite/project-policy-administration`:最终事务 authority
- `@qinglong/local-admin/project-policy-administration`:强认证 Owner 服务;
- `@qinglong/local-owner-cli/project-policy-command`:私有 command file 与低敏输出;
- `ql3-policy`:一次命令、一次进程的产品 binary。
新增三个 operation
- `policy.project.create`
- `policy.project.archive`
- `policy.project.restore`
workspace 仍为 22 个 package。该领域与 RoleBinding 共享认证、Policy、SQLite
authority、CLI 和部署消费者,不满足 ADR-0185 的新交付/进程/依赖隔离条件;把它
拆成单文件 package 只会增加 importer、lockfile 和供应链维护成本。
### 2. 只有实例 authority Project 的当前强认证 Owner 可以变更生命周期
command 同时携带 `authorityProjectId` 和目标 `projectId`。服务层先要求调用者在
authority Project 上通过 Owner-only `project.manage`。SQLite 在 `BEGIN IMMEDIATE`
取得写锁后再次复验:
1. authenticated credential、Identity、有效期、pepper binding/catalog/material
2. ADR-0211 的实例 authority anchor
3. authority Project active/version
4. actor 最新 RoleBinding version/state/owner role。
secondary Project Owner 即使能通过自己 Project 的 policy,也会在最终 authority
anchor 检查失败关闭。直接调用 repository 不能绕过。
### 3. Project create 与首 Owner、审计、mutation ledger 原子提交
`policy.project.create` 要求:
- `expectedCurrentVersion = 0`
- 唯一且规范的 Project ID、name、slug
- UUIDv4 mutation 和独立 failure-audit UUID
- Profile 容量仍有余量。
同一事务插入:
1. version 1、active 的 Project
2. actor 自身 version 1、active/owner 的 RoleBinding
3. allowed security audit
4. immutable Project administration mutation。
任一步失败全部回滚。成功输出只含 Project ID、name、slug、status、version 和
`inserted|existing`
### 4. archive/restore 是版本化状态转换,不删除历史
- archive`active@N → archived@(N+1)`
- restore`archived@N → active@(N+1)`
- 两者都使用 expected-version CAS
- authority Project 禁止 archive
- archived Project 由现有 Project Policy 默认拒绝业务权限;
- RoleBinding、Task、Run、Secret、Package 和审计历史不删除;
- restore 后沿用既有 RoleBinding,重新进入正常 Policy 判定。
本切片不提供 hard delete。需要资源清理时必须另建引用感知、可恢复的 retention
协议,不能把 archive 冒充删除。
### 5. mutation ledger 提供精确响应丢失重放
SQLite v37 新增 `QingLong3ProjectAdministrationMutations`,冻结 operation、
authority Project、目标 Project 快照、前后版本、actor、首 Owner version、audit 和
时间。相同 mutation 且语义完全一致返回 `existing`;相同 mutation 用于不同操作、
Project、metadata、版本、actor 或 audit 时返回 mutation conflict。
Project 当前行是可变 headmutation ledger 是不可变历史,两者不能合并成同一事实。
### 6. Profile 容量是硬上限
- Edge:最多 16 个 Project
- Standalone:最多 128 个 Project。
容量在最终写事务内计数,达到上限时不写 Project、Owner、allowed audit 或 mutation。
archive 不释放名额,因为对象和引用仍然存在。容量仅影响人工管理命令,不增加
daemon、timer、watcher、listener、缓存或空闲写入。
## 不采用方案
### 为 Project lifecycle 新建 package
拒绝。它与 RoleBinding 共用同一产品、authority 和交付闭包,没有独立消费者或进程
权限,违反 ADR-0185 的 package budget。
### 允许任意 Project Owner 创建其他 Project
拒绝。Project-scoped RBAC 不能隐式授予实例拓扑 authority,否则 secondary Owner
可无限扩展实例作用域。
### 先创建 Project,再单独授予 Owner
拒绝。崩溃窗口会留下 active 但无人可管理的 Project。
### archive 时删除 RoleBinding 或业务数据
拒绝。删除会破坏审计、历史 Run 可解释性和可恢复性,也无法安全判断所有引用。
### 只更新 Project 当前行,不保存 mutation ledger
拒绝。COMMIT response loss 后无法区分未执行、已执行和被其他命令覆盖。
## 影响
正向影响:
- 本机部署首次具备受支持的多 Project 创建、暂停和恢复路径;
- 创建后立即存在可登录、可交接的 Owner;
- archived Project 自动复用既有默认拒绝 Policy;
- secondary Project Owner 与 direct repository caller 均不能扩大实例拓扑;
- Edge/Standalone 资源上限明确,空闲成本为零;
- workspace 保持 22 包,没有新增第三方依赖。
代价与限制:
- Local SQLite contract 从 v36 提升到 v37,镜像和 rollout 写契约必须同步升级;
- Project list/inspect 由 ADR-0213 补齐;当前仍没有 rename、authority transfer 或
hard-delete 产品命令;
- authority Project 无法 archive;恢复该根对象需要未来独立 break-glass ceremony
- Cluster 仍使用 PostgreSQL/RBAC 管理面,不能复用本机 command file。
## 验证
- GitNexus 对共享 SQLite readiness 入口评估为 CRITICAL15 个直接调用者、35 个上游
符号;v37 必须跑迁移、冷启动、rollout 和既有安全回归;
- `ql3-policy` 真实 SQLite/CLI 10/10
- create/exact replay
- 首 Owner、audit、mutation 原子事实;
- archive 后业务 policy 拒绝、restore 后恢复;
- mutation drift、ID/slug 冲突;
- authority Project archive 拒绝;
- secondary Project Owner 越权拒绝;
- Edge 第 17 个 Project 在零部分写入下拒绝;
- 既有 RoleBinding、防锁死和 credential fence 回归;
- SQLite database 13/13、rollout safety 7/7、Identity/Credential 聚焦 4/4
- local-admin 与 local-owner-cli strict TypeScript 通过;
- Local image/OCI labels、CI image contract 和 deployment evidence 必须固定为 v37
- 完整 workspace、制品/RSS 和 PostgreSQL HA 门在锁定依赖恢复后重跑。