☰
openrig 51-09 自托管 live-leg 夹具:跨主机 Sender Triple 与 Founder-Collision 的端到端验证
2026/10/10 8:36:45 网站建设 项目流程
  • 人工智能
  • AI Agent
  • 多智能体
  • Agent 编排
  • 代码智能体
  • CLI

【免费下载链接】openrig

Build your own network of agents from Claude Code, Codex and Pi: persistent teams with roles, shared context and owned work.

项目地址:https://gitcode.com/GitHub_Trending/op/openrig
点击查看免费下载

本技术指南围绕 openrig 仓库中的 51-09 live-leg fixture rigs 展开:它是一组以runtime: stub构造的极简拓扑夹具,专门用于在两台真实 daemon 上端到端证明「跨主机 stamped sender triple」(member@rig@host)与「founder-collision」(同名 rig 碰撞)两项关键能力。读完本文,你将掌握夹具的 rig/seat 命名规范、零 token 构造原理、以 openrig 用户身份完成 staging 与预检栅栏的方法,以及 LEG A(send / queue / broadcast 三个发送表面)与 LEG B(同名 rig 碰撞)的完整验证步骤,并能在真实双主机测试床中复跑这套 QA 流程。

夹具定位:51-09 两个 LIVE 证明的最小拓扑

夹具说明位于 culture.md,配套的完整执行手册位于同目录的 RUNBOOK.md。两处共同定义了两个 51-09 LIVE 证明腿(leg):

  • cross-host stamped triple:跨主机发送时,接收端渲染出的From:签名必须携带发起主机(origin host)的 self-host id,而非接收主机或本地同名座席;
  • founder-collision:当两台主机上存在同名 rig时,接收签名必须指明 origin,逐字回复(↩ Reply:)必须回到 origin 主机上的同名 seat,而不是落在本地同名座上。

夹具的设计原则是Minimalruntime: stubtopologies:按构造零 token(zero tokens by construction),这些夹具里没有任何东西真正执行工作,唯一目的是给每条 leg 一个真实 seat(带规范的<pod>-<member>@<rig>名称)跑在一台真实 daemon上。也就是说,stub 运行时把「agent 是否真的在干活」从验证范围里剔除,让验证聚焦于身份、路由与存储语义。

这一设计对应仓库中的 stub 运行时实现族,例如 stub-runtime-adapter.ts、stub-runner.ts 与 stub-runner-protocol.ts —— 它们共同提供不消耗 token、不启动真实 LLM 进程的座席执行通道。

三个 rig 与派生 seat 命名

运行手册要求三台真实 rig,均以夹具形式提交在topologies/下,全部在 2026-08-07 之后才存在(此前 leg 引用了不存在的 rig,在裸容器上于 provisioning 阶段即失败):

文件rig 名规范 seat(<pod>-<member>@<rig>)所在主机
rig-a.yamlrig-aorch-main@rig-aH_A
rig-b.yamlrig-bdev-main@rig-bH_B
shared.yamlsharedlead-main@shared两台主机

三个 rig 的 YAML 结构完全一致,仅名字与 pod/member 不同。以 rig-a.yaml 为例:

# 51-09 live-leg fixture — LEG A origin rig (runs on H_A) # Canonical seat = <pod>-<member>@<rigName> (deriveCanonicalSessionName) => orch-main@rig-a version: "0.2" name: rig-a culture_file: culture.md pods: - id: orch label: Orch members: - id: main agent_ref: "local:agents/orch" profile: default runtime: stub cwd: . edges: []

关键点:

  • seat 名是派生出来的,不是作者手写的。deriveCanonicalSessionName(pod, member, rig)是纯字符串拼接${pod}-${member}@${rig},实现在 session-name.ts:orch+main+rig-a→orch-main@rig-a。手册特别强调:类似orch@rig-a这种单 token 形式不可派生(不是<pod>-<member>@<rig>的形状),因此所有步骤必须使用真实派生名。
  • 三个 seat 引用的 agent 均为local:agents/<name>下的 stub 定义(orch、dev、lead),这些 agent.yaml 不含任何 skills/工具,进一步保证零 token。
  • culture_file: culture.md引用的正是本夹具的说明文档,作为 rig 的文化上下文文件。

