7.3 KiB
ADR-0116:受审 Worker POSIX Executor 与 Upload-before-completion 闭环
- 状态:Accepted(ADR-0117 已补 HTTPS/数据库闭环,ADR-0121 已补生产执行面装配;retention 与完整 Worker 产品生命周期仍默认关闭)
- 日期:2026-07-23
- 关联 RFC:QL-RFC-0001 D-14、D-17、D-24、D-26、D-68、D-110、D-114、D-115
- 关联 ADR:ADR-0021、ADR-0069、ADR-0111、ADR-0115
背景
ADR-0115 交付了 Worker 本地日志 spool 和 output ownership,但仍缺真实进程启动器、可认证 完成回执和 upload-before-delete 顺序。若 Worker 复制一套 launcher,会让本机与远端执行的 安全修复漂移;若先提交 Run 终态再上传日志,控制面成功而网络失败会形成不可恢复的空 Artifact;若上传后立即删除本地文件或回执,inbox CAS 崩溃又会丢失重放证据。
另一个关键窗口是 launching 已落盘、进程已经 spawn、started 尚未写入时的 Worker 崩溃。
仅在 started 保存启动时间,回执无法与 durable spawn authority 做 exact 匹配,恢复只能永久
阻断或错误放宽认证。
决策
1. 复用 local-process 边界,不新增 package
@qinglong/worker-runtime/posix-executor 依赖现有 @qinglong/local-process。这是有意的单向
依赖:local-process 拥有受审 POSIX launcher、verified-fd 执行、completion receipt、durable
process identity 和 OS 路径规则;Worker 只拥有 Session/Lease/inbox 策略。它们具有真实的
platform/供应链边界,符合 D-85,不复制 launcher,也不新增只有一两个文件的 package。
Worker Executor 只接受带私有 file-plan capability 的 output。它在 spawn 前重读同一 inbox,
精确校验 offer、Run、Attempt、callback sequence/token digest、log Artifact 和启动时间;随后
关闭父写 descriptor,让受审 launcher 以 verified fd 和独立进程组启动用户命令。明确
no_spawn 才返回 rejected;spawn 后 identity 捕获失败为 unknown,禁止上层上报 start-failure。
当前 timeout 仍 fail closed:只要 execution revision 携带 timeoutMs,Executor 在 durable
spawn barrier 前拒绝。没有 durable timeout/cancellation evidence 时不得用进程内 timer 冒充。
2. 启动时间属于 durable pre-spawn authority
Processor 在交接 output 前把 executorStartedAtMs 与 log ID、callback sequence/digest 一起写入
launching。local-process 接受可选的上层 durable start timestamp,但必须验证它是安全整数且
不晚于本地 launch observation;launcher journal、receipt、Executor result 和最终 inbox 必须
使用同一个值。
因此崩溃发生在 spawn 后、started CAS 前时,可信 completion receipt 仍可从 launching 或
launch_outcome_unknown 恢复,不需要裸 PID、日志内容或宽松时间范围猜测。该状态机变化影响
processOnce、launch、acceptOffer 三条流程,必须由 exact transition 与 restart 测试门禁。
3. 回执认证只消费原始 capability,不传播它
Worker inbox 只持久化 32-byte callback capability 的 SHA-256。launcher receipt 可短暂保存 base64url 原文,协调器读取后必须 canonical decode 为恰好 32 bytes,以 constant-time 比较其 SHA-256,并精确匹配 Run、Attempt、callback sequence 和 durable start time;局部 buffer 随后 清零。上传、completion command、日志、诊断和 inbox 都不得携带 token 原文。
非法、未来时间或 authority 不匹配的回执不能触发上传或 completion。当前实现保留回执供后续 隔离/运维,不把损坏证据推导成用户任务失败。
4. 日志使用固定内存流,不整文件载入
现有 WorkerFileLogArtifactAllocator 同时实现只读 source。它按 opaque ID 定位单个文件,使用
O_NOFOLLOW 后复验 owner、单 link、权限、fd/path inode 和 root/shard identity;不扫描目录。
内容以最多 64 KiB chunk 单次消费,Edge 与 Node 共用协议而使用各自 4/64 MiB 总上限。
launcher 的 immutable truncation fact 以同样私有路径读取,并精确匹配 Run、Attempt、log ID、
Profile maximum 和 bounded timestamp。fact 缺失表达 unknown,不能伪装成未截断。
5. 顺序固定为 upload、completion、inbox ACK、receipt cleanup
@qinglong/worker-runtime/completion-coordinator 的可重放顺序固定为:
- 重读并规范化唯一 inbox authority,复验当前 Worker Session 与 Run Lease 未过期;
- 读取并认证 completion receipt;
- 打开 exact log Artifact,以流式 SHA-256 和 byte count 校验 uploader ACK;
- 只有 durable upload ACK 后才提交 lease-fenced completion,command 携带 Artifact ID、长度、 digest 和 truncation 状态;
- completion applied/exact replay 后 CAS 写
completion_acknowledged; - 只有该本地 terminal barrier 已耐久化,才 best-effort 删除 receipt。
本协调器绝不删除本地日志。Artifact 只能由后续 retention 在已证明 upload/control-plane ACK 且 超过策略保留期后清理。任一步网络/CAS 失败都保留可重放的 receipt、inbox 和 spool;上传端与 completion 端必须用 ID/digest/fence 提供精确幂等。
当前交付的是 Worker 侧真实文件/进程实现和严格 adapter port。ADR-0117 已补中央 Artifact store port、认证 HTTPS upload/completion endpoint 与 PostgreSQL 终态事务;ADR-0118 已补失租停止与 durable timeout/cancellation,ADR-0120 已补具体 S3-compatible store,ADR-0121 已补默认关闭的 production execution-plane composition。retention、Session/credential 产品流程与部署入口仍未装配, 因此完整 Worker Profile 继续默认不可达。
被否决的替代方案
- 为 Worker launcher 新建 package 或复制 shell:扩大碎片并产生两套安全修复源。
started后才保存 start time:spawn 后崩溃无法严格认证回执。- 对 base64url 字符串直接 hash:与 Processor 保存的原始 32-byte capability digest 不一致。
- completion 后再上传:终态成功但日志永久留在离线 Worker。
- upload 返回成功但不验证消费字节/digest:空读或部分读可冒充 durable Artifact。
- 上传后删除 spool:inbox/completion CAS 窗口丢失重试源。
- 整文件读入 Buffer:64 MiB Node 配额会放大路由器和并发 Worker 峰值内存。
- 为完成协调器新建 workspace package:单一 Worker consumer、同部署/依赖/权限闭包,不满足 D-85;使用现有 package subpath。
验收证据
- reviewed-fd Worker launch 产生 exact durable handle、日志和 completion receipt,callback token 不进入用户环境。
- spawn barrier 漂移零 spawn;spawn 后 identity 失败保持 unknown。
launching持久化 start time,launcher receipt 与最终 state exact;重启不二次 spawn。- completion coordinator 可从无 executor handle 的 durable
launching回执恢复。 - capability mismatch 在 upload 前拒绝并保留全部证据。
- 文件 source 固定 chunk 流式读取并认证 truncation fact,不枚举目录。
- 测试证明 upload 完成先于 completion,inbox terminal ACK 先于 receipt remove。
- upload 失败时不调用 completion、不删除 receipt,并关闭只读 descriptor。
- 未新增 workspace package、数据库、schema、timer 或 Worker 常驻连接。