feat(broker): 常开控制面 broker (WSS+PSK+扇出) + abg broker start (PR3)#190
Open
raysonmeng wants to merge 1 commit into
Open
feat(broker): 常开控制面 broker (WSS+PSK+扇出) + abg broker start (PR3)#190raysonmeng wants to merge 1 commit into
raysonmeng wants to merge 1 commit into
Conversation
按 spec §11.1 落地常开 broker 进程——v3 跨机协作的脊柱。新进程 src/broker.ts(独立
故障域,不碰现有 daemon 1:1 流):Bun.serve WSS + 每连接 PSK 握手(StorePskIdentityProvider)
+ MessageTransport 扇出。**控制面 only**:只接受/转发 Envelope,绝不读写 repo 文件(§2.6)。
- src/broker.ts:hello{token} 鉴权→welcome/auth_error(close 4401);subscribe(回 ack)/
unsubscribe/publish;非 hello 消息要求先鉴权;close 退订全部。可配 bind host(默认 loopback)。
- src/cli/broker.ts:abg broker start --host/--port/--db;collab DB 目录锁 0700;
resolveBindHost 白名单护栏(空串→loopback;非 loopback 且非 Tailscale CGNAT 100.64.0.0/10 都警告 §7.3)。
- InProc/InMemoryTransport 加固:每个 subscriber handler try/catch 隔离(throwing-subscriber
不阻塞 siblings,broker 扇出消费者驱动)+ 契约测试锁。
- docker/:多容器多机模拟(compose + Dockerfile + provision/broker/sim-client)+ .dockerignore。
测试:broker 集成测试(auth + 扇出 + malformed-JSON 拒绝)+ broker-cli(bind-host 护栏)。
**Docker 多机模拟实跑通过**:4 容器跨容器 PSK 鉴权 + 扇出,subscriber 收到 publisher 的
task_completed 事件(SIM_OK)。full check exit 0:1730 pass / 0 fail。
Cross-review:轮 1 thorough 抓出并修复 2 个真实 issue——① HIGH 绑定护栏(旧黑名单 host==="0.0.0.0"
漏掉空串/IPv6 :: → 静默绑全网口;改 loopback 白名单 + broker.ts `|| ` 回落);② malformed JSON
(null/number 访问 .type 抛错逸出 async handler 成 unhandled rejection;加 shape 守卫 + .catch)。
轮 2/轮 3 lean 连续两轮 0 收敛(CGNAT 精度顺手修正)。
Backlog:broker 无 topic/room 级授权(任一 token 可订阅/发布任意 topic)——room 成员授权是
PR5/PR6;订阅数/publish 大小/idle 无上限(后续限流/超时);DEFAULT_BROKER_PORT=4700 避 multi-pair。
另:2 个 pre-existing flaky 计时测试(DaemonClient.sendReply、port-cleanup,隔离 pass、非本 PR)。
---
feat(broker): always-on control-plane broker (WSS + PSK + fan-out) + abg broker start (PR3)
Land the always-on broker (§11.1) — the backbone of v3 cross-machine collaboration.
New process src/broker.ts (independent failure domain): Bun.serve WSS + per-connection
PSK handshake + MessageTransport fan-out. CONTROL PLANE ONLY — forwards Envelopes,
never touches repo files (§2.6). Configurable bind host (loopback default; §7.3 warning
on exposed addresses). Hardens InProc/InMemory transports against a throwing subscriber.
Ships a Docker multi-machine sim (verified: cross-container PSK auth + fan-out → SIM_OK).
Converged after 1 thorough + 2 lean adversarial rounds (fixed a HIGH bind-host guard gap
and an unhandled-rejection on malformed JSON).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要 / Summary
PR3:落地常开控制面 broker(§11.1)——v3 跨机协作的脊柱。新进程
src/broker.ts(独立故障域,不碰现有 daemon 1:1 流):Bun.serve WSS + 每连接 PSK 握手 + MessageTransport 扇出。控制面 only:只接受/转发 Envelope,绝不读写 repo 文件(§2.6,代码同步靠 git)。改动 / Changes
src/broker.tshello{token}PSK 鉴权(StorePskIdentityProvider)→welcome/auth_error(close 4401);subscribe(回 ack)/unsubscribe/publish;非 hello 要求先鉴权;close 退订全部;可配 bind hostsrc/cli/broker.tsabg broker start --host/--port/--db;collab DB 目录 0700;resolveBindHost白名单护栏(§7.3)docker/.dockerignore测试计划 / Test plan
provision→broker→publisher→subscriber,subscriber 跨容器收到 publisher 的task_completed事件 →SIM_OK退 0(验证 §13 跨机切片:PSK 鉴权可达 + 扇出)bun run checkexit 0 → 1730 pass / 0 fail、typecheck 干净、bundle 同步Cross-review
host === "0.0.0.0"漏掉空串--host=与 IPv6::→Bun.serve静默绑全部网口、零警告(lsof 实证)。broker.ts的?? "127.0.0.1"是 nullish 合并,空串不回落。→ 改 loopback 白名单(空串→loopback;非 loopback 且非 Tailscale CGNAT100.64.0.0/10都警告)+broker.ts用||回落。JSON.parse("null")后访问.type抛错逸出 asynchandleMessage被void吞成 unhandled rejection(客户端发null/42即触发)→ 加 shape 守卫 + message handler.catch。Backlog / 计划内
resolveDbPath+0700 在 auth/broker 重复(可抽 helper);2 个 pre-existing flaky 计时测试(DaemonClient.sendReply、port-cleanup,隔离 pass、非本 PR)。🤖 Generated with Claude Code