会话名契约:为何「单 token 形式」不被接受

从源码看,会话名解析遵循 OPR.0.4.6.MH1 FR-8 契约(见 session-name.ts 内嵌的契约注释块):

  • member= 第一个@之前的非空串;rig= 其后的贪婪部分(可含更多@)。这个贪婪 rig 是承重设计:member@rig@x会解析成 rig 为rig@x,registry 查找必然落空,从而触发与契约前相同的unknown_destination_rig拒绝——host 永远不会内联进会话字符串(BR-1 规则)。
  • 字符集受validateSessionNameChars约束:a-z, A-Z, 0-9, -, _, ., @(tmux 会话名兼容集)。

这正是后面 LEG B 中「3-part 地址诚实化 + teaching 拒绝」的底层机制来源。

字节一致性与碰撞前提:shared.yaml 的单一来源纪律

founder-collision 的前提是碰撞对象本身字节一致:shared.yaml是同一个文件被复制到两台主机,而不是两台主机各自「照抄一份」。手册给出的纪律是:

  • BYTE-IDENTITY IS THE COLLISION PREMISE — assert it, never assume it(字节一致是碰撞前提——断言它,绝不假设它);
  • 在 leg 运行前,用 sha256sum 对两台主机的shared.yaml做哈希比对,不一致即中止:
    SA="$(docker exec H_A sha256sum "${STAGE}/shared.yaml" | cut -d" " -f1)" SB="$(docker exec H_B sha256sum "${STAGE}/shared.yaml" | cut -d" " -f1)" [ "$SA" = "$SB" ] || { echo "ABORT: shared.yaml differs across hosts ($SA vs $SB) — the collision premise is void"; exit 1; }
  • 该文件头部注释同样强调:copy this one file, never author a second(只复制这一个文件,绝不作者化创作第二份)。

Provisioning:以 openrig 用户身份交付,而非 root

测试床镜像在 Dockerfile 中声明USER openrig(第 61 行)与WORKDIR /home/openrig(第 62 行),因此默认docker exec以openrig身份运行——该用户无法穿越 root 的 home 目录。手册因此把夹具 staged 到 openrig 用户自己的 home下,且绝不 exec as root:daemon 本就以openrig运行,root-exec 探针测的是一个产品从不使用的用户,还会掩盖 testbed 本要暴露的权限缺陷。

STAGE=/home/openrig/topologies # openrig-readable by construction (its own home) # DELIVER AS THE PRODUCT'S OWN USER. docker cp 会保留 ROOT 所有权, # 得到一个 openrig 可读但不可写的 staging;而 rig up 的 pre-launch delivery # 会向 staging 写入 AGENTS.md,root 所有的 staging 会在任何 seat 存在前 # 以 EACCES 失败。用 tar-pipe 在默认 docker exec 中解包,天然以 openrig # 身份落盘——构造上即正确,全程无 chown、无 root exec。 SRC=packages/daemon/test/fixtures/self-host-live-legs/topologies for h in H_A H_B; do docker exec "$h" mkdir -p "${STAGE}" tar -C "${SRC}" -cf - . | docker exec -i "$h" tar -C "${STAGE}" -xf - done

为什么不能用docker cp?手册给出的原因非常具体:docker cp保留 root 所有权,产出「可读但不可写」的 staging;而rig up的 pre-launch delivery会向 staging 写入(AGENTS.md),root 所有的目录会在 instantiate 阶段以 EACCES 失败。tar-pipe 解包天然以 exec 用户(openrig)为属主,无需 chown——产品以谁的身份运行,交付就用谁的身份做。

预检栅栏:以执行用户真实读写,而非读 mode bit

