5.2 KiB
ADR-0113:有界 Worker Secret 与 Log Materialization
- 状态:Accepted
- 日期:2026-07-23
- 关联 RFC:QL-RFC-0001 D-24、D-72、D-85、D-110、D-111、D-112
- 关联 ADR:ADR-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
一致后交给 Executor;Executor 返回 handle 后,该 ID 与 handle 一起持久化,并随
acknowledgeRunning 提交控制面。禁止 Executor 自行生成另一个未回报的日志身份。
调用 Executor.start 即转移 output ownership。tagged rejected 证明未 spawn,Processor
执行一次防御性幂等 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 都闭合后 才能启用。
被否决的替代方案
- 把完整 Offer 交给 provider:不必要地扩散 lease capability、command 与 Worker target。
- 按数组位置返回 Secret:provider 顺序漂移会静默把 Secret 注入错误变量。
- 先分配 Artifact 再解析 Secret:Secret 不可用会制造无意义写入和 orphan。
- Executor 自己生成日志 ID:running ACK、Artifact 路由与实际输出无法闭合。
- 把 Secret 明文写入 inbox:把瞬时 capability 变成跨重启持久泄露面。
- 另拆 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 执行保持关闭。
验收证据
- 相同 Secret ref 只解析一次,两个环境变量得到同一受限值。
- Secret 不可用或超过 64 KiB 时 Artifact 调用数为零。
- duplicate/unknown/malformed provider response 被拒绝,并执行所有可用 cleanup。
- provider 请求的序列化内容不包含 lease token。
- Executor launch 观察到与 running ACK 相同的
logArtifactId。 - output 只在 durable launching barrier 后交接;unknown spawn 不被 Processor 关闭。
- package 数、依赖树与默认入口闭包不增加。