Skip to content

09 · 频道、消息、线程与 DM

Buzz 的协作域不是单一 messages 表。事件承载跨端语义,频道/成员/线程/反应/DM 等关系表提供高效查询与权威权限。SDK builders 统一客户端构造规则,Relay ingest 统一服务端裁决,数据库 projections 统一读模型。

1. 频道模型

buzz-core::Channel 关键维度:

维度
visibilityopen / private
typestream / forum / dm / workflow 等
roleowner / admin / member / guest / bot

Bot 被刻意排除在普通角色层级比较之外。因为 bot 是主体类别,不是“比 guest 高/低”的权限等级;具体动作应显式允许。

频道 ID 在数据库中总与 community_id 配对。仅凭 UUID 查频道会把全局唯一性的偶然假设变成租户漏洞。

2. 管理事件与投影

Buzz 使用 NIP-29 风格管理事件表达创建、更新、加入、离开、角色和归档。Relay 接收后:

  1. 校验作者当前角色。
  2. 在事务中修改 channels/members 投影。
  3. 保证至少一位 owner 等不变量。
  4. commit 后发 discovery snapshot、membership snapshot/delta。

关系投影负责在线授权,事件负责跨端可观察历史。若两者更新不原子,刚撤权的成员可能继续通过旧投影写入。

3. 消息版本与语义

注册表同时存在 kind 9 和 V2 kind 40002。消息可以附带:

  • h 频道。
  • NIP-10 root/reply。
  • p mentions。
  • broadcast marker。
  • diff/repo/commit 元数据。
  • workflow actor/source attribution。

SDK builder 会做频道名/标记规范化、提及转 tag 等客户端便利工作;Relay 仍重新验证,不信任 builder 一定被使用。

4. 线程

回复的难点不是展示缩进,而是建立稳定 ancestry:

text
root message (depth 0)
  └─ reply A (parent=root, root=root, depth 1)
       └─ reply B (parent=A, root=root, depth 2)

Relay 从 marker 与 parent 推导 root,不允许客户端把另一个频道事件声称为 root。最大深度 100 防恶意超深链拖垮递归/查询。数据库保存 root/parent/depth 和计数,使 feed 与 thread view 不必实时图遍历。

5. 编辑与删除

编辑事件不是直接覆盖原始签名内容:

  • 编辑者必须是原作者,或是该 Agent 的 owning human。
  • 仍需对目标频道有当前访问权;“曾经有权”不够。
  • Relay 记录编辑关系/事件,由客户端展示最终版本与历史语义。
  • 删除使用 NIP-09 引用,数据库查询默认排除已删除目标,但审计/保留策略可保存必要证据。

6. Reactions 与论坛投票

Reaction 是签名事件,数据库投影聚合 (target, emoji, author),避免同一人重复计数。撤销会更新投影。

论坛投票比通用 reaction 更严格:目标必须是同频道 forum post/comment,方向限定 up/down。否则攻击者可以对任意事件制造看似合法的 forum score。

7. DM

DM 使用独立频道/事件 kind 和参与者投影。核心门是:读者必须是参与者,新增成员按 DM policy 授权;通用 p-gate 只是其中一部分,不能替代 DM membership。

DM 的“频道化”设计使:

  • thread、reaction、feed 等基础设施可复用。
  • community/tenant 隔离仍一致。
  • 多人 DM 可用成员投影演进。

但它也要求所有通用频道查询正确排除不应在普通 discovery 中出现的 DM。

Feed 基于可访问频道集合和消息 kind 生成 newest-first 视图;Search 使用 FTS 命中再 hydrate。两者最终都经过 reader visibility gate。不要把“能在 feed 看到”与“能用精确 ID 读取”做成两套权限。

9. Canvas、Notes 与 Diff

Buzz 把不同协作内容都映射到事件:

  • Canvas:频道级可替换 Markdown 状态。
  • Notes:NIP-23 long-form,d tag 是 slug/coordinate,可发布、更新、列表与删除。
  • Diff:结构化元数据 + 有界 patch 内容,链接 repo、commit、branch、PR。

它们共享签名、租户、频道、检索和订阅基础,但 ingest 规则不同。统一协议原子不等于取消领域校验。

10. Presence 与状态

Presence kind 20001 是短 TTL/ephemeral 在线状态;typing 20002 更短。NIP-38 status(如 30315)则是 parameterized replaceable 的用户声明,可以持久化。三者生命周期不同:

信号生命周期典型恢复
typing秒级不恢复
presence分钟级 lease周期刷新
status持久 replaceable查询最新 coordinate

11. SDK 与 CLI 的边界

buzz-sdk 提供 typed builders 和 protocol helpers;buzz-cli-core/buzz-cli 将其映射为脚本友好的 JSON 命令。CLI 覆盖消息、频道、reaction、DM、workflow、forum、notes、repos、patch/PR/issues、media、memory、moderation 等,是 Agent 使用 Buzz 的重要稳定表面。

CLI 从 stdin 读取消息/diff body 的路径也很重要:它避免 shell 对反引号、$var 和代码块做意外展开。

12. 源码入口

独立源码研究笔记 · 非 Buzz 官方文档