6.9 KiB
ADR-0205:物理 Edge Init-managed Service 首次 Active 候选证据
- 状态:Accepted
- 日期:2026-07-29
- 关联 RFC:QL-RFC-0001 D-86、D-87、D-175、D-194、D-195
- 关联 ADR:ADR-0088、ADR-0193、ADR-0194、ADR-0204
背景
ADR-0204 已证明不同 Linux boot 中,最终 AI-excluded native application closure
可以从 recorder spawn() 到唯一正式 active,但 recorder 本身已经加载 Node,
也没有经过 systemd/OpenRC。它因此仍把
power_on_cold_node_and_service_manager_start_to_first_ready 保留为 broad Gate。
完整 firmware 上电时间不能从 Linux 用户态可靠取得。/proc/uptime 从 Linux
内核时钟开始,不包含 bootloader/firmware;安全实现必须拆开这一边界,而不是把
kernel uptime 改名为 power-on latency。
决策
1. 新增非 package、无自动整机 authority 的三阶段记录器
根命令 evidence:physical-edge-service-start 提供:
inspect:复用 ADR-0204 的 exact 12-package artifact 与 Node inventory;prepare:创建 fresh Edge deployment、证据 wrapper、FIFO 和 digest-bound session;resume:只读核验新 boot、init 状态、进程身份和正式 active 后发布 report。
记录器不新增 workspace package、生产依赖、daemon、timer、watcher、端口或
Cluster import。它绝不执行 install、systemctl enable/start、rc-update、
rc-service start、reboot、poweroff、stop、disable 或文件清理。
2. Operator 必须显式安装并启用 exact descriptor
prepare 使用正式 prepareLocalDeployment:
- Profile 固定为 Edge;
- service kind 由 manifest 固定为
systemd|openrc; - 仍使用 production renderer 的 User/Group、WorkingDirectory、resource limit、 SIGTERM、restart 和 hardening contract;
- systemd 的 probe 目录位于 deployment root 内,满足
ProtectSystem=strict + ReadWritePaths=<deploymentRoot>。
prepare 输出而不执行:
- descriptor source/destination 与 SHA-256;
/usr/bin/install的逐参数 invocation;systemctl enable <unit>或rc-update add <service> default的逐参数 invocation。
session 精确绑定这些参数、目标 mode、service name、status manager 与 enable
executable/hash、wrapper hash、artifact/Node、UID、prepare boot 和所有 scratch
path。systemd 两者都是 systemctl;OpenRC 分别是 rc-service 与 rc-update。
operator 审查后以 root 安装/enable,再在工具外正常重启。resume 要求目标
descriptor 为 root-owned、single-link、exact mode/content。
3. POSIX wrapper 在 Node 之前建立时间锚点
证据 wrapper 是私有 0700 POSIX shell 文件。它在执行 Node 之前:
- 复验 exact
node --config <path>参数和已准备 FIFO; - 从
/proc/sys/kernel/random/boot_id与/proc/uptime读取 boot/start; - 以 noclobber 创建
0600start/event/stderr 文件; - 才启动 exact Node binary、正式
@qinglong/local-application/dist/cli.js和 production config。
wrapper 逐行复制 application stdout。遇到同时包含正式 component/event/Profile/
AI status 的候选行时,立即读取同一 /proc/uptime,以 event ordinal 发布一次性
active record。resume 使用 Node exact JSON parser 重新验证整个 event log、唯一
active 和 ordinal;shell substring 不能自行形成通过结论。第二个 active、已有
record、partial JSON、非零 stderr 或 boot/monotonic 逆序均失败关闭。
wrapper 不是旁路 daemon:它就是 evidence service 的 main process,转发终止信号,
并等待唯一 Node child。systemd 必须把 wrapper PID 报为 MainPID;OpenRC 必须由
rc-service status 和 default runlevel 同时证明 active/enabled。
4. Resume 必须复验实时 service 与进程树
resume 在读取报告文件前要求:
- 与 prepare 不同且与 wrapper record 相同的 boot ID;
- 当前 boot age、架构、文件系统、UID、Node 和 manifest 一致;
virtualizationIndicators为空,容器/VM 直接拒绝;- artifact metadata、wrapper、manager 和 installed descriptor 未漂移;
- systemd
loaded/active/running/enabled、exact FragmentPath/MainPID,或 OpenRC active + default runlevel; - wrapper/node PID 仍存活,Node PPid 为 wrapper,UID、
/proc/exe与完整 cmdline 精确匹配。
最后重算完整 artifact content。报告记录:
serviceStartBootAgeMs;activeBootAgeMs/bootToActiveMs;serviceStartToActiveMs;- active event ordinal 和 live process start ticks。
所有三项时延都必须落在 manifest 的显式预算内。report 与统一 importer 都重新
计算 qualification,不能信任报告自带 passed:true。
5. 结论继续保持候选与窄作用域
通过的报告增加:
kernel_boot_to_init_managed_native_application_active
并把 broad Gate 细化为仍未完成的:
firmware_and_bootloader_power_on_to_linux_kernel_clock;direct_release_unit_without_evidence_wrapper。
报告永久 supported:false,并明确不证明 exclusive cold page cache/dynamic
linker provenance、active 前 RSS/I/O、service stop/disable、突然断电、Compose、
Standalone/Cluster 或 release attestation。证据 wrapper 将测得时延作为安全上界,
但它不是最终直连 Node 的 release unit;必须保留 equivalence Gate。
验收证据
- Linux recorder manifest/CLI/wrapper/session/record/init/report/POSIX syntax/OpenRC executable split/virtualization/FIFO-child 契约 13/13;
- importer same-device/current-boot/qualification 再裁决与 remaining Gate 细化 3/3;
- importer 3/3,Linux 专项合计 16/16;macOS 为 12 pass/1 条件 skip;
- exact Node 24.18.0 bookworm-slim digest 在只读 rootfs、无网络、cap-drop、 no-new-privileges、128 MiB/64 PID 下完成真实 FIFO、active ordinal 和 SIGTERM wrapper smoke;该容器只证明脚本兼容,不是物理/init 报告;
- wrapper 静态门不含 reboot/poweroff/systemctl/rc-service/rc-update/sudo;
- 实现不新增 workspace package、生产依赖或常驻采集资源。
macOS 开发机不能运行 Linux PID 1、/proc 和真实 enable/reboot,所以没有产生
物理报告。Accepted 只表示协议、采集器和失败关闭门已实现;固定 systemd/OpenRC
设备的 operator install/reboot/resume 仍是发布候选 Gate。
被拒绝的替代方案
- 使用
Date.now()作为 power-on 时间:墙钟可跳变,也没有 firmware 起点。 - 由 Node recorder 在 reboot 后启动 Node:Node 已被 recorder 自己预热。
- 自动安装/enable/reboot:扩大整机破坏 authority,且不能保留人工审查边界。
- 只读取 journal 文本时间:日志持久化、clock domain 和旧 boot 过滤不稳定。
- 把 wrapper descriptor 称为最终 release unit:证据 shim 改变了进程树。
- 新增 boot-agent package/daemon:增加低配 Edge 的交付和常驻成本。