staging 之后立即做双向预检栅栏(pre-flight fence),覆盖完整产品契约:

for h in H_A H_B; do AS="$(docker exec "$h" id -un)" docker exec "$h" test -r "${STAGE}/shared.yaml" || { echo "ABORT: ${STAGE}/shared.yaml not READABLE as ${AS} on ${h} — ..."; exit 1; } docker exec "$h" sh -c "touch '${STAGE}/.fence-write' && rm -f '${STAGE}/.fence-write'" || { echo "ABORT: ${STAGE} not WRITABLE as ${AS} on ${h} — ..."; exit 1; } done

栅栏的两个半区都通过实际执行来探测(真实 touch/rm),而不是读 mode bit——因为 mode bit 在属主、ACL 或只读挂载下可能说谎。只读 staging 能通过读栅栏,却会在稍后的写入点 EACCES 失败,所以两个半区都必须真实做一遍。

SELF-HOST IDS:adopt-by-read,绝不预测

self-host id 是 daemon 侧铸造、以永不重写单例存储的(51-09 incr 1:该单例从不被重新 key)。手册要求从 daemon 自己的表面捕获 id,绝不预测、绝不硬编码、绝不派生,并且绝不用rig whoami——它报告的是 seat 身份,主机没有 seat,因此回答不了「我是哪台主机」:

ID_A="$(docker exec H_A bash -lc 'curl -fsS http://127.0.0.1:7433/healthz' | python3 -c "import json,sys; print(json.load(sys.stdin).get('selfHostId',''))")" ID_B="$(docker exec H_B bash -lc 'curl -fsS http://127.0.0.1:7433/healthz' | python3 -c "import json,sys; print(json.load(sys.stdin).get('selfHostId',''))")"

捕获得到的selfHostId字段来自 daemon 的/healthz表面(实现见 server.ts,其中还附带selfHostIdSource说明 id 的来源状态;id 由 boot 期 reconciled 的getSelfHostId()提供,缺失时该字段整体缺省,保持旧响应体字节不变)。后续所有A/B记号均指捕获到的${ID_A}/${ID_B}——id 每次启动随机,所以每次都必须重新捕获。

配套的 L5 运行手册 L5-multi-host-and-51-09.md 还给出了双容器启动的完整环境:OPENRIG_HOST=0.0.0.0、OPENRIG_AUTH_BEARER_TOKEN(非 loopback 绑定必须携带,见 auth-bearer-token.ts 的守卫)、显式发布端口,以及「registry 行只携带 bearer指针(--bearer-env的环境变量名),绝不携带 token 值」的纪律。

双向注册:两条 leg 都要在链路的两个方向应答

L5.2 在 H_A 上注册 H_B 使 outbound 发送可解析;但两条 leg 的逐字回复都要从 H_B 跑回 H_A,这要求 H_A 也能从 H_B 解析。因此注册必须是双向的,采用同一个 adopt-by-read 过程、方向相反——只注册单方向的 leg 会在回复步骤死亡,而不是在发送步骤死亡:

# forward (H_B known to H_A) — as L5.2 does: docker exec H_A bash -lc "rig host add --id '${ID_B}' --transport http --url http://H_B:7433 --bearer-env OPENRIG_AUTH_BEARER_TOKEN && rig host ls --json" # REVERSE (H_A known to H_B) — required by the reply half of both legs: docker exec H_B bash -lc "rig host add --id '${ID_A}' --transport http --url http://H_A:7433 --bearer-env OPENRIG_AUTH_BEARER_TOKEN && rig host ls --json"

rig host add的当前语法要求--id与--transport必填,http transport 下--url必填,bearer 以环境变量名(pointer)而非值传递(见 host.ts 的参数定义与帮助文案)。注册的 id 必须是捕获的${ID_B}/${ID_A}——adopt-by-read,绝不用作者化的名字。

LEG A — 跨主机 Stamped Triple:两个表面、两种动词

