feat(runtime-host): add peer mesh membership - #4048
Conversation
4cae1a9 to
a9df41e
Compare
3657e44 to
b0d2b8a
Compare
jackwener
left a comment
There was a problem hiding this comment.
I reviewed exact head b0d2b8af32ba2be68635556ca9f9370a598c650e. The membership and transport boundaries are generally sound, but I found one re-admission bug that should be fixed before this feature is merged, plus one bounded cancellation issue.
[P2] A removed member cannot use a fresh invitation to rejoin
After A creates a Mesh and B joins, B stores signed roster revision 2. If A removes B, A advances to revision 3, but B still has the older signed snapshot. That is expected while roster propagation is out of scope; the bug is that a later fresh invitation from A cannot repair it. join() checks the local snapshot first and throws This peer already belongs to that Peer Mesh before contacting A.
I reproduced this with the release addon: A reported revision 3 containing only A, while B still reported revision 2 containing A+B. Closing B's node and native endpoint and reopening the same key and data root preserved revision 2. A newly issued invitation was then rejected locally with the error above.
A valid signature proves that revision 2 was once authoritative, not that it is still current. A fresh invitation should be allowed to reach the authenticated authority even when the local snapshot contains the peer. The client should replace its replica only with a correctly signed roster from the same authority whose revision is strictly newer. A release-addon regression should cover remove → restart → fresh invitation → successful rejoin. Full proactive roster propagation is not required for this repair; if status() remains local-only, it should be documented as last-known signed state rather than current membership.
[P3] Cancelled negotiations temporarily consume the connection's stream budget
Once the connection handler emits an OutboundSubstreamRequest, cancelling or timing out the caller removes the engine waiter and aborts the open_stream task, but the handler retains the closed result sender until libp2p later reports negotiation success or failure. The already-issued negotiation also continues.
A directed handler test issued and cancelled 128 negotiations on one persistent connection and observed pending.len() == 128. This is bounded rather than permanent: libp2p's default upgrade timeout is 10 seconds, yamux defaults to 512 streams per connection, and the product reconnect owner backs off. Still, a short retry burst can temporarily consume the stream budget for both application and Mesh work.
Please prune closed senders and enforce a hard bound on all issued-but-unsettled negotiations. A regression should verify deterministic rejection or backpressure at the limit and recovery after settlement or timeout; pruning the map alone does not cancel negotiations already handed to libp2p.
The remaining checks were positive: Ed25519 roster authority remains separate from Runtime Host credentials and grants no Runtime Host resource access; invitation redemption is bound to the authenticated peer and survives a lost response; durable state and multi-process ownership fail closed; and application/Mesh protocol isolation, abort, reconnect, endpoint close, Rust tests, the full Runtime Host suite, and hosted exact-head checks all passed. The current-main merge is clean. Because this is a feature, the final merge decision still belongs to a human after the P2 is resolved.
Posted by an automated review agent operated by @WAWQAQ. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.
简体中文
本条评论由 @WAWQAQ 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。
EnglishThe confirmed re-admission bug is fixed at A locally stored roster is now treated as last-known signed state, not proof of current membership. A fresh invitation is allowed to reach the authenticated authority even when the local replica still contains the joining peer. An existing replica is replaced only when the response is signed by the same authority and carries a strictly newer revision; re-admission also does not double-count the peer against Mesh capacity. The installed CLI smoke now covers the reported product path: remove member → close and restart with the same peer key and data root → retain the stale replica → redeem a fresh invitation → rejoin at a newer revision. The full Runtime Host test suite also passes. The cancelled-negotiation finding is valid but belongs to the endpoint negotiation lifecycle introduced by #4036 rather than this membership change. It is bounded and does not block #4048, so it is tracked separately in #4057. That follow-up explicitly bounds all issued-but-unsettled negotiations instead of merely pruning closed result senders. 简体中文已确认的重新加入问题已在 本地保存的 roster 现在只代表最后已知且签名有效的状态,不再被视为当前成员关系的证明。即使本地副本仍包含待加入节点,新的 invitation 也会到达经过认证的 authority。已有副本只有在响应来自同一 authority 且 revision 严格更新时才会被替换;重新加入也不会重复占用 Mesh 容量。 已安装 CLI 的 smoke test 现已覆盖审查中报告的真实路径:移除成员 → 使用相同 peer key 和 data root 关闭并重启 → 保留旧副本 → 使用新 invitation → 以更高 revision 重新加入。完整 Runtime Host 测试套件也已通过。 取消协商的问题成立,但它属于 #4036 引入的 endpoint negotiation 生命周期,而不是本次 membership 变更。该问题有界且不阻塞 #4048,因此已独立记录为 #4057。后续会显式限制所有已发出但尚未结算的协商,而不是只清理已关闭的结果 sender。 |
Add durable signed Mesh membership and recoverable authenticated invitations. Share one peer endpoint across application and Mesh protocols while preserving bounded lifecycle, connection ownership, and release-package validation. Generated-by: OpenAI Codex
Treat a replica roster as last-known signed state rather than proof of current membership. Let a fresh invitation reach the authority and replace local state only with a newer roster from the same authority. Exercise removal, member restart, and re-admission through the installed CLI artifact. Generated-by: Codex
Mirror the public peer stream close contract in the native test helper. A remote EOF may complete the stream before the second endpoint sends its explicit close, which is already treated as an idempotent success by the production binding. Generated-by: Codex
6f3d87d to
851ff73
Compare
jackwener
left a comment
There was a problem hiding this comment.
I re-reviewed exact head 851ff732f5850dd81d6f77b7d4b9a89a7e54fd56. I found no remaining P0–P2 issues.
The re-admission defect is closed. A stale local replica no longer blocks a fresh invitation before the authenticated authority is contacted. The client replaces an existing replica only when the returned roster is signed by the same authority, contains the local peer, and has a strictly newer revision. Replacing that replica also does not consume an additional Mesh-capacity slot.
The installed-CLI smoke test now covers the reported recovery path end to end: remove a member, close and restart it with the same peer key and data root, recover the stale roster, redeem a fresh invitation, and rejoin with a newer signed roster. The final rebase preserves both reviewed patches exactly; its only additional commit makes the Rust test helper accept a stream whose command channel has already closed. The focused Runtime Host and Rust tests pass.
The bounded cancelled-negotiation issue remains a non-blocking endpoint-lifecycle follow-up and is now tracked separately in #4057. It does not change the membership authority or durability guarantees reviewed here.
The exact-head required checks completed successfully, and the merge result against current main is clean. @M4n5ter has made the human decision to proceed with this feature and retains the merge action.
Posted by an automated review agent operated by @WAWQAQ. This is not an
independent human review and does not satisfy the committer review required by
CONTRIBUTING.md. A human is accountable for this comment — please push back if
anything here is wrong.
简体中文
本条评论由 @WAWQAQ 运行的自动化审查程序发出。它不构成 CONTRIBUTING.md
所要求的独立人类审查,也不能替代人类审查。有人类对本条评论负责,如有错误请直接指出。
English
Summary
Add durable signed Peer Mesh membership on the shared libp2p endpoint. A Host can create a Mesh, issue bounded one-time invitations, admit authenticated peers, remove members, and close the Mesh without granting Runtime Host resource authority.
Signed rosters are the sole membership authority. Redeemed invitations remain durable for response-loss recovery, while application and Mesh control streams keep independent bounded lifecycles on one Swarm. This is an internal foundation: discovery, roster propagation, Desktop UI, public CLI, transit, and Runtime resource grants remain out of scope.
Refs #3842
Verification
npm run lintnpm run format:checknpm run typechecknpm test --workspace @maka/runtime-host— 1,313 passed, 9 skippedReview focus
AI use
Tool(s) and scope: OpenAI Codex implemented and verified the change under the contributor direction and review
Checklist
Does this PR entail a change in behavior?
中文
概要
在共享的 libp2p endpoint 上增加持久、带签名的 Peer Mesh 成员能力。Host 可以创建 Mesh、签发有界的一次性邀请、接纳经认证的 peer、移除成员并关闭 Mesh,同时不会授予 Runtime Host 资源权限。
带签名的 roster 是成员关系的唯一权威事实。已兑换邀请会持久保留以支持响应丢失恢复;application 与 Mesh control stream 在同一个 Swarm 上保持相互独立且有界的生命周期。本 PR 只提供内部基础:discovery、roster propagation、Desktop UI、公开 CLI、transit 和 Runtime 资源授权均不在范围内。
Refs #3842
验证
npm run lintnpm run format:checknpm run typechecknpm test --workspace @maka/runtime-host— 1,313 通过,9 跳过审查重点
AI 使用
工具及范围:OpenAI Codex 在贡献者指导和审查下实现并验证了本次变更
检查清单
本 PR 是否包含行为变化?