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,94 @@
# ADR-0287Content-free 的 Package Prompt 目录读取
- 状态:Accepted
- 日期:2026-08-08
- 关联:D-85、D-87、D-157、D-213、D-244、D-257、ADR-0150、ADR-0222、ADR-0260、ADR-0261、ADR-0263、ADR-0267、ADR-0276、ADR-0270、ADR-0286
## 上下文
QingLong 3.0 已经能通过 Local `ql3-prompt prompt.execute` 和 Cluster
`POST /api/v3/projects/{projectId}/packages/{packageName}/prompts/{promptId}/executions`
执行 generation-bound Package Prompt,但调用者必须预先知道精确 `promptId`。同一 Package 的 Workflow 已有受认证
目录读取,Prompt 却只能盲调用,导致 AI 产品链路缺少“发现可用能力”这一步。
直接返回 automation publication 会同时暴露 Prompt template、publication digest、installation/generation/lock、其他
Workflow 定义和内部持久化事实。把目录读取绑定到 Provider/Gateway/Secret 或本机 AI feature activation,又会让纯只读
操作承担网络、凭据、并发槽和可选 schema 的成本,不适合低配路由设备。Cluster 默认非 AI 镜像也不能因为目录读取而
获得 `@qinglong/ai` 生产依赖或新增常驻路由。
## 决策
1. 共享结果 schema 固定为 `qinglong/plugin-package-prompt-catalog@v1`。结果只包含 `projectId``packageName`
`found``publicationState` 和 Prompt 摘要数组;每个 Prompt 只允许 `id/name/description` 与参数
`name/description/required`
2. Prompt `template`、参数值、publication/lock/generation/installation digest、Provider、Model、SecretRef、Artifact、
Run、StepRun、价格、quota、credential、authentication ID 和审计内部字段一律不得进入目录结果。
3. Local 在既有 `ql3-prompt` command-file schema v1 增加 `prompt.inspect`。固定要求强 User 和 `model.invoke`;只读
options 只接受 deployment root、SQLite、Owner pepper、credential 与可选 busy timeout,不要求 Secret keyring、
Provider authority、AI feature activation、Gateway 或网络。allowed/failure audit 的 operation 均为
`prompt.inspect`
4. Cluster AI Profile 增加
`GET /api/v3/projects/{projectId}/packages/{packageName}/prompts`operation 为 `prompt.read`、permission 为
`model.invoke`。认证、Project Policy fence 和 allowed audit 继续由共享 admission pipeline 完成;默认 AI-free
cluster-control 不注册该路由。
5. PostgreSQL catalog service 只通过当前 automation publication head 与 immutable publication 的精确 join 读取
一个目标,参数为 Project/Package,查询固定 `LIMIT 2`;零行返回 `found=false`,重复行、损坏 JSON、target 漂移或
存储失败统一 unavailable。HTTP 拒绝 GET body、无效 Package 与 capability identity drift。
6. Local 与 Cluster 共用 `@qinglong/ai/plugin-package-prompt-catalog` 的纯投影 contract;该 subpath 只依赖
runtime-core,不取得数据库 mutation、Provider、Secret、Artifact 或 model invocation authority。
7. 本增量不新增 workspace package、生产 dependency、migration、表、索引、Pool、端口、listener、timer、watcher、
cache、后台扫描或状态机。路由设备按一次短命令付费;Cluster 复用显式 AI 进程已有数据库 Pool。
8. Prompt 目录不是通用 Package inventory,也不是 template/source 下载 API。跨 Package 发现、全文检索、标签、版本
筛选和模板读取必须分别定义索引、分页、权限与敏感内容边界,不能静默扩宽 v1。
## 被拒绝的方案
- **让调用者继续保存 `promptId`**:执行可用但能力不可发现,不构成完整产品入口。
- **返回完整 Prompt resource 或 automation publication**:会暴露 template 与无关的安装、Workflow 和 digest 事实。
- **用 `prompt.execute` 做探测**:会消耗 quota、加载 Provider/Secret,并可能产生外部费用和 durable Run。
- **Local inspect 强制 AI feature active**:目录事实属于已发布 Package,不需要 model invocation 可选 schema;这会让
低配设备为只读发现承担无效前置条件。
- **把 Prompt 目录加入默认 cluster-control**:会破坏默认镜像 AI-free 的依赖与路由闭包。
- **新增 catalog package、projection 表或缓存**:既有 immutable publication 已是权威事实,额外持久化会制造双写和
常驻资源成本。
- **使用通用 `run.read``package.manage`**:前者没有表达模型调用能力,后者会把普通 Prompt 使用者错误提升为
Package 管理者;v1 固定使用现有 `model.invoke`
## 当前证据
- `@qinglong/ai` 204 tests201 pass、3 条外部 PostgreSQL 条件 skip;目录纯投影与 PostgreSQL current-head
`LIMIT 2` 正反向测试通过。
- `@qinglong/cluster-control` 在可绑定本机端口的环境中 179 tests:177 pass、2 条外部服务条件 skip;新增 route、
identity drift、GET body、共享认证/Policy/audit 和 AI-only composition 通过。
- `@qinglong/local-owner-cli` 在可绑定本机端口的环境中 102/102;`prompt.inspect` 证明不激活 AI、不加载 Provider、
不要求 Secret/Provider path,并且结果不包含 template 正文。
- AI、Cluster Control、Local Owner CLI TypeScript package closure 均通过;`git diff --check` 与 HA 脚本语法检查通过。
- 完整 19-package clean build/test 全绿;backend 1,110 tests 为 1,108 pass/2 条环境条件 skip,零失败。Edge import、
Cluster dependency、package boundary、Cluster deployment、CloudNativePG 与 local image 六项审计均 compatible
package boundary 仍为 19 个受审包、零单文件包,只有两个纯公开产品入口允许浅层布局。
- 十档 Local artifact/RSS 门全部 compatible。最小 Edge 为 3,614,826 bytes,最大 Standalone Application AI 为
6,053,998 bytes,距 6 MiB 上限仍有 237,458 bytes;所有实测 RSS 增量均低于对应预算。
- 刷新后的 GitNexus 为 42,868 nodes/97,573 edges/1,675 clusters/261 flows13 个关键修改符号均为 LOW,
最大 3 个上游符号,生产执行流无扩散。`detect_changes` all/compare `develop` 分别为 12 files/31 symbols 与
14/34,均为 low/0 affected processQL3 孵化树大部分仍 untracked,因此该统计不替代逐符号 impact、完整测试、
制品与真实 HA 证据。
- PostgreSQL 18.4 arm64 physical-streaming HA 已实跑通过:Prompt catalog 在 primary、standby WAL replay 与
promoted primary 完全一致,`found=true/state=active`、Prompt ID 精确,template/private input 持续缺席。
timeline 1→2、旧主 fencing、`pg_rewind --write-recovery-conf` 只读同步 rejoin、两套 fresh control replica 与
`gates.passed=true` 全绿;最终 `ql3-ha-*` container/network/volume 零残留。
## 接受条件
1. 完整 19-package workspace test、backend、package/deployment/image boundary audit 与十档 artifact/RSS 门全绿。
2. PostgreSQL 18.4 arm64 physical-streaming HA 必须证明 primary、standby WAL replay 与 promoted primary 返回完全相同
的 catalog`found=true/state=active`、Prompt ID 精确且 template/private input 均缺席;旧主 fencing、
`pg_rewind`、fresh replicas 与零残留仍须全绿。
3. 刷新 GitNexus 后关键修改保持受审影响范围,并运行 `detect_changes` all/compare `develop`
## 后续边界
- 若 UI 需要跨 Package 搜索,先交付受认证、按 Package name keyset 的可见 Package 目录,禁止在内存中扫描全部
publication。
- Prompt template 预览、版本 diff、参数默认值和示例输入可能包含敏感内容,必须使用独立 permission/schema,不能
扩宽 content-free catalog。
- 默认非 AI Profile 继续保持零 Prompt routeLocal inspect 继续保持 request-driven、零 daemon/Provider/Secret。