LEG A 之所以拆成三个子腿,是基于 delivery-lock 自身措辞的落地:锁定的证明契约第 3 项原文为:

"ALWAYS: send, broadcast, and queue sender surfaces all render the sender triple member@rig@host unconditionally — local sends included — with the host token in one fixed deterministic position."

它点名了三个发送表面,因此该属性不是「某处有一个身份」,而是同一个 triple 在每个表面独立出现。早期的单腿形式只驱动了rig send(transport),随后去断言一条转发 qitem 上存储的source_session(queue)——但rig send不创建任何 queue 行,那种断言永远只能读到零行。手册给出的纪律是:动作必须与断言匹配——绝不可从渲染出的终端信封推断出 queue 记录。每个表面都必须由真正写它的那个动词来证明。

Fixture:origin 为 H_A(${ID_A})、destination 为 H_B(${ID_B}),seat 为 H_A 上的orch-main@rig-a与 H_B 上的dev-main@rig-b;两个方向均已注册(回复半区需要反向行)。

LEG A1 — Transport 表面(rig send):渲染信封 + 逐字回复

  1. self-id 来自上面的 adopt-by-read 捕获(${ID_A}/${ID_B}),不是rig whoami;
  2. 在 H_A 的orch-main@rig-a上执行:rig send dev-main@rig-b "ping" --host B;
  3. 在 H_B 捕获dev-main@rig-b的 pane,EXPECTFrom: orch-main@rig-a@${ID_A}—— 是origin主机,绝不是@${ID_B};
  4. 把↩ Reply: rig send orch-main@rig-a@${ID_A} "..."提示逐字复制并在 H_B 上执行,EXPECT它路由回 H_A 并投递给orch-main@rig-a,而不是本地同名座。

A1 PASS:渲染签名点名${ID_A};逐字回复落在 H_A 上。A1 对 queue 断言零内容——rig send不产生 qitem,声称有就是「从渲染推断存储」。Fail-open 控制(C1):停止 H_A 的 daemon 后重复步骤 2,From:降级为 2-part 形式且不崩溃。

LEG A2 — Queue 表面(rig queue create --host):持久化的存储 provenance

锁点名 queue sender surface 是独立的,且只有 queue 动词会写 queue 行。因此直接驱动真实的跨主机 queue 写入并对行本身断言:

# from H_A, create a qitem ON H_B with a unique body (the discriminator) export BODY="lega2-$(date +%s)" # exported: the python assertion below reads it from the environment docker exec H_A bash -lc "rig queue create --source orch-main@rig-a --destination dev-main@rig-b --host '${ID_B}' --summary 'leg-a2 provenance' --body '${BODY}'" # assert on H_B's DURABLE row — the stored identity, not a rendered line docker exec H_B bash -lc "rig queue list -A --json" | python3 -c " import json,sys,os rows=[q for q in json.load(sys.stdin) if os.environ['BODY'] in (q.get('body') or '')] assert len(rows)==1, f'expected exactly 1 row for the discriminator, got {len(rows)}' r=rows[0]; print('sourceSession:', r.get('sourceSession'), '| tags:', r.get('tags')) "

A2 PASS:恰好一行匹配唯一 body;其存储的sourceSession是带主机限定的 triple,点名 ORIGIN(orch-main@rig-a@${ID_A},stamp-at-forward,incr 4a);随行下发的from-host:tag 存在且未变(锁第 6 项)。A2 对 pane 断言零内容——信封是 A1 的表面。

这一行为在源码层面由 queue-repository.ts 的stampSelfHostSuffix支撑:转发 daemon 在远程 create 前把自己的 id作为 origin 后缀印上;只有当会话是裸member@rig(恰好 split 成两段)时才附加@selfId,已是 triple/畸形值则原样透传——origin 不可伪造。fail-open 语义是:reconciled self-id 缺失时原样通过。

LEG A3 — Broadcast 表面(rig broadcast --host):契约第 3 项点名的第三个表面

