Files
qinglong/docs/adr/ADR-0175-private-authenticated-local-model-price-catalog-cli.md
T

167 lines
8.7 KiB
Markdown
Raw 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-0175:私有认证 Local Model Price Catalog CLI
- 状态:Accepted
- 日期:2026-07-27
- 关联:RFC D-49、D-73、D-84、D-85、D-156、D-162、D-163、D-164、D-165ADR-0085、ADR-0143、ADR-0167、ADR-0173、ADR-0174
## 背景
ADR-0174 已完成授权型 Model Price Catalog facade、双方言 9006 原子授权事实与
Profile 决策模式,但本机用户仍没有受审产品入口。若直接把 repository 暴露给脚本,
调用方就可以伪造 actor、Policy、assurance 或授权结果;若让常驻 edge runtime 或
`local-admin` 根入口静态导入 AI,则禁用 AI 的路由设备仍要支付模块加载和制品成本。
本机入口还存在两个真实竞态:
1. local-console 在事务外验证 credential 后,credential、pepper、User 或 Owner
binding 可能在 catalog transaction 开始前被撤销;
2. 同一私有命令文件在进程退出或响应丢失后重试,会建立新的认证时间窗。若把该时间
漂移当作 durable authorization 漂移,已经提交的命令无法安全收敛。
AI migration 是显式 feature stream。产品 CLI 不能为了“方便”在运行时自动执行
9001–9006 DDL,否则只读检查、低资源设备和生产变更控制都会失去边界。
## 决策
### 1. 复用现有短生命周期 CLI package
在现有 `@qinglong/local-owner-cli` 增加:
- 显式子路径 `@qinglong/local-owner-cli/model-price-command`
- 二进制 `ql3-model-price`
- `model-price.publish|activate|deactivate|revoke|inspect` 五种 operation。
不新增 workspace package、第三方依赖、daemon、listener、timer、watcher、缓存或数据库
连接。只增加 `local-owner-cli → @qinglong/ai` workspace 依赖;通用
`local-admin``cluster-admin`、默认 edge/standalone runtime 和基础制品不得反向导入
AI。命令执行完成后关闭单一 SQLite authority。
CLI 只接受:
```text
ql3-model-price run --command-file /absolute/private-command.json
```
命令文件必须是私有、规范化、有界绝对路径上的 exact-shape JSON。body 只能包含公开
intent、CAS fence、幂等 ID 和失败审计 event ID,不得包含 principal、subject、
authentication ID、assurance、Policy、decision mode、catalog/result digest 或任意
authority seam。输出只含 publication/head 与低敏授权摘要,不返回 credential、
principal 或认证 ID。
### 2. 显式 feature activation,运行时不执行 DDL
入口打开已经通过主 SQLite readiness 的数据库后,只读核对:
- 90019006 六条 AI migration history、stream identity 与 checksum
- 11 张 Model Invocation/Price Catalog 业务表;
- 独立 `QingLong3AiSchemaMigrations` history 表。
任一缺失或漂移均以 `LOCAL_MODEL_INVOCATION_FEATURE_NOT_READY` 失败,并且在认证前停止。
CLI 不创建、修补或迁移 schema。部署者必须通过受审 feature activation ceremony 先行
执行 AI migration。
### 3. 本机强认证与平台 Owner 资格
所有 operation 复用 local-console POSIX/private-file proof、API credential、
credential-version pepper provenance 和 `local_console` assurance。请求不得指定 User。
edge/standalone 当前以 `default` Project 的最新 active `owner` binding 证明该本机 User
是产品平台 Owner。这个 binding 只作为本机 operator 资格证据,不把价格数据变成
Project-scoped 资源:catalog、Policy、authorization 和 resolver 中仍不存在 Project ID。
`inspect` 也要求当前 Owner,避免该管理入口成为普通本机 User 的旁路。
本机平台 Policy 固定为:
- revision `local_console_platform_owner_v1`
- allow reason `local_console_confirmed`
- decision mode `human_confirmation`
Policy、assurance、principal 和 result digest 均由受信 composition 派生。
### 4. SQLite transaction 内二次围栏
`publishAuthorized`/`transitionAuthorized` 在取得 `BEGIN IMMEDIATE` 后、读取 replay 或
写入任何 catalog/authorization 行前调用同步 transaction hook。hook 在同一 connection
和 transaction 内精确复验:
- credential ID/version、active state、secret digest 与有效期;
- active User identity
- credential-to-pepper binding、active/retired pepper state 与 material digest
- `default` Project active 状态和该 User 最新 active Owner binding。
任一撤销、版本、摘要、时间或角色漂移都回滚 publication/head/authorization 全部写入。
进程时钟和事务外 `confirm()` 只用于早拒绝,不能代替数据库 fence。
### 5. 成功事实、失败审计与重放
成功 mutation 继续只由 9006 authorization 与 publication/head 在同一事务证明。
transport 不先写一条“成功 security audit”,避免双事务裂缝。
下列失败写入现有低敏 `QingLong3SecurityAuditEvents`
- credential authentication rejection
- credential/User/pepper transaction fence rejection
- 当前平台 Owner 资格 rejection
- Policy deny 或 quota deny。
审计只保存 caller 提供的独立 event ID、request/operation、nullable authenticated
subject/authentication ID、固定 outcome/reason 和本地时间;不保存 token、secret、
价格 body、stack 或 raw error。相同失败 event ID 的精确重放忽略观察时间差并收敛为
一条事实。
对于已提交 mutation,同一 authorization/request/catalog command、同一 User、同一
credential proof authentication ID、assurance、Policy 和 decision mode,可以在当前
transaction fence 再次通过后使用新的认证时间窗重放。repository 返回首次提交的不可变
authorization,不重写其时间或摘要;不同 User、authentication proof、Policy、ID 或
catalog command 仍然 conflict。
## 拒绝方案
1. **新增 `ql3-model-price-cli` package**:没有独立部署或权限边界,只会继续制造单文件
package,拒绝。
2. **把 CLI 放进常驻 edge runtime**:会扩大默认导入闭包和攻击面,拒绝。
3. **由 CLI 自动运行 AI migration**:把产品调用升级为 DDL authority,拒绝。
4. **只做事务外 local-console confirm**:无法关闭撤权竞态,拒绝。
5. **把调用方 body 当作 Policy 或 User 来源**:可伪造授权,拒绝。
6. **把价格目录挂到 `default` Project**:全局 catalog 会形成虚假租户边界,拒绝;
Owner binding 只证明本机 operator 资格。
7. **因新认证时间窗拒绝已提交重放**:会让响应丢失无法收敛,拒绝。
8. **用新认证覆盖首次授权事实**:会改写历史,拒绝。
9. **现在开放 Cluster CLI/HTTP**:尚无 TLS identity assertion、平台 Policy
repository、耐久 quota 与双人 ceremony,拒绝。
## 当前证据
- `@qinglong/ai` 92 项:90 pass2 条真实 PostgreSQL 条件 skip;新增 AI readiness、
transaction hook 与 fresh-reauth replay 测试;
- `@qinglong/local-owner-cli` 16/16,覆盖 publish replay、activate、inspect、真实
product binary、无敏感输出、未激活 schema、widened body、认证失败审计精确重放、
过期强认证、precheck 后 credential revoke 和非 Owner rollback
- 受影响 AI/local-sqlite/local-owner-console/local-owner-cli 均通过 TypeScript build
- 22 个 QL3 package 已完成干净全量 build/test0 fail22-importer dependency audit
覆盖 AI 20 个、Owner CLI 8 个源码文件且 `findings=[]`edge 121-module import gate
无 AI/cluster 越界;
- 默认 edge/standalone 仍为 3,910,465/3,910,525 bytes、478 files;显式
edge-ai/standalone-ai 为 4,555,506/4,555,578 bytes、520 files。禁用态三个 Profile
的 storage/provider/management loader 全为 0,模块加载 RSS 增量 475,136 bytes
- PostgreSQL 18.4 arm64 physical HA 总门通过:90019006、11 张 AI 表和最小 ACL
在 timeline 1→2 后一致,physical streaming、`remote_apply`、partition guard、
fencing、promotion、`pg_rewind` rejoin 与全部 domain gate 为 true;临时 Docker
资源已清理;
- workspace 仍为 22 个 QL3 package;没有新增第三方生产依赖或长期资源。
## 后续门禁
1. 独立、显式的 AI feature activation/deactivation 产品 ceremonyADR-0176 已完成);
2. 私有命令模板、operator 文档、备份/恢复和真实低配 Linux 设备证据;
3. Model Price Catalog mutation 专属 SQLite crash/COMMIT-response-loss 矩阵;
4. Cluster TLS/identity assertion、平台 Policy repository、耐久 quota、双人发布/激活
ceremony 与 deny/unavailable audit
5. Cluster 产品入口完成后重新运行 PostgreSQL 三角色 integration 与 physical HA 门。
## 后续状态
第 1 项已由 ADR-0176 完成:本机 9007 append-only active/inactive head、
`ql3-ai-feature`、migration plan/data-safety fence、Owner transaction fence 和
invocation/price 写事务内 active fence 已实现。其余门禁保持不变。