19 · 架构模式与技术债
Buzz 最成熟的地方不是功能数量,而是反复使用同一组安全/一致性模式:服务器解析租户、community-scoped keys、候选与授权分离、事务内事实与提交后通知分离、租约配 generation fence、对象存储 pointer CAS。主要风险则来自巨大协议面、权限规则多处复现、Desktop/Relay 热点文件和“基础设施完成 ≠ 产品闭环”的状态表述。
1. 值得复用的架构模式
1.1 Type-level tenant fence
TenantContext 不允许从用户 payload 默认构造,把“先解析 host 再处理请求”变成类型要求。数据库/Redis/object key 又重复 community scope,形成纵深防御。
1.2 Candidate is not authority
多处使用同一原则:
| 候选层 | 最终裁决 |
|---|---|
| subscription index | authoritative filter + access gate |
| Redis topic | receiver tenant + membership/privacy gate |
| search generated column | hydrate + event_visible_to_reader |
| workflow cache | run-time owner authority recheck |
| readiness directory | signature + expiry + generation |
缓存/index 错误只能影响性能或候选集,不能扩大授权。
1.3 Durable fact before notification
DB commit 在 Redis/fan-out/workflow 前;Git immutable packs 在 manifest CAS 前;Push 重要投递进入 outbox,而不是依赖 PubSub。三个子系统用不同实现表达同一条因果规则。
1.4 Lease + generation
Huddle/Mesh owner 与 Push endpoint 都使用 generation fence。TTL 处理“多久后能接管”,generation 处理“旧持有者回来怎么办”。
1.5 Explicit incomplete states
工作流 approval 没有伪装完成:finalizer 主动标 Failed;feature-disabled reaction 返回 skipped;README/代码有“being wired up”语义。显式失败比悬挂状态更可运营。
2. 主要复杂度债务
2.1 Kind 注册表成为巨大协议 schema
优点是跨端统一;风险是每加 kind 都要同步 lifecycle、DB、privacy、search、CLI、TS/Dart、docs/conformance。需要生成式注册表或机器可读 schema 减少手工漂移。
2.2 权限逻辑分布
写入在 ingest,历史读在 req,live 在 event/fan-out,HTTP bridge/搜索/Push/工作流各有适配。虽然已有中心 helper/集合,仍容易出现“某条入口漏一层”。独立 conformance 应持续覆盖所有入口,而不只核心 Filter。
2.3 热点文件与编排中心
ingest.rs、req.rs汇聚所有 kind 特例。state.rs汇聚服务与后台任务。buzz-acp/relay.rs汇聚复杂重连状态。desktop/src-tauri承担大量 OS/Agent/Git/媒体职责。
按协议/领域拆小有利可读性,但拆分不能复制安全门;更适合“纯 validator + 单一 pipeline orchestrator”。
2.4 Event 与投影的双重真相
成员、workflow、Git refs 等有不同权威点。必须为每个对象写清:
- 哪个存储是 commit point。
- Nostr event 是命令、事实还是通知。
- 投影失败如何修复。
- 重建从哪里开始。
否则客户端/运维容易把最新 event 错当数据库状态,或反之。
3. 已确认的文档漂移
| 旧叙述 | 当前源码证据 | 结论 |
|---|---|---|
| 架构文档称没有 rate limiter | RedisRateLimiter + Relay AppState 构造接线 | 已过期 |
| 搜索图可能暗示独立 indexer | 当前 buzz-search 使用 PostgreSQL generated search_tsv | 无 sidecar indexer |
| README 把 Push 放 pending | gateway、lease、outbox、worker 已完整存在 | 服务端已实现,产品/部署闭环部分完成 |
| Workflow schema 有 approval | finalizer 遇 token 主动标 Failed,WF-08 注释 | 不能宣称可用 |
| Schema 展示单一 FTS 表达式 | migration 对新库/棕地采取不同 rollout | 运维状态需分开描述 |
4. 安全审查的优先区域
P0/P1 级边界
event_visible_to_reader与 fan-out 对所有 privacy kind 的对称性。- tenant/community 是否进入每个 SQL/key/advisory lock。
- NIP-98 URL canonicalization、proxy 与 replay。
- workflow webhook SSRF、header/secret 与 egress。
- Git repo path normalization、CAS retry 后 policy recheck。
- Pairing secret zeroize、transcript/SAS 与超时。
- Push generation/claim fence 与 provider 错误分类。
- Desktop Agent 工具权限、process tree 取消与 workspace boundary。
5. 性能审查的优先区域
REQ多 filter OR 与复杂 reader gate 的 SQL plan。- private membership recheck 的 cache hit/miss 和 invalidation 延迟。
- 热频道 fan-out 对 ConnectionManager 锁/队列的影响。
- Redis dynamic subscription churn 和 reconnect herd。
- Event partition/index growth 与 brownfield FTS rewrite。
- Git hydrate bytes、pack cache single-flight/eviction。
- ACP 多频道公平、单频道 backlog 与 provider latency。
- Desktop message virtualization 与 native event bridge。
6. 可维护性建议
以下是基于源码结构的推断性建议,不是上游计划:
- 从 kind registry 生成 Rust/TypeScript/Dart 常量、privacy matrix 和文档表。
- 建立“入口 × privacy kind × tenant/channel/global”的 conformance 矩阵,覆盖 WS/HTTP/search/live/count。
- 为每个 durable subsystem 写 machine-readable commit-point/repair runbook。
- 将 workflow action 完成度从 schema 中显式编码,禁止 UI 展示未接线 action。
- 在 brownfield migration state 中增加可查询版本/metric,而不是靠人工记住 FTS 差异。
- 持续拆分热点文件,但保持单一授权 orchestrator。
7. 总体评价
| 维度 | 观察 |
|---|---|
| 架构一致性 | 高:tenant、fence、post-commit、candidate-not-authority 贯穿多个子系统 |
| 安全意识 | 高:fail-closed、SSRF、零化、replay、generation、形式化资产丰富 |
| 产品广度 | 极高:协作、Agent、Git、媒体、Push、Mesh 同仓 |
| 实现复杂度 | 极高:权限和事件语义交叉,热点明显 |
| 完成度表达 | 中高:代码多处诚实失败,但根文档有漂移 |
| 运维门槛 | 中高:Postgres/Redis/S3/Push gateway/多客户端与 native sidecars |
Buzz 更像一套“Agent-native 协作操作系统内核”而非单一应用。它最有参考价值的不是把所有功能塞在一起,而是对跨租户、跨 pod、跨进程和长流程竞态使用了相对统一的正确性词汇。
8. 证据入口
ARCHITECTURE.md:与当前实现对比的基线。crates/buzz-core/src/kind.rs:协议/隐私复杂度集中点。crates/buzz-relay/src/handlers/ingest.rs:写路径热点。crates/buzz-relay/src/handlers/req.rs:读路径热点。crates/buzz-conformance/:独立安全模型。migrations/:实现演进而非静态目标。