为什么这是 LIVE leg 而不是「测试已覆盖」?测试半区原先的解读是 send 与 broadcast 共享同一个 composition 瓶颈(chokepoint)。它们并没有——在关键部分:broadcast 的envelopeSender是CLI 侧从裸环境变量作者化的,会落到字面<unknown sender>(见 broadcast.ts,body.envelopeSender = seatSender ?? SENDER_FALLBACK),这条 provenance 路径与 send 的种类不同。因此 live send 捕获证明不了 broadcast,且现有 hermetic 测试(pane-envelope.test.ts/send-header.test.ts中的 broadcast 用例只断言To:scope 行;triple 套件self-host-envelope-triple.test.ts系列直接驱动共享根,未点名任何 broadcast 用例)也都不断言 broadcast sender triple。

# (i) STAMP PATH, NOT FALLBACK: set the sender env EXPLICITLY. 若不加, # 容器 exec 可能不带 OPENRIG_SESSION_NAME,捕获会渲染 "<unknown sender>"—— # 测的是 fall-open 而不是属性本身,属于「披着产品外衣的夹具缺陷」。 export BBODY="lega3-$(date +%s)" docker exec -e OPENRIG_SESSION_NAME=orch-main@rig-a H_A bash -lc \ "rig broadcast --rig rig-b --host '${ID_B}' 'broadcast triple probe ${BBODY}'" | tee "${EVID}/L5-leg-a3-send.txt" # capture the RECIPIENT pane on H_B and assert the full triple, host token in its fixed position docker exec H_B bash -lc "rig capture dev-main@rig-b" | tee "${EVID}/L5-leg-a3-recv.txt" grep -q "From: orch-main@rig-a@${ID_A}" "${EVID}/L5-leg-a3-recv.txt" || { echo "LEG A3 FAIL: recipient envelope does not carry the ORIGIN triple orch-main@rig-a@${ID_A}"; exit 1; } grep -q "<unknown sender>" "${EVID}/L5-leg-a3-recv.txt" && { echo "LEG A3 FAIL: rendered the FALL-OPEN sender — ..."; exit 1; }

A3 PASS(以锁第 3 项原文为谓词):接收方渲染信封携带 sender triplemember@rig@host——orch-main@rig-a@${ID_A}——"unconditionally … with the host token in one fixed deterministic position",点名 ORIGIN 主机,既不是${ID_B}也不是 fall-open 字面量。

