Files
qinglong/docs/adr/ADR-0375-shared-current-task-point-read-api.md
T

7.4 KiB
Raw Blame History

ADR-0375:共享的 current Task point-read API

  • 状态:Accepted
  • 日期:2026-08-11
  • 关联:QL-RFC-0001 D-06、D-08、D-13、D-17、D-28、D-75、D-85、D-87、D-157、D-239、D-253、D-257、D-262、D-279、D-280、D-285、D-286、D-287ADR-0256、ADR-0272、ADR-0350、ADR-0373、ADR-0374

背景

D-286 已让 Local、Cluster 和 MCP 能以稳定 keyset 发现 Project 的 current Task,但客户端若持有一个 Task ID,仍必须扫描列表才能确认它当前是否存在、是否启用以及具体 revision。后续 Task start 又必须绑定明确的 current revision 与 immutable content digest,否则 discovery 与 mutation 之间的定义变化会被静默接受。

直接返回完整 TaskDefinition 不是可接受的捷径:command、public environment、SecretRef、working directory、placement、description 与 labels 都可能暴露执行细节或 secret-adjacent 内容,并会把内部 spec 格式冻结成公共 API。point read 应先提供精确 current-head identity/fence;完整 spec preview 与 Task start 继续分别评审。

决策

  1. Runtime Core 在 task-definition/projection 拥有唯一 executeBoundedTaskReadProjection,输入为可信 Project ID 与一个 Task ID,只调用 TaskDefinitionSource.findCurrentTaskDefinition(projectId, taskId)
  2. 找到时只返回 found=truetaskId、current revisionnamekindspecSchemaenabledcontentDigestcreatedAtMsupdatedAtMscontentDigest 是后续 mutation 的 optimistic fence,不是执行授权。
  3. 不得返回 Project、description、spec config/command/environment/placement、labels、mutationId、SecretRef 或数据库 row。合法的不存在、Task identity 不匹配与跨 Project 记录必须统一为 found=false;畸形 record、digest/time 不一致和 repository failure 必须失败关闭为 unavailable。
  4. Local 与 Cluster 增加同构 GET /api/v3/projects/{projectId}/tasks/{taskId},固定 operation task.get、permission task.read。不允许 query 或 bodyLocal 继续在 authentication 前拒绝非规范 path/queryCluster 复用 route registry 的 exact path/query 编译。
  5. HTTP 找不到统一返回 404 task_not_found;存储或投影不可用统一返回 503 task_query_unavailable。响应不把 Project ID 重复写入 bodyProject authority 来自经过 admission 的 path binding。
  6. 本机 MCP 增加 qinglong.task.get@1.0.0,输入只有 taskId,输出直接复用共享 projection。Tool 固定 effect=readrisk=lowtask.read 与 5 秒上限,复用 authentication→Tool Policy→durable audit→credential confirm→同一 SQLite authority。
  7. Local Application product surface 和 Local MCP database 只把既有 source 的 findCurrentTaskDefinition 加入窄 read authorityCluster 复用 ClusterControlAssemblyInput.taskDefinitions 与现有 PostgreSQL Pool。
  8. 不新增 workspace package、第三方依赖、migration、表、索引、数据库连接、listener、sidecar、timer、watcher、cache 或写 authority。历史 revision read、完整 spec preview、Task start、input payload 与 mutation 继续需要独立 ADR。
  9. D-285/D-286 的 18-package、14 Profile artifact、真实 Local image、完整 backend/packages、dependency/package boundary 与 PostgreSQL HA 门不得放宽。

不采用方案

  • 让客户端扫描 Task list:深链接成本随 Task 数量增长,也不能获得明确的 current digest fence。
  • 返回完整 TaskDefinition:会泄露命令、环境、SecretRef 和部署细节,并提前冻结扩展 spec 协议。
  • 只返回 revision、不返回 digest:同一 revision 的损坏或错误 adapter 映射无法被客户端/后续 start 计划绑定。
  • task.get 合入 task.list query:混合 collection 与 resource 语义,增加游标和 not-found 歧义。
  • 只实现 HTTP 或只实现 MCP:会让人类客户端与 AI 客户端拥有不同的 current-head/fence 语义。
  • 新增 Task query package/service:纯投影没有独立部署、authority 或重依赖隔离价值。

