Files
qinglong/docs/adr/ADR-0287-content-free-package-prompt-catalog.md
T

95 lines
7.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-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。