Skip to content

feat(broker): 常开控制面 broker (WSS+PSK+扇出) + abg broker start (PR3)#190

Open
raysonmeng wants to merge 1 commit into
feat/v3-pr2-identity-authfrom
feat/v3-pr3-broker
Open

feat(broker): 常开控制面 broker (WSS+PSK+扇出) + abg broker start (PR3)#190
raysonmeng wants to merge 1 commit into
feat/v3-pr2-identity-authfrom
feat/v3-pr3-broker

Conversation

@raysonmeng

Copy link
Copy Markdown
Owner

Stacked on #189 (PR2) — base 是 feat/v3-pr2-identity-auth。逐层合并后自动 retarget。

概要 / 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.ts WSS + hello{token} PSK 鉴权(StorePskIdentityProvider)→welcome/auth_error(close 4401);subscribe(回 ack)/unsubscribe/publish;非 hello 要求先鉴权;close 退订全部;可配 bind host
src/cli/broker.ts abg broker start --host/--port/--db;collab DB 目录 0700;resolveBindHost 白名单护栏(§7.3)
InProc/InMemory 加固 每个 subscriber handler try/catch 隔离(throwing-subscriber 不阻塞 siblings)+ 契约锁
docker/ 多容器多机模拟(compose + Dockerfile + provision/broker/sim-client)+ .dockerignore

测试计划 / Test plan

  • broker 集成测试(valid/invalid auth + 扇出 + malformed-JSON 拒绝)+ broker-cli(bind-host 护栏 + CGNAT 精度)
  • Docker 多机模拟实跑通过:4 容器 provision→broker→publisher→subscriber,subscriber 跨容器收到 publisher 的 task_completed 事件 → SIM_OK 退 0(验证 §13 跨机切片:PSK 鉴权可达 + 扇出)
  • bun run check exit 0 → 1730 pass / 0 fail、typecheck 干净、bundle 同步

Cross-review

  • 轮 1(thorough,3 维 + 对抗式 verify):抓出并修复 2 个真实 issue
    • HIGH 绑定护栏:旧黑名单 host === "0.0.0.0" 漏掉空串 --host= 与 IPv6 ::Bun.serve 静默绑全部网口、零警告(lsof 实证)。broker.ts?? "127.0.0.1" 是 nullish 合并,空串不回落。→ 改 loopback 白名单(空串→loopback;非 loopback 且非 Tailscale CGNAT 100.64.0.0/10 都警告)+ broker.ts|| 回落。
    • malformed JSON unhandled-rejectionJSON.parse("null") 后访问 .type 抛错逸出 async handleMessagevoid 吞成 unhandled rejection(客户端发 null/42 即触发)→ 加 shape 守卫 + message handler .catch
  • 轮 2 / 轮 3(lean):连续两轮 0 真实 issue → 收敛(CGNAT 精度顺手修正)。

Backlog / 计划内

  • broker 无 topic/room 级授权(任一有效 token 可订阅/发布任意 topic)—— room 成员授权是 PR5/PR6(membership + 三档路由);loop prevention/traceId/hop 同。
  • 订阅数 / publish 大小 / idle 无上限(后续限流 + 超时,防 slowloris/DoS)。
  • resolveDbPath+0700 在 auth/broker 重复(可抽 helper);2 个 pre-existing flaky 计时测试(DaemonClient.sendReply、port-cleanup,隔离 pass、非本 PR)。

🤖 Generated with Claude Code

按 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant