mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
94 lines
5.2 KiB
Markdown
94 lines
5.2 KiB
Markdown
# 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 都闭合后
|
||
才能启用。
|
||
|
||
## 被否决的替代方案
|
||
|
||
1. **把完整 Offer 交给 provider**:不必要地扩散 lease capability、command 与 Worker
|
||
target。
|
||
2. **按数组位置返回 Secret**:provider 顺序漂移会静默把 Secret 注入错误变量。
|
||
3. **先分配 Artifact 再解析 Secret**:Secret 不可用会制造无意义写入和 orphan。
|
||
4. **Executor 自己生成日志 ID**:running 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 数、依赖树与默认入口闭包不增加。
|