Files
qinglong/docs/adr/ADR-0113-bounded-worker-secret-and-log-materialization.md
T

5.2 KiB
Raw Blame History

ADR-0113:有界 Worker Secret 与 Log Materialization

  • 状态:Accepted
  • 日期:2026-07-23
  • 关联 RFCQL-RFC-0001 D-24、D-72、D-85、D-110、D-111、D-112
  • 关联 ADRADR-0024、ADR-0025、ADR-0073、ADR-0092、ADR-0111、ADR-0112

背景

Worker Processor 已能在单一 inbox 上执行 ACK/spawn barrier,但此前只接受任意 materializer port。具体组合若把完整 Offer 交给 Secret/Artifact provider,会连同 lease token capability 扩散;若先分配日志再发现 Secret 不可用,会在重试中制造无主 Artifact。 另一个实际缺口是 materializer 返回的 logArtifactId 只用于 running ACK,没有交给 Executor,导致本地输出与控制面记录无法绑定同一 identity。

决策

1. 只向 provider 发送最小身份投影

BoundedWorkerRemoteExecutionContextMaterializer 必须先重新规范化完整 offer,但向 Secret provider 只发送 Project、Task、Task revision、Run、Attempt、capability-free 的 offer ID、 execution digest 与去重后的 secret refs;向 Artifact allocator 只发送 Project、Run、Attempt 与 offer ID。两类请求都不得携带 lease token/digest、callback token/digest、Worker credential、command 或完整环境。

Secret provider 返回以 secretRef 显式配对的 exact entries,不使用位置隐式关联:

  • 最多 64 个去重 reference
  • 每值最多 16 KiB,禁止 NUL
  • public 与解析后的 Secret 环境总量最多 64 KiB
  • 数量、引用集合、唯一性、字段或预算不匹配全部 fail closed
  • 可选 dispose 在任何后续失败与正常 handoff 后最多调用一次。

2. Secret 成功后才能分配 Artifact

只有所有环境值闭合后才调用 Artifact allocator。allocator 返回 exact logArtifactId + takeOutput + release,ID 最多 36 字节并符合 Run dispatch ID 约束。 takeOutput 只能在 spawn barrier 后调用一次;release 只释放未交接的 preparation 资源,不得关闭或删除已交给 Executor 的日志;无效/不可用 Artifact 必须同时释放 Secret resolution。

materialized context 的 dispose 幂等并同时尝试 Secret dispose 与 Artifact release,一个 清理失败不得跳过另一个。Processor 已在所有 launch 结果的 finally 中调用它。

3. Executor 与 running ACK 使用同一个日志身份

WorkerRemoteExecutionLaunch 必须同时携带 logArtifactId + output。Processor 在写入 durable launching barrier 后才取得 output capability,并复验 sink 与 materialized ID 一致后交给 ExecutorExecutor 返回 handle 后,该 ID 与 handle 一起持久化,并随 acknowledgeRunning 提交控制面。禁止 Executor 自行生成另一个未回报的日志身份。

调用 Executor.start 即转移 output ownership。tagged rejected 证明未 spawnProcessor 执行一次防御性幂等 close;异常或非法返回表示 spawn outcome unknown,不得由 Processor 误关可能正在写入的 output。

4. 保持 provider 与 Profile 默认关闭

本 ADR 只定义并实现 worker-runtime 内的组合原语;Secret 网络协议随后由 ADR-0114 在 不把 lease capability 暴露给通用 provider 的前提下闭合。本 ADR 不实现 Artifact 上传或本地文件 provider,不新增 package、数据库、timer、watcher或第三方依赖。生产 Profile 只有在受审 provider、具体 Executor、completion 与 lease-loss lifecycle 都闭合后 才能启用。

被否决的替代方案

  1. 把完整 Offer 交给 provider:不必要地扩散 lease capability、command 与 Worker target。
  2. 按数组位置返回 Secret:provider 顺序漂移会静默把 Secret 注入错误变量。
  3. 先分配 Artifact 再解析 Secret:Secret 不可用会制造无意义写入和 orphan。
  4. Executor 自己生成日志 IDrunning ACK、Artifact 路由与实际输出无法闭合。
  5. 把 Secret 明文写入 inbox:把瞬时 capability 变成跨重启持久泄露面。
  6. 另拆 materializer package:没有独立部署或供应链责任,只增加 package 碎片。

影响与剩余门禁

已完成:去重 Secret 请求、exact response、每值与总量预算、Secret-before-Artifact、最小 identity projection、失败清理、幂等 dispose,以及 log ID 从 materializer 到 Executor、 journal 和 running ACK 的单一链路。

ADR-0114 已完成 Secret provider 的认证传输和完整 Session/Lease/revision 围栏;仍未完成: 具体 KMS/Vault/本地加密存储策略、Artifact upload 与 retention、具体进程 Executor、completion transport、lease-loss/cancellation/recovery 组合和物理 Edge 故障证据。默认 Worker 执行保持关闭。

验收证据

  1. 相同 Secret ref 只解析一次,两个环境变量得到同一受限值。
  2. Secret 不可用或超过 64 KiB 时 Artifact 调用数为零。
  3. duplicate/unknown/malformed provider response 被拒绝,并执行所有可用 cleanup。
  4. provider 请求的序列化内容不包含 lease token。
  5. Executor launch 观察到与 running ACK 相同的 logArtifactId
  6. output 只在 durable launching barrier 后交接;unknown spawn 不被 Processor 关闭。
  7. package 数、依赖树与默认入口闭包不增加。