mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
8.0 KiB
8.0 KiB
ADR-0289:按执行 Request ID 恢复并读取 Durable Package Prompt 输出
- 状态:Accepted
- 日期:2026-08-08
- 关联:D-85、D-87、D-156、D-157、D-213、D-244、D-257、ADR-0261、ADR-0263、ADR-0267、ADR-0274、ADR-0275、ADR-0276、ADR-0288
上下文
ADR-0288 允许调用方在 Prompt execute 响应丢失后,用自己持久化的 executionRequestId 精确恢复 Run 状态;但其
结果刻意排除了 Artifact identity 和正文。现有 Prompt output read 又要求调用方同时保存服务端返回的 runId、
artifactId 和 artifactDigest。当首次 durable execute 已成功提交而 HTTP/CLI 响应丢失时,这三个事实同样无法取得,
形成“知道执行成功、却不能取回已付费输出”的产品断点。
Cluster 已定义 caller-selected Artifact read route,但显式 AI production composition 尚未装配其 read authorizer 和
capability。Local application runtime 支持 durable output,Owner CLI 却只接受 live_only。仅新增一个 Artifact reference
发现接口会把重试、权限、retention、密钥解析和解密继续留给调用者,不能构成 QingLong 3.0 的恢复闭环。
决策
- 新增共享结果 schema
qinglong/plugin-package-prompt-execution-output-read-result@v1。输入固定为强认证 principal 与projectId/packageName/promptId/executionRequestId;成功结果返回既有 immutable Artifact reference 和受界GenerateResult,缺失统一返回not_found。 - SQLite/PostgreSQL 在现有 Prompt admission
request_id主键上精确定位,只连接 succeeded finalization、 ModelInvocation completion、Run、StepRun 和 immutable output Artifact,并要求step.output_ref=artifact_id。 查询固定LIMIT 2,只投影runId/artifactId/artifactDigest,不得读取artifact_json、ciphertext 或 key material。 - 定位成功后必须委托既有
PluginPackagePromptOutputReadService,保持 metadata→artifact.readPolicy→retention/ tombstone→key resolve→AES-GCM decrypt→key wipe 的顺序。新服务不得直接解密、绕过 tombstone 或请求 active key。 - Local
ql3-promptcommand-file schema v1 增加prompt.execution.output.read,权限和 allowed audit operation 均固定为artifact.read/prompt.execution.output.read。读取只装载 SQLite、output Artifact/retention repository 和显式promptOutputKeyringPath,不得加载 Provider authority、Provider Secret 或 Model Gateway。 - Local
prompt.execute接受显式durable_artifact + retentionPolicy。只有该模式要求并装载promptOutputKeyringPath与 completion coordinator;live_only继续禁止配置 output keyring,确保默认路由设备路径 零 Artifact/key/repository 增量。exact replay 返回相同 Artifact reference,不再次调用 Provider。 - Cluster 显式 AI Profile 新增
GET /api/v3/projects/{projectId}/packages/{packageName}/prompts/{promptId}/executions/{executionRequestId}/output, operation 为prompt.execution.output.read,permission 为artifact.read。生产组合仅在 Prompt output keyring opt-in 时同时装配现有 caller-selected Artifact route 和新 request-keyed route;默认 AI-free control 不注册二者。 - absent execution、live-only、未完成、失败、cross-target、policy deny、已 tombstone 或 GC 后 Artifact 均统一映射
not_found/HTTP 404,不暴露目标存在性。内部 shape、digest 或 identity 漂移映射 503,正文不得进入错误和审计。 - 本增量不新增 workspace package、生产 dependency、migration、表、索引、Pool、端口、listener、timer、watcher、
cache、队列、controller 或部署单元。三个新 AI 文件全部进入既有
prompt-output/domain,workspace 保持 19 包且 root-file hard cap 不变。
被拒绝的方案
- 把 Artifact reference 加入 ADR-0288 的 content-free inspection:会把
run.read与artifact.read内容边界混合, 也让所有状态轮询暴露存储与 retention 元数据。 - 只返回 reference,不返回正文:调用者仍需拼接第二次 API、保存 digest 并处理 tombstone,响应丢失恢复仍不是一个 原子产品动作。
- 用 request ID 计算 Artifact ID 后直接解密:无法证明 Package/Prompt、terminal completion、StepRun output_ref 和 Artifact digest 的完整绑定。
- 把正文复制到 admission/finalization receipt:扩大热表、备份、审计和 HA 泄漏面,破坏 immutable 加密 Artifact authority。
- 为 recovery 建 projection 表或新索引:现有 request 主键和 terminal join 已能精确定位,新增状态会产生双写和 Edge migration 成本。
- 新增 workspace package 或常驻 recovery worker:没有独立部署或故障域收益,并增加小设备 importer、内存和运维 表面积。
当前证据
- 共享 service 5/5、Cluster route 3/3;SQLite/PostgreSQL locator 都使用 request 主键和 terminal joins,定位 SQL 不读取 Artifact envelope/ciphertext,并覆盖 malicious widened reference/result、cross-target 与 missing。
- Local Owner CLI 定向新用例通过:显式 durable execute、exact replay、按原 execution request 读取正文、重复读取和 allowed audit 均成功;Provider generate 仅一次,读取前后 Provider load 计数不变。
- Cluster AI/production/route 定向 19/19;output opt-in 同时装配 caller-selected 和 request-keyed read,默认 AI-free composition 保持不装配。
- AI、Local Owner CLI、Cluster Control 与 Local Application 的完整 package suites 均零失败;完整 19-package clean build/test 与 backend 1,110(1,108 pass/2 skip)全绿。cluster dependency、package boundary、Edge import、Cluster deployment、CloudNativePG 与 local image 六项审计 compatible;十档 artifact/RSS 全绿,Edge 3,614,826 bytes, 最大 Standalone Application AI 6,102,447 bytes,默认非 AI closure 未新增 keyring/Artifact importer。
- package ledger 保持 19 包、
singleSourcePackages=[];762 个 source 中 49 个仅为受审公开/binary/composition 根入口, 713 个实现位于领域目录。新增 AI/Cluster 实现进入既有 capability,未以恢复能力为由新增微包或根层平铺。 - PostgreSQL 18.4 arm64 physical-streaming HA 已实跑通过。轮换后的新 key durable output 在 primary 通过原
execution request 精确解密,standby WAL replay 与 promoted runtime-role decrypt 结果一致,cross-target 保持
not_found,报告不含正文;pluginPackagePromptExecutionOutputRecoveryIsExactAndContentFree与pluginPackagePromptExecutionOutputRecoveryReplicatesAndSurvivesPromotion均为 true。timeline 1→2、旧主 fencing/rewind/read-only synchronous rejoin、两套 fresh control replica、gates.passed=true与最终ql3-ha-*container/network/volume 零残留全绿。
接受条件
- AI、Local Owner CLI、Cluster Control 定向与完整测试全绿;双方言 exact/cross-target/live-only/tombstone/replay/ malformed-result 测试覆盖。
- 完整 19-package clean build/test、backend、Edge/Cluster dependency、package boundary、deployment/local image 与十档 artifact/RSS 门无回归;默认 Edge/Standalone 非 AI 与 live-only 闭包不得新增 keyring/Artifact importer。
- PostgreSQL physical-streaming HA 必须证明 durable Artifact、request-keyed locator 和 decrypt read 在 primary、standby WAL replay、promotion 后 runtime role 上保持一致;cross-target/content-free audit、timeline、rewind、fresh replicas 和 零残留继续全绿。
- 刷新 GitNexus 后对所有已修改符号重新检查影响,并运行
detect_changesall/comparedevelop。
后续边界
- Prompt execution history、输出列表、全文搜索、流式增量输出与跨 Package 查询仍需独立索引、分页和可见性 RFC。
- UI 可在 execute 超时后先读 content-free execution 状态;只有用户显式查看 durable output 时调用本内容接口,避免 状态轮询反复解密和传输正文。