完成门

  • Runtime Core 覆盖 found/absent、字段脱敏、disabled Task、跨 Project、畸形 record、digest/time drift 与 repository failureleaf import 不加载 Tool Registry/SemVer。
  • Local route、transport、admission、product authority 与真实 SQLite HTTP 覆盖 task.read、pre-auth query rejection、credential confirm、durable task.get audit、404 masking 和同一 storage authority。
  • Cluster route、registry 与 production composition 使用既有 TaskDefinitionSource/Pool,并覆盖 Policy、audit、404 masking、无 query/body 与响应上限。
  • MCP 覆盖精确 Tool schema、task.read admission、durable audit、credential confirm、真实 stdio/SQLite current Task read,并证明只调用共享投影。
  • Runtime Core、Local SQLite、Local API、Local Application、Local MCP、Cluster Control、双方言相关测试、完整 backend/18-package、14 Profile artifact、真实 Local image与 PostgreSQL HA 全绿。

验收证据

  • Runtime Core 486/486、Local SQLite 213/213、Local API 39/39、Local MCP 45/45、Local Application 45 pass/4 条件 skip、Cluster Control 204 pass/2 条件 skip;完整 18-package clean build/test 退出 0,完整 backend 1,163 pass/2 条件 skip、0 fail。Local HTTP 使用真实 SQLite authority 持久化 task.get auditMCP stdio 使用同一 SQLite current Task sourceCluster production composition 使用既有 PostgreSQL source/Pool。
  • workspace 保持 18 package/1,035 source,其中 1,017 nested/18 个受审根入口,singleSourcePackages=[]shallowSourcePackages=[]。package boundary 正反向门 62/62dependency audit findings=[];没有新增 package、 第三方依赖、migration、表、索引、连接、listener、timer、watcher、cache 或写 authority。
  • 14 个 Profile artifact 全部 compatible=true。默认 Edge/Standalone 仍为 2,385,220/2,385,298 bytes、288 files、 50 loaded modulesApplication、Adopted、AI 与 Application AI 档相对 D-286 精确不变。选择 Local API 的 Edge/Standalone 为 3,538,918/3,539,062 bytes、416 files、80 modules,相对 D-286 增加 5,412/5,412 bytes、 2 files、2 modules;选择 MCP 的 Edge/Standalone 为 7,161,579/7,161,687 bytes、776 files、213 modules 相对 D-286 增加 7,364/7,364 bytes、2 files、2 modules。未选择 API/MCP 的低配部署不承担该增量。
  • 真实 arm64 Local Application image 为 10 package/380 files/3,284,889 bytes,默认不含 Local API、MCP、AI 或 Cluster packageEdge 128 MiB/64 PIDs 与 Standalone 256 MiB/256 PIDs 均以 UID/GID 65532:65532、只读根、 network=none 完成 active→graceful stopSQLite integrity ok。临时 image 已删除。
  • PostgreSQL 18.4 arm64 HA 通过 112 gatestimeline 1→2,报告 SHA-256 d2f02a7cd67a712e5fe3e2152c8c3afdefe9680d51c6c0ab108c6882ac7c841c;旧主 fence、promotion、pg_rewind/ rejoin 与 fresh replica 收敛后 Docker 容器、网络、卷零残留。
  • GitNexus 刷新为 47,031 nodes/106,513 edges/1,853 clusters/295 flows。四个新增生产符号均为 LOWLocal route 1 direct/1 processCluster route 1 direct/2 totalMCP Tool 1 direct,共享投影 0 indexed upstream;跨 package export 未形成的调用边由三端定向测试、完整 package、真实 SQLite/MCP 与 artifact 门补强。无 HIGH/CRITICAL。