docs(protocol): add the peer agent directory, observation and delivery contract - #4530
Conversation
…y contract The steward channel and the peer Agents inside one Goal need the same three abilities about each other, and each is currently answered by a different internal surface: which Agents exist and which are running, what may be read about one of them, and how a bounded request is handed over. The operator side already exists as `agent_management_projection_v0`, which is explicitly not a dispatcher; there was no Agent-facing contract beside it. `peer_agent_directory_v0` adds that contract without adding a source of truth. Identity, work, claims, leases and the canonical revision stay with their owners; the contract contributes an Agent-facing view plus the rules for reading and delivering: - one row per registered Agent, with optional provider-scoped presence that must carry its provider, observation time and basis, so a reader can distinguish "not running" from "this machine cannot see it"; - a liveness vocabulary that maps a terminal-space provider's states onto LoopX meaning, with `unknown` never read as completion and `blocked` never read as permission to answer a gate; - bounded observation that prefers typed projections and treats terminal output as explicitly advisory, with declared provider limits and a durable fallback; - bounded delivery that separates refusal before write, submission, observed activity and the no-blind-resend rule, keeping `context_handoff` as the durable record; - authority rules that keep the contract non-mutating: observation and delivery grant no claim, lease, priority, plan change or amendment, a reader is not a scheduler for its peers, and scope is authorization rather than convenience. The provider half is written as a checklist a host surface must satisfy. Herdr is cited as the reference implementation of that half because its Agent skill documents the same abilities from the terminal's side — in-space caller proof, session-scoped identifiers, the same liveness words, bounded read sources with the alternate-screen limit, refusal at an approval gate, stalled-submission reporting, and no claim that a timeout means non-delivery — and the document names what LoopX adds that such a provider cannot supply. The shared-goal alignment RFC records the same rules at its own level in a new §3.6, in both language editions, so the per-Agent frontier and the peer-facing view stay one model. Verified: examples/docs-governance-smoke.py ok, including the new relative links from the RFC and the protocol index. Documentation only, no behavior change. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
一、变更内容
- 新增协议文档
docs/reference/protocols/peer-agent-directory-and-observation-v0.md(peer_agent_directory_v0):把"发现 / 有界观察 / 有界投递"三件事写成可复用、provider 中立的契约,作为agent_management_projection_v0(面向 operator)的面向 Agent 的伴生契约。 docs/reference/protocols/README.md在 Agent And Multi-Agent Coordination 分组登记该文档。docs/architecture/rfcs/shared-goal-alignment-and-governed-amendment-v0.md(及中文镜像)新增 §3.6,把同一组规则写在本 RFC 自己的层级上,并更新最后更新日期。- 契约要点:目录按已注册 Agent 出行、presence 可选且必须带 provider/observed_at/basis;liveness 词表把终端空间的
working|blocked|idle|done|unknown映射到 LoopX 语义(unknown绝不等于完成、blocked绝不等于可直接应答 gate);观察以 typed projection 优先、终端输出显式 advisory 且 provider 必须声明限制;投递区分"拒绝写入 / 已提交 / 观测到活动 / 超时不等于未投递且不得盲目重发";权威规则写明观察与投递不授予任何 claim、lease、优先级、计划变更或修订,读取方不得成为 peer 的调度器,范围是授权而非便利。 - herdr(
herdrdev/herdr,Apache-2.0)作为 provider 半边的参考实现被引用:in-space caller proof(HERDR_ENV=1+ 注入的 workspace/tab/pane id)、session-scoped 不透明标识、同一套 liveness 词、有界读来源与 alternate-screen 限制、agent prompt在审批 gate 处写入前拒绝、agent_prompt_stalled、以及"超时不证明未投递"的告警;同时写明 LoopX 多出而终端 provider 无法提供的东西(durable 身份、意图修订、claim/lease 归属、typed gate、以及"观察不授予任何权限")。
二、依据与一致性
- 依据是本次对 herdr 的实际调研:README/官网说明(后台 server 持有终端、detach 后继续、重启恢复布局但不复活进程、多机器统一 agent 列表、pane 状态 working/blocked/idle、agents 通过 CLI 与 socket API 驱动)、其仓库内
skills/herdr/SKILL.md(Agent 面向的完整契约)、以及src/(Rust:ipc.rs、pane/、detect/、layout.rs、persist.rs、agent_resume.rs、handoff_runtime.rs)给出的实现分层。 - 与既有 LoopX 契约一致且不重复:身份/工作/claim/lease 归 registry、todo、lease、frontier;意图归
shared_goal_intent_v0;投递归context_handoff;terminal layout/进程归宿主 provider。agent_management_projection_v0明确"不得成为 dispatcher/lease manager/workspace manager/write queue",本契约把同一条边界写在 Agent 侧。 - 与
peer_agent_runtime_v1一致:无 rank、无 leader agent;本契约不新增任何 rank 或调度权。 - 中文镜像按仓库规则同步 RFC 半边;protocol 目录按仓库惯例为英文(70 篇中仅 3 篇有镜像),这一点已在 PR 中说明而不是默默省略。
三、验证
examples/docs-governance-smoke.py:ok(含新增的相对链接:RFC → protocol,以及 protocol index → 新文档)。loopx canary premerge --from-git-diff:merge_gate_passed=false,原因是一条与本次 diff 无关的既有红:examples/control_plane/peer-agent-runtime-v1-smoke.py→peer-agent-hard-cut-boundary-smoke.py命中loopx/chat_manager.py:190、loopx/chat_manager.py:217、loopx/chat_runtime.py:398的散文。已在干净的origin/main(df47d07bd)上原样复现,且这三个文件本次未被改动;其余 7 条 catalog canary、risk-profile smokes 与 public boundary 全部通过;另一条是已知 advisorycontrol-plane-maintainability-ratchet-smoke。
四、风险与残余缺口
- 契约描述的是"应当如何",实现侧尚未接通:目前没有统一的
peer_agent_directory_v0产出(operator 侧是agent_management_projection_v0,管家侧是 manager inspection +context_handoff),也没有 provider 注册表。本文档不把它写成已交付,PR 正文亦如此。 - 基线红(peer-agent-hard-cut)会阻断任何选中该 canary 的 diff 的自合并。本次按授权合并并如实记录;紧接着用一刀独立修复(改散文措辞而不是放宽检查)。
- 未做:把 per-Agent 对齐投影并入目录行(当前目录行只带 work/presence);provider 的实际接入(例如本机若使用 herdr 或 tmux 作为终端空间);目录的前端呈现。
五、结论
批准以 admin squash 合并(需维护者授权,因门禁为既有基线红而非本 diff)。纯文档、可回滚、无行为与权限变化;它把 herdr 已证明可用的机制抽象成 LoopX 可复用的三方契约(发现/观察/投递),并明确 LoopX 特有的权威边界,使管家与 peer agent 未来能共用同一机制发现彼此。
English verdict: Approved for an admin squash merge with maintainer authorization. Documentation-only: a new provider-neutral protocol for peer agent discovery, bounded observation and bounded delivery, plus a §3.6 in the shared-goal alignment RFC. It adds no source of truth and grants no authority — observation and delivery confer no claim, lease, priority, plan change or amendment — and it cites Herdr as the reference implementation of the provider half while separating what only LoopX can own. Docs governance smoke passes; the one canary failure is a pre-existing baseline red reproduced on clean main in files this diff does not touch.
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
管家通道和同一个 Goal 里的对等 Agent 需要同样的三种能力:知道有哪些 Agent 存在、哪些在运行;在有界范围内观察其中一个;把一条有界请求交给其中一个。而这三件事此前分别由不同的内部面回答。operators 侧已经有 agent_management_projection_v0(它明确声明自己不是 dispatcher),但 Agent 侧旁边没有任何书面契约。缺口是真实的:没有契约时,每个调用方会各自发明 presence 与投递语义,最终很容易把"终端里看到的东西"当成进展证据,或把"投递成功"当成"对方开始干活"。
改动思路
写法我很认可:新文档先给"来源真相表",把身份/工作/租约/规范意图/投递/配额各自的 owner 摆明,再说"这里没有新的真源";接着才是 directory packet、presence 词表、有界观察、有界投递、权威边界、provider 契约与验收检查。也就是说,它没有顺手实现一个目录服务,而是先把"谁拥有什么"钉住,再定义视图和读取/投递规则。
几个关键的"反面语义"写得比正面语义更有价值:unknown 永远不等于完成、blocked 不等于有权回答 gate、done/idle 只是"可以输入"而不是"请求已送达";投递要把"拒绝写入 / 已提交 / 观察到活动 / 无盲重发"四件事分开;观察优先用类型化投影,屏幕摘录永不被提升为证据。presence 必须带 provider/observed_at/basis,才能把"没在跑"和"这台机器看不到"区分开。
RFC 侧只在 §3.6 记录三条最关键的规则(presence 是 advisory 且按 provider 划定范围、观察与投递不授予任何东西、terminal-space provider 是 provider 而非契约本身),并沿用 §3.5 的"不新增第五种/第六种共享状态"表述,这一致性是对的。
具体改动
新增 docs/reference/protocols/peer-agent-directory-and-observation-v0.md(234 行),在协议索引里登记 peer_agent_directory_v0(按字母序插在 multi_agent_visible_launcher_v0 与 peer_agent_runtime_v1 之间),并在对齐 RFC 的中英两版加 §3.6、把"最后更新"改为 2026-09-16。四文件 +294/-2,全部 Markdown。
我核对了文中的引用是否都落地:agent_management_projection_v0 存在且确实写着 "must not become a dispatcher",peer_agent_runtime_v1、agent-scoped-evidence-ledger-v0、context_handoff、shared_goal_alignment_v0 都存在(context_handoff 在 manager-context 代码里可见);索引行能解析到新文件,RFC 两版链接也都解析;examples/docs-governance-smoke.py 与 examples/multi-agent-visible-launcher-protocol-smoke.py 均 ok,git diff --check 干净。英文单版本符合仓库惯例(66 个协议文档里只有 3 个有中文版)。
一个 P3(非阻塞,已记入 findings):这份契约没有说明自己目前还没有实现。我把 schema id 与它的特征字段(provider_session_ref、observation_limits、presence_is_advisory)在仓库里搜了一遍,除 docs 外没有任何生产者;它指向的 operators 侧是另一个只读投影。这样读者可能会去找这个目录面然后找不到。仓库里已有若干协议文档用一行 Status: 说明状态(Status: implemented contract / staged implementation / experimental protocol and implementation target),相邻的团队入端口径 RFC 也明确写了"线上仍是惰性的"。补一句(契约文档,必要时连 §3.6 一起)说明当前状态——规范已定、provider 半边未落地,持久半边(注册身份、Todo claim/lease、context_handoff)已有——即可消除歧义,不改任何规则。
对主干的风险
风险极低且可完全回滚:diff 全是 Markdown,没有一行可执行代码,也没有新增 store、注册表、消息总线或权限;一个新协议 id 被登记,没有任何 id 被重命名或废弃。文档治理 smoke 与协议索引 smoke 都通过,链接在中英两版各自解析。
唯一需要留意的是上面那条 P3:文档没有自述实现状态,读者可能期待一个已存在的目录面。它不改变任何强制规则,blast radius 限于文档清晰度。
反过来说,这份契约最大的价值是把"不要从终端推断 LoopX 状态""不要盲重发""观察与投递不授予任何东西"这些容易被踩的规则写成了成文契约,并且明确把 terminal-space provider 定位为 provider 而非契约本身。
我的整体评价
这是一次范围贴合、结构清晰的契约补全:它把 Agent 侧的三种能力写成文档,却没有顺手实现任何东西,也没有新增共享状态;来源真相表、presence 反面语义、有界观察/投递、provider 契约与验收检查构成一份可执行性不错的规范,索引与 RFC 锚点也都对得上。引用逐条核对无误,两个 docs smoke 绿灯。
建议补一句实现状态(P3),不构成合并阻塞。
English verdict: APPROVE (exact head d7aba66)
Problem
The steward channel and the peer Agents inside one Goal need the same three abilities about each
other — which Agents exist and which are running, what may be read about one of them, and how a
bounded request is handed over — and each is currently answered by a different internal surface.
The operator side already exists as
agent_management_projection_v0, which is explicitly not adispatcher; there was no Agent-facing contract beside it.
What changed
New protocol doc
docs/reference/protocols/peer-agent-directory-and-observation-v0.md, registered inthe protocol index, plus a §3.6 in the shared-goal alignment RFC (EN and ZH) that records the same
rules at its own level.
peer_agent_directory_v0adds no source of truth: identity, work, claims, leases and the canonicalrevision stay with their owners, and the contract contributes an Agent-facing view plus the rules for
reading and delivering.
carry its provider, observation time and basis, so a reader can tell "not running" from "this
machine cannot see it". A live session never creates an identity.
unknownis never completion,blockedis never permission to answer a gate, anddone/idleare readiness for input rather than a delivered request.
declared provider limits and a durable fallback when a bounded read cannot carry the answer.
activity window with a typed
stalledoutcome, no blind resend after a timeout, andcontext_handoffreceipts as the durable record.amendment; a reader is not a scheduler for its peers; scope is authorization rather than
convenience; host-surface control keeps the host's own consent rules.
rule: with no provider the directory is registered identity plus durable work state.
Herdr is cited as the reference implementation of the provider half, because its Agent skill
documents the same abilities from the terminal's side: in-space caller proof, session-scoped opaque
identifiers, the same liveness words, bounded read sources with the alternate-screen limit,
agent promptrefusing at an approval gate before writing, stalled-submission reporting, and thewarning that a timeout does not prove non-delivery. The document also names what LoopX adds that such
a provider cannot supply (durable identity, intent revision, claim/lease ownership, typed gates, and
the rule that observation grants nothing).
Changed surfaces
docs/reference/protocols/peer-agent-directory-and-observation-v0.md(new),docs/reference/protocols/README.md(index entry),docs/architecture/rfcs/shared-goal-alignment-and-governed-amendment-v0.mdand.zh-CN.md(§3.6 and the date line).Protocol docs are English by repository convention (3 of 70 carry mirrors); the RFC half is mirrored.
Validation
examples/docs-governance-smoke.py: ok, including the new relative links from the RFC and the index.loopx canary premerge --from-git-diff:merge_gate_passed=falsefor one pre-existing, unrelatedfailure:
examples/control_plane/peer-agent-runtime-v1-smoke.pyfails becauseexamples/control_plane/peer-agent-hard-cut-boundary-smoke.pyflags prose inloopx/chat_manager.py:190,loopx/chat_manager.py:217andloopx/chat_runtime.py:398. Reproducedidentically on clean
origin/main(df47d07bd) with none of this diff applied, and none of thosefiles are touched here, so it is a baseline red and not this change. The other 7 selected canaries,
the risk-profile smokes and the public-boundary scan pass; one further failure is the known advisory
control-plane-maintainability-ratchet-smoke. Merged with explicit maintainer authorization; thebaseline red is being fixed separately rather than worked around here.
Boundaries
Documentation only, no behavior change, no authority change, no new runtime surface. The contract
grants nothing: it describes what may be discovered, read and delivered, and keeps every write with
its existing canonical owner.