Files
qinglong/docs/adr/ADR-0270-authenticated-local-plugin-package-workflow-product-entry.md
T

95 lines
5.3 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-0270:受认证的本机 Plugin Package Workflow 产品入口
- 状态:Accepted
- 日期:2026-08-04
- 关联 RFCQL-RFC-0001 D-08、D-09、D-12、D-70、D-212、D-213、D-250、D-251
- 关联 ADRADR-0223、ADR-0227、ADR-0228、ADR-0229、ADR-0269
## 背景
QingLong 3.0 已完成 Plugin Package Workflow 的 immutable plan、双方言 admission、frontier、
Task Attempt、执行、恢复、整体取消、唯一 scheduler cadence 和低资源门。但是本机产品只有 Package
安装/发布与 application runtime,没有受认证的 operator 入口来发现和启动已发布 Workflow。测试夹具能
直接调用 repository 不等于部署用户具备可用产品链。
如果 CLI 接受完整 publication、materialized revision 或 plan,调用者会取得本应由服务端权威派生的
generation/digest 字段;如果先做 Policy 检查再在另一个事务 admissioncredential revoke、RoleBinding
变化或 Project archive 可以穿过 TOCTOU 窗口。
## 决策
### 1. 在既有 Owner CLI 增加 `ql3-workflow`
命令只读取当前 UID 的私有 `0600` command file,提供:
- `workflow.inspect`:使用 `run.read`,只返回当前 Package automation publication 的 Workflow 名称、
enabled 状态、Step key、Task key 与依赖;
- `workflow.start`:使用 `run.start`,只接受 Project、Package、Workflow 与 caller-owned
`planId/runId/stepRunIds`。publication、generation、revision、Task definition ref/digest 和完整 plan
全部由当前 durable authority 派生。
Owner、Admin、Operator 可按现有 role matrix 启动;Viewer 只有 inspect 权限。两种操作都要求稳定强
User 与当前 credential。命令输出不含数据库路径、credential、Package digest、plan digest、Task spec
或业务参数。
### 2. 授权与 admission 必须原子提交
`workflow.start` 在现有 SQLite `BEGIN IMMEDIATE` 内重新验证:
1. credential version、pepper binding、状态和有效期;
2. active Project 与 exact Project/RoleBinding version fence
3. allowed `workflow.start` security audit identity
4. current active install/lifecycle/quarantine/publication/materialized revision/Workflow/Task evidence
5. immutable Workflow Run、全部 StepRun、Event、mutation 与 admission receipt。
任一项失败回滚全部事实。底层通用 admission repository 保留原单参数接口,只增加可选的事务内 guard;
application scheduler 与既有 repository caller 不取得管理 authority。
### 3. 重放绑定 caller-owned identity
首次 start 使用 command 中的 UUID v4 `planId``runId` 与每个 Step 的 `stepRunId`。结果未知时必须原样
重放同一 command filerepository 先读取 durable plan,逐项比较 Project/Package/Workflow/Run/Step
identity,再返回 `existing`,不能读取 current head 后重新生成另一 plan,也不能产生第二个 Run。
### 4. 不增加低配常驻成本
能力位于既有 `runtime-core``local-sqlite``local-admin``local-owner-cli` 显式 subpath。workspace
保持 19,不增加 migration、表、第三方 dependency、连接、daemon、listener、timer 或 watcher。
`ql3-workflow` 只在 operator 调用时短生命周期加载;实际执行继续由 application 已有唯一 scheduler
cadence 接管。
## 替代方案
- **让用户提交完整 execution plan**:拒绝。会把 publication/generation/Task digest authority 交给调用者。
- **CLI 先授权、随后直接调用普通 admission**:拒绝。Role/credential revoke 可穿过事务边界。
- **为 Workflow API 新建 daemon 或 workspace package**:拒绝。本机已有安全 console、Policy、SQLite 和
scheduler authority,新增常驻面只会扩大路由器资源与供应链成本。
- **CLI admission 后同步等待 Workflow 完成**:拒绝。长连接会把 CLI 生命周期混入 durable scheduler
也会在终端断开时产生错误取消语义。
## 验证
- Owner CLI 93/93
- Runtime Core 431/431,其中新增授权契约直接证明 exact-shape、allowed audit/fence 绑定与
subpath-only
- Local SQLite 192/192
- Local Admin 83/83
- 真实 edge SQLite 产品测试证明 inspect、created→existing 三次重放、1 Run、2 StepRun、1 start audit
- Viewer start 被 `permission_missing` 拒绝且保持 0 Run
- transaction guard 的新建、重放与拒绝回滚门通过;
- 精确依赖边界 45/45、全仓 dependency/package-boundary/local-image audit 均为
`findings=[]`workspace 仍为 19
- 完整 19-package 门退出 0;后端总回归为 1,094 pass/2 条件 skip/0 fail
- 十档 Edge/Standalone、Adopted、Application 与 AI artifact 全部 `compatible=true`:最小
Edge 为 3,506,692 bytes/324 files/10,780,672 bytes RSS,最大组合
Standalone Application AI 为 5,874,007 bytes/474 files/20,496,384 bytes RSS,均未放宽预算;
- PostgreSQL 18.4 arm64 physical HA 回归 `gates.passed=true`,覆盖 `remote_apply`、timeline
1→2、旧主 fencing、`pg_rewind` 只读重入和两个 fresh control replicas;本轮隔离的
`ql3-ha-*` container/volume/network 均零残留。
## 影响
Plugin Package Workflow 第一次具有部署用户可调用的本机产品入口。它只负责安全 admission,不替代
application、scheduler、Worker 或 Executor。远程 Cluster transport、UI/MCP 入口和固定物理设备断电/
ENOSPC 证据仍是独立后续门。