mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-23 03:18:09 +08:00
162 lines
8.2 KiB
Markdown
162 lines
8.2 KiB
Markdown
# ADR-0176:显式 Local AI Feature 启用与非破坏性停用
|
||
|
||
- 状态:Accepted
|
||
- 日期:2026-07-27
|
||
- 关联:RFC D-40、D-73、D-84、D-87、D-156、D-165、D-166;ADR-0087、ADR-0167、ADR-0175
|
||
|
||
## 背景
|
||
|
||
ADR-0175 要求 Model Price Catalog CLI 不得自动执行 AI DDL,但部署者当时没有受审的
|
||
产品启用入口,只能由测试或部署代码直接调用 `migrateLocalModelInvocationFeature()`。
|
||
这会产生三个问题:
|
||
|
||
1. “schema 已存在”和“部署者已明确启用”是同一个隐式状态,无法安全停用;
|
||
2. 迁移版本、备份确认、稳定 User、强认证和当前 Owner 没有绑定到耐久启用事实;
|
||
3. 只在 CLI 外层检查启用状态,无法阻止停用提交后的并发 invocation admission。
|
||
|
||
本机 feature migration 还可能跨多个 SQLite 事务。进程在某一步迁移后退出时,不能假装
|
||
整次启用原子完成;重试必须从受审 history/checksum 恢复,并且只有最后的 activation
|
||
transition 提交后,业务写入口才可到达。
|
||
|
||
## 决策
|
||
|
||
### 1. 复用现有包和短生命周期 authority
|
||
|
||
在现有 `@qinglong/local-owner-cli` 增加:
|
||
|
||
- 显式子路径 `@qinglong/local-owner-cli/ai-feature-command`;
|
||
- 二进制 `ql3-ai-feature`;
|
||
- `ai-feature.inspect|activate|deactivate` 三种 operation。
|
||
|
||
不新增 workspace package、第三方依赖、daemon、listener、timer、watcher 或缓存。CLI
|
||
仍只接受私有 exact-shape command file,完成后关闭唯一 SQLite authority。默认
|
||
edge/standalone runtime、通用 local-admin 和 Cluster image 不导入该入口。
|
||
|
||
现有 SQLite facade 的实现原本以 Plugin Package 命名,却已被多个本机管理域复用。
|
||
本 ADR 在同一个 `@qinglong/local-sqlite` 包内增加中性的
|
||
`/authenticated-management` 子路径,并保留 `/package-management` 兼容入口;不为
|
||
一个类型别名拆新包。
|
||
|
||
### 2. 9007 只属于本机 AI feature stream
|
||
|
||
本机 AI migration stream 在既有 9001–9006 后追加:
|
||
|
||
```text
|
||
9007-ai-feature-activation
|
||
```
|
||
|
||
9007 创建两张本机控制表:
|
||
|
||
- `ModelInvocationFeatureTransitions`:append-only generation、active/inactive、
|
||
mutation/request、migration plan、data-safety、User/authentication 和 digest;
|
||
- `ModelInvocationFeatureHead`:只指向一个已存在的不可变 transition。
|
||
|
||
PostgreSQL Cluster 仍保持 pg-9001–pg-9006、11 张业务表和既有 ACL,不能把本机
|
||
Owner ceremony 复制成 Cluster authority。9007 checksum 为
|
||
`2454987c61a48dc5286a883d755c709000e6fd630025373cb276723001bdcc6c`;
|
||
包含 9001–9007 的 migration plan digest 为
|
||
`529cd8d3bce9ef124dd609044c4f704ea313926c9c8fc422c23871e110fed538`。
|
||
|
||
### 3. inspect、activate 与 migration plan fence
|
||
|
||
`inspect` 只有在 local-console 强认证和当前 `default` Project Owner 复验后,才返回:
|
||
|
||
- `absent | partial_or_drifted | ready` 三态 schema 摘要;
|
||
- 当前 active/inactive generation 的低敏摘要;
|
||
- 当前二进制的 migration plan digest。
|
||
|
||
`activate` command 必须回传 inspect 得到的 exact plan digest 和 CAS generation/state。
|
||
代码版本、迁移顺序或任一 checksum 改变都会形成新 plan digest,旧 command 不得执行
|
||
新 DDL。
|
||
|
||
首次启用必须选择一种 data-safety 证据:
|
||
|
||
- `fresh_database`:只允许没有 AI durable data 的 feature;不带备份 digest;
|
||
- `backup_verified`:带 64 位十六进制 backup evidence digest。
|
||
|
||
CLI 在 DDL 前和 transition 前均复验 credential、pepper、User 和 Owner。9001–9007
|
||
逐步使用既有 migration history/checksum 收敛;崩溃后可能留下 reviewed partial
|
||
schema,但不会留下 active head。重试完成全部 migration 并再次通过强认证后,才在
|
||
一个 `BEGIN IMMEDIATE` 中写 transition/head。相同 mutation 的响应丢失重试优先返回
|
||
首次 durable transition,即使启用后已经产生业务数据也不得重新执行“空库”裁决。
|
||
|
||
### 4. 停用不删除数据,并形成 admission fence
|
||
|
||
`deactivate` 只追加下一代 `inactive` transition 并更新 head:
|
||
|
||
- 不执行 `DROP`、`DELETE`、清表、回滚 migration 或修改历史;
|
||
- data-safety 必须固定为 `preserve_existing`;
|
||
- 有未完成 ModelInvocation 时拒绝停用;
|
||
- credential/User/pepper/Owner 与未完成调用检查在 transition 的同一
|
||
`BEGIN IMMEDIATE` 中再次执行。
|
||
|
||
本地 invocation 的 `admit`、`admitWithQuota`、`admitWithPricing` 在各自
|
||
`BEGIN IMMEDIATE` 内、写任何新 start 前读取 active head。价格目录 mutation 也在其
|
||
事务 hook 内复验 active。由此:
|
||
|
||
- admission 先提交时,停用随后看到未完成调用并拒绝;
|
||
- 停用先提交时,后续 admission/价格 mutation 看到 inactive 并拒绝;
|
||
- 已经存在的 admission replay 和 completion/recovery 仍可完成,不因停用破坏耐久
|
||
收敛。
|
||
|
||
这是一条数据库串行化写围栏,不依赖进程内布尔值、文件锁或 watcher。
|
||
|
||
### 5. 鉴权、审计和输出
|
||
|
||
三种 operation 都要求稳定 User、`local_console` assurance、credential-version pepper
|
||
provenance 和当前平台 Owner。命令不得提供 principal、authentication ID、assurance、
|
||
Owner、Policy 或数据库时间。
|
||
|
||
成功由 append-only transition/head 证明;失败写现有低敏 SecurityAudit,固定原因包括:
|
||
|
||
- `credential_rejected` / `credential_fence_rejected`;
|
||
- `platform_owner_required`;
|
||
- `data_safety_rejected`;
|
||
- `in_flight_invocation`;
|
||
- `transition_conflict` / `transition_unavailable`;
|
||
- `migration_unavailable`。
|
||
|
||
输出不包含 credential、secret、principal、subject ID、authentication ID、备份路径或
|
||
DDL 细节。
|
||
|
||
## 拒绝方案
|
||
|
||
1. **新增 `ql3-ai-feature-cli` package**:没有新的部署边界,只会制造小包,拒绝。
|
||
2. **让 `ql3-model-price` 顺便迁移**:把日常业务管理升级为 DDL authority,拒绝。
|
||
3. **以 schema presence 代表 enabled**:无法表达显式停用和 operator intent,拒绝。
|
||
4. **停用时 DROP AI 表**:破坏账本、重放、恢复和备份语义,拒绝。
|
||
5. **只在启动配置读取一个布尔值**:无法和 durable admission transaction 串行化,
|
||
拒绝。
|
||
6. **只在停用前事务外检查未完成调用**:检查后仍可并发创建 start,拒绝。
|
||
7. **把 9007 同步加入 PostgreSQL**:本机 Owner ceremony 不具备 Cluster TLS、平台
|
||
Policy、耐久 quota 和职责分离 authority,拒绝。
|
||
|
||
## 当前证据
|
||
|
||
- AI suite 96 项:94 pass、2 条真实 PostgreSQL 条件 skip;覆盖 9007 schema/history、
|
||
append-only transition/head、CAS/plan/identity drift、事务 hook/replay、inactive
|
||
admission fence 和既有 crash matrix;
|
||
- local-owner-cli 22/22,覆盖真实 `ql3-ai-feature` binary、inspect/activate/replay/
|
||
deactivate、无敏感输出、widened body、plan drift、pre-migrated backup evidence、
|
||
credential revoke、in-flight deactivation rejection 和 inactive price gate;
|
||
- local-sqlite 127/127;22-importer dependency audit `findings=[]`,AI 21 个、Owner
|
||
CLI 10 个源码文件;edge 121-module import gate 无 AI 越界;
|
||
- clean build 后 workspace 仍为 22 个 QL3 package,没有新增生产依赖或常驻资源;
|
||
base edge/standalone 均为 478 files,AI opt-in 制品均为 522 files,disabled loader
|
||
的 storage/provider/management authority load 保持为 0;
|
||
- 2026-07-27 重新执行 PostgreSQL 18.4 arm64 physical HA 门,timeline 1→2、
|
||
old-primary fence、双 control replica 重建、`pg_rewind` 只读 sync rejoin 与总
|
||
`gates.passed=true`。AI 专项在 promotion 前后均精确保持 pg-9001–pg-9006、
|
||
11 张表和同一最小权限矩阵;本机 9007 未进入 PostgreSQL history,因而该证据不
|
||
冒充 Cluster activation ceremony。
|
||
|
||
## 后续门禁
|
||
|
||
1. 产品启动 composition、active-head dynamic import、restart/drain/operator UX 已由
|
||
ADR-0177 完成;真实产品 executable 仍需选择该显式入口;
|
||
2. 私有命令模板、备份/恢复演练和真实低配 Linux 设备断电/ENOSPC 证据;
|
||
3. activation transition 与 Model Price mutation 专属 SQLite
|
||
COMMIT-response-loss/SIGKILL 矩阵;
|
||
4. Cluster TLS identity、平台 Policy/quota、双人 activation 和独立 transport;
|
||
5. 只有 Cluster 入口变更 PostgreSQL schema/ACL 后才重跑对应三角色与 physical HA 门。
|