P21 census 观察(记录在案,不是leg 门槛):broadcast 的envelopeSender由 CLI 从裸环境变量作者化并带<unknown sender>fall-open(body-identity 类 census site #14)。leg 通过 pin 环境变量来测 stamp 路径;provenance 问题本身属于 P21 的 pooled sweep,不属于本 leg 的裁决范围。

LEG B — Founder-Collision(证明项 5,E2 级杀手)

Claim:当两台主机存在同名 rig时,接收到的签名点名 origin,回复落在 origin 主机,而不是本地同名座。

Fixture:名为shared的 rig 同时存在于 H_A(self-idA)与 H_B(self-idB);每台主机上有 seatlead-main@shared;H_B 已在 H_A 上以B注册。

Steps:

  1. 从 H_A 的lead-main@shared:rig send lead-main@shared "collision test" --host B;
  2. 在 H_B 捕获lead-main@shared,EXPECTFrom: lead-main@shared@${ID_A}—— origin 主机消解了两个同名 rig 的歧义(这就是 founder 叙述过的碰撞,如今可诚实观测);
  3. 在 H_B 上逐字执行↩ Reply: rig send lead-main@shared@${ID_A} "...",EXPECT落到 H_A 的lead-main@shared(后继/回复跟随 triple 点名的 host),不是H_B 的同名lead-main@shared;
  4. NEGATIVE(D10 honest scope):从 H_B 执行rig send lead-main@shared "x"(裸形式,无--host)→ 会在 H_B 的shared上本地铸造。这是预期行为,且本 slice不修复它——2-part 同名歧义只能通过--host/ sender-side triple 关闭;daemon 的 teaching 拒绝只对 3-partlead-main@shared@X形式触发(unknown_destination_rig+ "use --host")。证明必须写明:51-09 让 3-part 诚实化并给出教学提示;它不会魔法般消灭 2-part 静默铸造。

Pass:跨主机签名点名 origin;逐字回复往返到 origin 主机;D10 negative 被记录在案,而非声称已消灭。

源码侧,queue-repository.ts 的destinationRigTeaching就是这条 teaching 路径:当被拒目标(3-part)的贪婪 rig token 含@时,返回附加结构化字段(destinationSplit、selfHost、hint),hint 要么是「@<host>就是本机——host 从不内联进会话字符串,请以裸member@rig重发」,要么是「请用--host <host>+ 裸 destination」。2-part / 非规范 token 则返回undefined,拒绝字节不变。同时 C4 规则明确:self-suffixed 目标点名 self 场景,绝不自动剥离/路由回家。

C5 诚实范围(继承自 ruling c9964404)

  • origin-host-in-sender-identity slice 使3-part 形状的 host-blind 寻址不可能被静默写出:always-suffixFrom:+ 回复往返 + teaching 拒绝三者闭合;
  • **2-part 同名静默铸造(D10)**由--host信封 + sender-side stripping(incr 3)关闭,不是由 in-string daemon 解释器关闭——上面的证明(LEG B 步骤 4)明确如此声明。

从夹具到可复跑测试床:L5 运行手册的承接关系

这套夹具与运行手册是 L5-multi-host-and-51-09.md 的51-09 live-leg rider:在 L5 的同一双容器会话中,先按 L5.1 启动两台 named self-host(每容器一个 daemon、容器本地 DB/HOME、唯一共享面是 docker 网络),按 L5.2 通过 host registry over HTTP 组网,然后在此会话内端到端跑完 LEG A 与 LEG B 并归档两套证据。L5 的 pass 标准包括:两台容器在各自/healthz上报非空、互不相同的selfHostId,且该 id 在容器内 daemon 重启后保持稳定(51-09 incr 1 —— 单例永不重 key)。

关键源码与文档索引

  • 夹具说明:culture.md
  • 完整执行手册:RUNBOOK.md
  • 三台 rig 定义:rig-a.yaml、rig-b.yaml、shared.yaml
  • 会话名派生与解析契约:session-name.ts
  • 转发时 origin 后缀 stamp 与 teaching 拒绝:queue-repository.ts
  • broadcast 的 sender 作者化与 fall-open:broadcast.ts
  • /healthz的selfHostId表面:server.ts
  • host registry 注册语法:host.ts
  • 测试床镜像的 openrig 用户声明:Dockerfile
  • 双主机测试床承接手册:L5-multi-host-and-51-09.md

小结

51-09 live-leg 夹具的核心方法论可以浓缩为四条纪律:seat 名只派生、不手写;身份只捕获、不预测(adopt-by-read);动作与断言必须匹配(哪个动词写哪个存储,就由哪个动词证明);诚实边界要声明(3-part 诚实化并 teaching,2-part 静默铸造不被消灭但被记录)。配合 zero-token 的 stub 运行时与「以产品用户身份交付、以执行用户真实读写」的 provisioning 纪律,这套夹具把跨主机 sender triple 与 founder-collision 从单元测试的「共享根直驱」升级为两台真实 daemon 上的端到端证明。

  • 人工智能
  • AI Agent
  • 多智能体
  • Agent 编排
  • 代码智能体
  • CLI

【免费下载链接】openrig

Build your own network of agents from Claude Code, Codex and Pi: persistent teams with roles, shared context and owned work.

项目地址:https://gitcode.com/GitHub_Trending/op/openrig
点击查看免费下载
上一篇:Step1X-Edit v1.2:当AI图像编辑学会"思考"之后
下一篇:SortableJS移动端适配终极指南:打造完美触摸排序体验

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询