mcpField
D
Dibs

Dibs

本地服务
agenxy.orgAI 与智能体2今天更新

关于 Dibs

Dibs 为多个 AI Agent 提供协作看板、类型化消息和共享资源声明,帮助它们发现重复工作并交接任务。它记录协作状态,但不编排 Agent,也不阻止它们执行工作。

主要功能

  1. 01查看 Agent 正在进行的工作
  2. 02带期限和回执的类型化消息
  3. 03传递加密文件附件
  4. 04对路径设置建议性声明
  5. 05以加密哈希链记录历史

适用场景

  1. 01发现不同 Agent 正在重复处理同一目标
  2. 02向其他 Agent 提问并等待回复
  3. 03跨机器发送工作文件
  4. 04查看离线期间的协作记录

MCP 相关

Dibs 的 dibd 守护进程同时提供 MCP 服务和 Web 看板,供 Agent 连接并访问协作工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
mcpbdibs.mcpb0.0.16

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

README 配图

Dibs

CI Release Go Reference License: GPL 3.0 or later

让你的 Agent 随时了解彼此的动态。

你的 Agent 可以在这里查看其他 Agent 正在做什么,也能采取相应行动:发送带有截止时间和回执的类型化消息、传输文件、对共享资源提出建议性声明,以及加入主题空间。Dibs 负责汇报,但从不决定 Agent 下一步该做什么。它执行的三项操作,都是为了交付他人发来的内容:批准携带 grant 或 adopt 的 request 会应用相应变更,这正是批准它的目的;有邮件时,会通知已停止的 Agent。通知有三种方式:自有的 ChatGPT Agent 对话线程会接收原生应用通知(空闲时启动,运行时引导),然后才运行规范配置的队列路由;[wake.exec] 会为其他路由运行由操作者配置的投递命令;或者通过其运行环境发布的会话套接字发送尽力而为的摘要。收到匹配的原生回复表示输入已被接受;命令退出则表示该命令已运行。两者都不表示邮件已被读取。命令路由只携带事件,不会在任何用户均可读取的 argv 中包含参与者名称或私密正文;套接字则携带有大小限制的协调摘要。两者都不包含指令。原生应用通知会私密地携带事件和发件人,不包含邮件正文,也不会调用打开窗口的操作。ChatGPT 冷启动线程仍保留队列/打开应用的备用流程,该流程可能会跳转到应用;进入队列绝不意味着已通过原生方式投递。Claude 会话关闭后的恢复仍遵循独立的空闲策略。会话套接字由接收方自行决定如何处理:处于 bypassPermissions 模式的 Claude Code 会话会将对等方消息留给用户处理,且不发送回执,因此 Dibs 无法判断消息是被暂存还是已投递,也不会声称自己能判断。该暂存行为是接收方的默认设置,只需修改一个设置即可关闭;dibs doctor 会指出该设置,Dibs 绝不会写入它。这段说明过去写的是“它从不行动”,在上述功能出现前确实如此;后来改成了“只在你要求的地方行动”,但唤醒不再需要配置后,这句话也不再属实。

你打开了三个 Agent。一个正在重构会话存储。另一个在不同窗口中,也刚决定重构会话存储。它们彼此看不到对方,于是你为同一项工作付了两次成本,又要再花一次成本来协调。版本控制也帮不了你:冲突不在文件里,而在意图上;等问题体现在文件中时,浪费早已发生。

这正是 Dibs 要解决的问题,而且也是最小的问题。能够看到彼此的 Agent 还能移交工作、提问并等待答复、发送文件、商定由谁负责某个目录,以及查看它们未运行期间发生的事情。

一个看板涵盖所有连接到它的 Agent,无论你同时打开多少个项目,也无论它们分布在哪些机器上:dibd 默认绑定到环回地址;如果你希望同一看板上的其他电脑也能连接这些 Agent,则可将其绑定到 tailnet 或 LAN 地址。Agent 不与某个代码仓库绑定:没有任何东西会将它限制在某个项目中,声明使用绝对路径,邮件则发送给 Agent。每个 Agent 都会标注其正在处理的项目,因此分布在三个代码仓库中的 Agent 群组看起来是三组,而不是一列相同的行。如果你希望将两组 Agent 分开运行,也可以在独立的数据目录中运行第二个 dibd,两者之间互不共享数据。

Dibs 看板:五个 Agent、各自正在处理的工作以及尚待处理的事项

冲突是什么样的

两个 Agent 在不同窗口中,准备做同一件事。第二个 Agent 声明自己的工作,Dibs 随即回应:

// codex-1 → declare
{ "text": "Fixing session reconnect handling",
  "dirs": ["internal/session"], "refs": ["issue:1140"] }
{
  "ok": true,                        // nothing was blocked
  "slot_id": "s1",
  "overlaps": [
    { "agent": "claude-1", "signal": "same-objective", "kind": "slot",
      "text": "Reworking how the session store handles reconnects",
      "refs": ["issue:1140"] }
  ],
  "warning": "another agent is already pursuing the same objective: you are
    probably about to duplicate its work. Read its slot, then message it
    (question/handoff) to split or stand down. This is the measured failure;
    do not just proceed."
}

ok 为 true。Dibs 没有阻止任何事情,也无法阻止:它记录了声明,指出已经在处理该目标的同伴,并将决定留给两个 Agent。教程。

看板上还有什么

声明工作只是 53 个工具中的一个。其余工具用于 Agent 彼此可见之后的协作:

  • 邮件。 私人邮箱,分为四种类型(notify、question、request、handoff),支持送达回执、截止时间和附件。问题不会阻塞任何人:它会等待,也可以被拒绝。
  • 文件。 内容寻址的 Blob,静态加密,最大 64 MiB;可附加到消息,也可通过 ID 获取。不同机器上的 Agent 可以传递工作成果,而无需接触你的文件系统。
  • 声明。 对绝对路径进行建议性的 shared 或 exclusive 占用,并允许人工覆盖。建议性就是字面意思:不会强制执行。
  • 空间。 Agent 可创建、加入和合并的主题频道,支持要求确认的公告,以及用于管理成员的准入和移除。
  • 历史记录。 以上每项操作都会记录为加密、哈希链式账本中的一条记录,状态则是对账本进行纯折叠运算的结果。未运行的 Agent 可以查看错过的内容,而 dibs verify 可以证明记录未被篡改。

没有 Agent 能通过 Dibs 对另一个 Agent 采取行动。你收到的最糟情况也不过是一条可以拒绝的消息。它是一个可见性层,不是编排器。

Agent 需要你时

你和其他人一样,都是看板上的一员,因此 Agent 可以像联系同伴那样联系你。问题会作为通知发送到你自己的机器上,你可以在那里回答:无需终端,无需打开看板,也无需在工具中输入任何内容。

一个未解决的问题Agent 列出的回答选项
Agent 通过原生 macOS 对话框向人类提出自由文本问题Agent 提供一组选项供人类选择

如果 Agent 明确列出选项,你收到的就是一个按钮,而不是一句话:最多三个选项会成为通知自带的按钮,回答只需轻触一次。请求也以同样的方式运作,并会产生相应效果。request + grant: "coordinator" 会在你批准后将提问者提升为协调者;request + adopt: "<agent>" 会将旧邮箱交还给回归的 Agent。**批准就是执行操作,而不是留下一条说明有人同意应该执行该操作的备注。**之后永远不会有待你运行的命令。

这很重要,因为另一种做法会让你充当传递渠道。如果 Agent 必须等待人类注意到、打开某项内容并转达答案,那你就在替 Agent 承担这部分工作。

**两个 Agent 编辑同一个文件很正常,也无妨。**Dibs 并不会锁定你的源代码。它要避免的浪费是重复劳动:两个 Agent 追逐同一个目标。REQUIREMENTS.md 记录了一个定义本设计的实际事故。


目录:安装 · 教程 · 面向 Agent · 你将获得什么 · 发现重复工作 · 子 Agent 停止工作时 · 配置 · 安全 · 平台 · 设计 · 工程


安装

已列入官方 MCP Registry, 条目标识为 io.github.Agenxy/dibs。当使用方或 Agent 需要查找尚未获知的 服务时,会在这里查找:

curl 'https://registry.modelcontextprotocol.io/v0/servers?search=dibs'

两个静态二进制文件:dibd(守护进程、MCP 服务和 Web 看板)和 dibs (CLI)。两者均使用 CGO_ENABLED=0 构建,字节级可复现。无需数据库、Node 或运行时依赖。

macOS 二进制文件使用稳定的 Agenxy 身份进行代码签名,因此 macOS 会将不同 版本识别为同一个程序,而不是每次发布都识别为新程序:你授予一次的防火墙 许可或文件夹权限会持续生效。证书为自签名证书,这意味着 Gatekeeper 首次 仍会询问,spctl 仍会拒绝;只有 Developer ID 和公证才能消除这一问题,而 Dibs 目前还没有。签名是确定性的,因此对于持有相同证书的任何人,上述可复现 性都成立;其他人可以复现未签名的二进制文件,并比较除签名之外的所有内容。

Homebrew(macOS)
brew tap agenxy/tap
brew trust agenxy/tap
brew install dibs

Homebrew 6 拒绝加载来自未信任 tap 的 cask,因此第一行不可省略;省略后安装 会因信任错误而失败。每个 tap 只需执行一次。

agenxy/tap 是所有 Agenxy 项目共用的 tap,因此只有第三个组成部分会变。 agenxy/lanes/lanes 仍然有效:GitHub 会将旧仓库名称重定向,而 tap 会将旧的 cask 映射到这个 cask,因此重命名前安装的版本会在下次 brew update 时原位 升级。

会安装两个二进制文件。该 cask 会尝试在安装时清除 macOS 隔离标记:这些二进 制文件使用 cosign 签名以证明来源,但未经 Apple 公证;如果不执行此步骤, macOS 会在安装成功后拒绝运行它们,看起来就像产品损坏,而不是未经签名。

此操作不会被视为致命错误,因为在常见情况下 xattr 会以非零状态退出,而 因此导致安装失败,后果会比它所避免的警告更糟。所以,如果 macOS 仍提示开发 者无法验证,就说明操作未生效;运行 xattr -dr com.apple.quarantine "$(brew --prefix)/bin/dibd" 即可完成处理。若声称它总能生效,你就可能会遇到 文档称为不可能出现的对话框。

Go
go install github.com/agenxy/dibs/cmd/dibs@latest
go install github.com/agenxy/dibs/cmd/dibd@latest

Go 的模块代理就是它的包注册表:无需发布任何内容,也无需创建账户。任何带 标签的公开仓库都可以通过路径安装,并且 pkg.go.dev 会自动为其建立索引。需要 Go 工具链是个限制,因此这种方式更适合贡献者,而 非普通用户。

在 macOS 上,这种方式只能提供四个构件中的两个。 go install 会构建 Go 程序,而 Touch ID 助手是 Swift 程序,通知器则是应用包:缺少它们时,dibs web 会改为要求输入管理员密码,通知也会通过 osascript 以 Script Editor 的名称发送,且没有按钮。这两种情况都不会提示“安装方式有误”,所以这里特 别说明。dibs doctor 会报告这两项问题。如果你想获得完整功能,请使用 Homebrew 或发布归档;也可以按照从源代码构建中的说明,从 检出目录构建另外两个构件。

从源代码构建

工具链通过 mise 固定,因此在任何环境中,检出目录的 构建方式都相同。mise 不会读取尚未获准信任的配置文件,因此全新克隆后需要先 运行一条命令:

mise trust && mise install   # pinned Go/Task/lint/release toolchain
task install                 # build + install to ~/.local/bin

跳过信任步骤会导致 task build 失败,并显示 No version is set for shim: task;这看起来像是缺少安装,而不是配置未受信任。如果你不想使用 mise, go build ./cmd/... 只需要 Go 1.26.10,其中包含标准库的安全修复。在网络出 口受限的环境中,GOTOOLCHAIN=local go build ./cmd/... 可跳过工具链下载; 请使用已安装且已打补丁的工具链,因为较早的补丁版本可能可以编译,但仍会保 留安全问题。

不使用 mise 或 task

如果网络允许访问 Go 模块代理,却无法访问代理重定向到的对象存储,那么这两个工具都无法安装,报错看起来像是工具链损坏,而不是主机访问受阻。Dibs 本身仍然可以构建:它自身的依赖项可从代理解析,且每个构建步骤都是在此代码树中运行 go build 或 go run ./tools/...。

go build -o bin/dibd ./cmd/dibd
go build -o bin/dibs ./cmd/dibs
swiftc -O -o bin/dibs-presence internal/humanauth/presence_darwin.swift   # macOS
go run ./tools/appbundle -o bin/Dibs.app -daemon bin/dibd -presence bin/dibs-presence -version 0.0.0 # macOS

需要安装的产物有四个,而不是两个:dibd、dibs,以及在 macOS 上的 dibs-presence 和 Dibs.app。守护进程会根据自身可执行文件的位置解析后两个产物,因此它们必须放在守护进程旁边。如果只复制二进制文件,守护进程就会报告一个自己无法修复的故障。

接下来安装它们,这是单独的一步:上面的命令只会生成 bin/,所以在新机器上,这之前运行 dibd 会提示找不到命令;而在已有旧版本的机器上,则会运行之前构建的版本。

mkdir -p ~/.local/bin
rm -rf ~/.local/bin/dibs ~/.local/bin/dibd ~/.local/bin/dibs-presence ~/.local/bin/Dibs.app
cp bin/dibs bin/dibd ~/.local/bin/

在 macOS 上,还需要安装仅在该平台存在的两个产物:

cp bin/dibs-presence ~/.local/bin/
cp -R bin/Dibs.app ~/.local/bin/
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f ~/.local/bin/Dibs.app

最后一行会将应用包注册到 Launch Services。如果不执行,macOS 就不知道它的存在,并会拒绝授予通知权限;表现出来就是通知器不发布任何内容,并报告“cannot notify”。

还有两条安装规则不容易从命令中看出来:

  • 复制前先删除。 macOS 会根据 inode 缓存二进制文件的签名判定结果。用 cp 覆盖正在运行的可执行文件,会在新内容上复用 inode,之后每次运行都会被 SIGKILL,且没有任何提示;即使文件与可正常运行的文件逐字节相同也一样。先运行 rm 可以创建新的 inode。

  • 签名时设置标识符。 Go 工具链会将它们保留为 a.out:

    codesign --force -i org.agenxy.dibs.daemon -s - ~/.local/bin/dibd
    codesign --force -i org.agenxy.dibs.cli -s - ~/.local/bin/dibs
    

    -s - 是临时签名,构建时使用没有问题,但每次安装都会再次触发 macOS 隐私授权提示,因为系统会根据签名关联授权。运行 go run ./tools/signcheck 可了解如何一次性创建稳定标识,并避免这一问题。

在 macOS 上,task install 和 Homebrew 会注册应用的后台服务。若要手动安装,请改为运行 dibs configure --service。在 Linux 上,可以先运行 dibd & 体验一下,或者使用下方的 systemd 单元。然后:

dibs mcp-config          # print the MCP host config (add to e.g. .mcp.json)
dibs admin set-password  # only where Touch ID is unavailable: see below
dibs web                 # print the live board URL
dibs board               # the same board, in the terminal
dibs doctor              # what is quietly broken, and how to fix it

看板可以有名称。Dibs 本身不负责解析名称:这由 Remap(Agenxy 名称平面)负责。安装 Remap 后,dibs configure 会提示注册名称(remap set dibs http://127.0.0.1:4777/),将名称写入 dibs.toml 的 name 字段,之后看板就可以通过 http://dibs/ 访问:dibs web 会在地址旁打印该链接,守护进程也会接受此名称作为自身的来源地址。

Shell 补全

该二进制文件会根据 CLI 调度所用的同一动词表生成自己的补全脚本,因此补全内容不会与动词不一致(而且代码树中无需存放任何 Shell 脚本)。将脚本写入 Shell 加载补全脚本的位置:

dibs completion bash > /usr/local/etc/bash_completion.d/agents    # bash
dibs completion zsh  > ~/.zsh/completions/_dibs                 # zsh (a dir on your $fpath)
dibs completion fish > ~/.config/fish/completions/agents.fish     # fish
让服务持续运行

dibd & 会将守护进程绑定到启动它的 shell:关闭终端或重启后,整个集群都会失去看板。除非只是初步体验,否则请使用 init 系统运行它。

macOS(Dibs.app 后台服务):将已安装应用的服务注册为登录时启动,并在崩溃后重启:

dibs configure --service

macOS 可能需要你在系统设置 → 通用 → 登录项与扩展 → 允许在后台 → Dibs中批准。该命令会保留现有的看板目录和服务 PATH。对于不受支持的旧版设置,命令会在停止旧服务前拒绝执行。将守护进程移入 Dibs.app 可能需要重新授权一次“桌面”“文稿”和“下载”文件夹;命令会请求读取权限一次,而 dibs doctor 会报告测量结果。已请求不代表已获授权。在源码版和发行版的签名身份之间切换,也可能需要重新授权。

移除已安装的应用前,请运行 dibs configure --service --remove 取消注册其后台服务。这会保留看板及其目录固定设置。如果你已经移除了 Homebrew 应用,请通过 brew install --cask agenxy/tap/dibs 恢复,然后运行移除命令,再运行 brew uninstall --cask dibs。恢复应用时会短暂启动服务。残留的后台项目可以在同一个设置面板中关闭;doctor 会检测到已启用的注册项所指向的应用程序缺失。

Linux(systemd 用户单元):

dibs configure --service     # writes ~/.config/systemd/user/dibs.service
systemctl --user enable --now dibs

在始终开机的主机上,请阅读命令随后打印的那一行。 这两个单元都属于用户级,因此都会随你的会话而非机器启动:LaunchAgent 位于 gui/<uid> 域中,只有你登录桌面时该域才存在;systemd 用户管理器则会在你的最后一个会话结束时关闭。在笔记本上,这正合适。但在放在储物柜里、有人曾登录过一次的 Mac mini 上,这意味着看板在崩溃后仍会运行,却无法在断电后恢复。dibs configure --service 会说明这台机器使用的是哪一种,并指出改变这一点所需的唯一设置(自动登录,或 system LaunchDaemon;Linux 上使用 loginctl enable-linger);dibs doctor 会重新检查。

若要停止此数据目录对应的守护进程,且只停止它:

dibs stop

不要运行 pkill dibd。Dibs 的设计允许多台彼此隔离的守护进程在同一台机器上共存;按名称杀进程会关闭恰好共享该名称的任意集群。

第二台机器

这个看板是集群看板:其他机器上的 Agent 会加入同一个守护进程,并显示在相同的行中。无需再运行第二个服务,也无需复制任何内容。

使用集群为 Hub 命名的方式。 Dibs 不会自行记录每台计算机的身份:这由 Supgang——Agenxy 地址平面——负责,Dibs 会向它查询。在属于 Supgang 成员的机器上,Hub 是其对等节点之一,因此此处的操作会使用该对等节点的名称、标签或指纹,并解析 Supgang 当前为它签名的地址:

dibs mcp-config --board MacMarine
dibs mcp-config --board MacMarine:4790   # a hub on a port other than 4777

桥接器每次启动时都会再次查询 Supgang,因此看板会跟随 Hub 的地址变化;这台机器上的每个 Agent 也都会携带此计算机的 Supgang 身份——Hub 和所有其他成员都通过同一身份识别它。在没有 Supgang 的机器上,此处的操作会改用地址,这也是 SSH 转发所用的方式:

dibs mcp-config --board 127.0.0.1:4777

无论哪种方式,操作都会根据看板推导出数据目录,并打印每个步骤,同时填入实际路径。

该看板会有自己的数据目录,用于保存其机密信息。机密信息按看板划分,并从数据目录读取,因此,同时运行自己的看板的机器需要第二个目录;它的 ~/.dibs 仍属于它自己的看板。目录以地址命名,因此加入三个看板的机器会保留三个可区分的目录。 加入网络的机器上的 Agent 由那台机器唤醒,而不是由中枢唤醒:在那台机器上的 board 数据目录中放入一个 [wake.exec] 表,并使用相同的两个变量运行 dibs host-bridge。中枢决定何时应唤醒某个 Agent,并将要恢复的线程交给桥接程序;桥接程序运行这台机器的操作员编写的命令,并报告结果。使用相同变量运行 dibs host-bridge --service,会写入 launchd 或 systemd 单元,使桥接程序在注销和重启后继续运行。

无论 board 运行在哪里,你都能在自己的 Mac 上收到它的消息。 发给你的邮件(问题、审批请求、交接)会在运行 board 的机器上触发通知;一旦那台机器变成服务器,这就不是合适的位置了。在你的 Mac 上使用相同的两个变量运行人工中继:

dibs human-relay enroll    # once: makes a key in this Mac's Secure Enclave, asks the board's admin password
dibs human-relay           # one Touch ID, then your mail shows here and your answers go back

随后,board 会将邮件发送给中继,而不是显示在自己的屏幕上。你的答复由该密钥签名;它只有在 Touch ID 验证后才会签名,因此 board 能确认答复来自真人,而不是信任连接本身;批准会授予某种权限的请求时,需要用手指确认该项批准。中继永远不会持有 board 的密钥。论证见 docs/NETWORK.md §8。

如果中枢是明文的环回守护进程(这是默认设置),请将端口转发到它,而不是将它暴露给网络:

ssh -N -L <local-port>:127.0.0.1:4777 you@hub

两端彼此独立:4777 是中枢监听的端口,<local-port> 是这台机器上任意一个空闲端口;如果这台机器已经运行着自己的 board,该端口就不会是 4777。因此,DIBS_ADDR 应设为 127.0.0.1:<local-port>,也就是这台机器上的转发端。中枢始终不会离开环回地址,而且 ssh 会在 Dibs 接收到任何字节之前验证机器身份。这是受支持的传输方式,并非权宜之计:许多主机永远不会有可路由的地址,要求它们必须有这种地址只会无端排除它们。

可直接访问的中枢会通过它生成的证书提供 HTTPS,而桥接程序只信任加入机器记录过的证书。如果中枢的操作员已通过 Supgang 发布该证书的密钥(在中枢上运行 dibs fingerprint 会打印准确的 supgang advertise dibs … 命令;如果尚未运行该命令,在中枢上运行 dibs doctor 会告知你),则无需其他操作:运行中枢的计算机为该密钥签名,dibs mcp-config --board <peer> 会从 supgang resolve 读取该密钥,将中枢提供的证书与之核对并记录下来;如果两者不一致,则完全不会打印配置步骤。如果未发布该密钥,加入的机器需运行一次 DIBS_DIR=<that board's directory> dibs trust <host:port>,并将指纹与中枢上的 dibs fingerprint 输出进行比对。这里的 DIBS_DIR 不能省略:trust 会将证书记录在指定目录中,而桥接程序会从自身配置所指定的目录读取证书。mcp-config --board 会根据地址打印相应的步骤。

只需一次,而不是每年一次。 记录下来的是 board 自己的签名身份,而不是它今天碰巧提供的证书。守护进程会以该身份为自己签发短期证书;证书接近过期时,它会在运行期间自动更换,无需重启;如果证书不再包含客户端连接时使用的地址,则会在下次启动时更换。已经信任该 board 的机器可以一直正常工作。只有从 board 目录中同时删除 tls-ca.pem 和 tls-ca-key.pem,身份才会改变;这是唯一需要再次完成验证流程的情况。如果这两个文件只剩其一,守护进程会拒绝启动,而不会创建不完整的身份,因为这正是恢复操作只完成一半时留下的状态。 使用桥接器(mcp-stdio),不要使用 URL 形式。在另一台机器上,这一点尤其重要。两种传输方式的身份机制相同:register 会返回一个生成的 nonce,URL 客户端只要保留它,就能通过同一个调用重新连接。桥接器的额外作用是让它在整个会话期间保持有效,包括重启和原地升级,并能自行跟随守护进程重启;如果 URL 客户端丢失了 nonce,就会重新注册为一个同级参与者,无法读取前一个参与者的邮件,而远程会话正是那些长期运行、无人值守的会话。

桥接器会为每个 Agent 占用一个进程,这个数量值得提前了解,而不是事后才发现:在一台开发机上的测量结果显示,9 个空闲桥接器总共占用 72 MB,每个约占用 8 MB 和 13 个文件描述符,此外守护进程还会为每个桥接器持有一个长期连接和一个 goroutine。50 个 Agent 在开始工作前,适配器就大约要占用 400 MB。守护进程本身可直接通过 HTTP 提供 MCP 服务,因此连接到它并不需要这些开销;这些进程的作用另有其所在。桥接器就是会话:它能观测到 cwd、branch 和真实的 pid,而不是向一个不可能知道这些信息的模型询问;它是让下一轮重新连接到同一个 Agent 的密钥;它的退出则是看板得知 Agent 已退出的方式(SPEC §5.0)。URL 客户端为了省下 8 MB,放弃了这四项功能。刻意不让多个 Agent 共用一个桥接器:每个桥接器都承载一个身份和一个会话,复用桥接器会重新引入桥接器本来要消除的歧义。

请慎重选择中枢。运行守护进程的机器决定了整个 Agent 群是否有看板,而笔记本虽然看起来是个诱人的选择,却并不合适:它会休眠、会切换网络,而且最可能在任务执行过程中重启。通过转发连接到一台始终在线的主机才是正确选择。

在加入的机器上设置相同的 DIBS_ADDR 和 DIBS_DIR,然后运行 dibs doctor 检查。

一段 ChatGPT 对话

普通的 ChatGPT 会话可以通过 OpenAI 的 Secure MCP Tunnel加入看板;它会在你的机器上运行一条命令,并将对话中继到其中。不暴露任何内容:不会打开端口,看板的密钥由桥接器在本地读取。

tunnel-client run --mcp.command "dibs mcp-stdio --remote-session" \
  --control-plane.tunnel-id tunnel_…

**--remote-session 是必需的,不是可选项,也不是偏好设置。**如果不加这个选项,桥接器就会像处理这台机器上的所有其他工具一样,观测主机、工作目录、检出目录以及自身的 pid,并将这四项信息附加到 Agent 上。隧道具备这四项属性,而浏览器标签页一项也不具备。以这种方式注册的对话会显示为正在隧道启动时所在的目录中工作,还可能对它看不到的文件进行目录认领。加上该选项后,桥接器不会观测任何信息,并会明确说明这一点;守护进程则会记录一个没有关联机器的参与者。如果桥接器发现 ChatGPT 对话未使用该选项,就会向 stderr 打印警告。

该参与者可以执行所有协调类操作:查看成员列表、邮件、空间和请求,以及使用 declare 声明正在处理的工作,但不指定任何路径。它不能执行 claim,因为认领意味着声明自己正在某个目录中工作,这可能会阻止正在该目录工作的其他人。它也无法被唤醒:浏览器标签页没有可用的路由,因此它只能通过调用 check_in 来收取邮件,而不能由系统推送邮件。

升级运行中的集群

只需一条命令即可将守护进程切换到新版本,加上一个标志即可获取新版本:

dibs upgrade --check     # is there a newer release? changes nothing
dibs upgrade --fetch     # get it, prove it, install it, then do the move
dibs upgrade             # just the move, onto the build you already installed

--fetch 会验证发布版本校验和的 cosign 签名,根据摘要检查归档,并将完整载荷安装到这台机器运行的守护进程旁边:包括两个二进制文件、Touch ID 辅助程序和通知程序包。它会刻意拒绝三种情况。对于 Homebrew 安装,它会交由 Homebrew 处理,因为替换 brew 所管理的文件会导致 brew 与磁盘上的状态不一致,而下次执行 brew upgrade 时又会恢复旧版本。如果没有 cosign,它会拒绝而不是发出警告,因为与文件一同提供的校验和只能证明下载内容完好无损,无法证明是谁生成了它(如果机器确实无法安装 cosign,可以使用 --allow-unsigned)。如果 cosign 已安装但无法运行,则会报告缺少工具,而不是验证失败,因为两者的含义截然相反。

dibs doctor 会以警告形式检查同样的问题。没有任何操作会按计时器运行,守护进程也绝不会自行检查:Dibs 发出的每个网络请求都是由某人主动发起的,DIBS_NO_UPDATE_CHECK=1 也会阻止 doctor 发起检查。

本节其余内容介绍升级操作本身的行为,无论是否获取新版本。

我们特意不采用 dibs stop && dibd &,因为这样会悄无声息地引发三种问题。服务单元固定使用绝对路径,因此守护进程安装到新位置后,服务会永远启动数月前的旧版本。手动启动的守护进程会使用默认的环回地址,因此所有远程 Agent 都会从原本跨机器服务集群的看板上断开。若新二进制无法折叠旧版本写入的日志,也要等到停止了能够服务看板的守护进程之后才会发现。

因此,dibs upgrade 会先让新二进制检查日志(dibd -check,它会重放日志但不提供服务,可以安全地对另一守护进程当前正在使用的看板运行),只有检查通过后才会停止任何进程。然后,如果服务单元固定指向了错误的守护进程路径,它会更新该路径;有服务管理器时通过服务管理器重启,没有时则直接重启;恢复守护进程此前绑定的地址;并等待看板响应,然后报告它恢复时的序列号和 Agent 数量。如果停止后、启动前的任何操作失败,它都会再次启动刚安装的版本,等待看板响应(如果看板尚未响应,则会在旧进程退出的同时再次启动),并说明情况。这并不是回滚:不会保留旧二进制,因此如果问题出在新版本本身,请重新安装旧版本。

这一切都不需要 Agent 重新注册:state == fold(ledger),因此重启后的守护进程会重建看板,而不会丢失它;stdio 桥接会等待这段时间过去(REQUIREMENTS.md R12)。dibs upgrade -n 会说明它将执行哪些操作,但不会进行任何更改;使用 --fetch 时,它会在安装后停止,这样你可以先检查安装的内容,再让整个集群升级到新版本。

对于已安装并启用 dibs@dibs 的情况,升级还会通过 Codex 自带的安装程序安装此版本对应的 Codex 插件。插件更新失败会发出警告,并导致 dibs doctor 失败,但不会中断守护进程升级;运行 dibs codex-plugin install 即可修复。新对话和真正的应用刷新可以加载当前工具。已运行的对话会继续使用现有工具列表,直到对话结束或应用刷新工具列表。请参阅插件说明。

配置

Dibs 即使没有配置文件也能正常运行,而且大多数集群从不创建配置文件。守护进程接受的所有设置都列在 docs/CONFIGURATION.md 中,其中也说明了每项设置保持默认值时会发生什么。

遇到未知键时,守护进程会停止运行,而不会忽略该键,这是刻意设计的:从未生效的设置不能看起来像是已经应用。

man dibs      # the CLI
man 8 dibd    # the daemon: flags, files, what a restart costs
dibs doctor   # what is actually in effect right now
验证下载的内容

发布制品使用 cosign 以 Sigstore bundle 格式签名:签名、证书和透明日志条目都在同一个文件中;每个归档还附带一个 SPDX SBOM。

TAG=v0.0.1   # the release you downloaded
cosign verify-blob checksums.txt \
  --bundle checksums.txt.bundle \
  --certificate-identity "https://github.com/Agenxy/dibs/.github/workflows/release.yml@refs/tags/$TAG" \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com'

身份信息包含工作流和标签,因此必须与您下载的发布版本匹配。Verified OK 表示校验和文件由此仓库在该标签下的发布工作流生成。将下载的归档的 SHA-256 值与已验证文件中完全匹配的文件名进行比较。包含 guest CLI 证据的发布还会列出 members/<os>_<arch>/dibs:这些描述的是归档内的可执行文件字节,而不是单独可下载的制品。如果没有将解压后的可执行文件也放在这些路径下,直接运行 sha256sum -c checksums.txt 会报告这些成员路径缺失。

浏览器面板会显示解密后的邮件,并且可以代表您执行操作,因此它需要通过 Agent 无法满足的条件来设限:每个 Agent 都持有协调密钥,而没有任何一个是您。在配备 Touch ID 的 Mac 上,这道门槛由传感器把关,dibs web 会优先使用它:无需进行任何设置,也无需保存密码。

没有传感器可用时,您需要设置 admin set-password,也就是在 Linux、没有 Touch ID 的 Mac 上,或不在键盘前的会话中。无论如何都设置密码,可以提供一种不依赖硬件的访问方式;但这不是必需的,而且这种凭据比它所替代的凭据更弱。dibs doctor 会告诉您这台机器适用哪一种方式。

终端中的 dibs board 两者都不需要:它只会显示面板上的内容。

随后,Agent 会通过 MCP 工具进行协调:register → check_in → declare / claim / send / await_events。服务端的说明会教会 Agent 使用协议,因此无需其他文档。

刚接触? docs/TUTORIAL.md 用十五分钟带您走完整个流程:守护进程、两个 Agent,以及一次当场发现的重复工作冲突。

面向 Agent

如果您是连接到 Dibs 的 AI Agent,需要了解两件事,而这两件事都不在本 README 中。

  1. 连接时,服务端会教您使用协议。 它的 instructions 包含完整的调用顺序,每条错误信息都会附带指出纠正调用的 hint。调用工具无需查阅单独的文档。

  2. 读取一次资源 dibs://skills。 它位于协议之上:那些违反直觉的部分、看似成功的错误,以及与您预想不同的默认设置。它通过 MCP 提供,因此无需此仓库即可读取;也可以在此处查看 SKILLS.md。

以下问题最让 Agent 费时:

  • Agent 是一个 AGENT,而不是一项任务。 它的名称就是您的地址(reviewer,而不是 refactor-auth),因为发给任务名称的邮件读起来毫无意义。
  • 不带 slot_id 的 declare 会新增声明,而不是替换现有声明。调用四次,面板上就会显示您正在做四件事。
  • 认领过期并不意味着获得许可。 这表示协调已丢失,而不是其他 Agent 已完成工作。
  • 重叠分数低,并不能证明您是唯一参与者。 tier 0 的召回率约为 0.3。高分意味着“留意一下”;低分则说明不了什么。
  • 指定 parent 不会赋予您任何权限:必须使用父 Agent 通过 vouch_child 发放的 nonce 来证明血缘关系。
  • 如果您的运行框架支持接收原生投递,请使用它。 不要再用后台监视器重复实现。否则,dibs await 是备用方案:请保留它的游标和退出状态;SKILLS.md 说明了如何处理重启。

如果您是在开发 Dibs,而不是使用它,AGENTS.md 是地图,docs/ARCHITECTURE.md 是疆域,llms.txt 则为所有内容编制了索引。

移动文件

设置 DIBS_TOKEN 为你的注册令牌:

dibs put artifact.bin --json
dibs get sha256:<digest> -o downloaded.bin --json

对于受邀加入的公开看板,将 DIBS_ADDR 设置为其 HTTPS 来源地址,并将 DIBS_INVITE 设置为邀请凭据。将两项凭据保存在环境中,不要放在命令参数里。 JSON 成功响应会提供 blob ID 和大小(对于 get,还会提供目标路径);错误响应会提供 code、msg 和 hint,并以非零状态码退出。目标必须是新路径。字节票据绝不会打印。

上传会在连接中断后继续;下载会通过 Range 继续,并在发布目标文件前验证最终 SHA-256。 在第一阶段,未完成的上传不会在守护进程重启后保留;基于声明的哈希和大小实现重启续传 是另一个后续必需事项。没有 CLI 的主机可以使用 MCP upload/download 描述符;小文件仍可使用内联 put_blob/get_blob。 请参阅附件契约。

你将获得

  • 人们愿意打开的实时看板:服务端渲染、通过 SSE 实时推送(约 200 ms 内收到更新,无需重新加载页面)、支持深色/浅色模式且响应式,并在 /help 提供协议指南。没有框架,没有构建步骤,也没有打包文件:只有 htmx 和一个手写脚本。
  • 与看板风格一致的终端界面:dibs board 打开后会先显示一行集群汇总,然后显示 Agent、工作和认领;颜色含义与浏览器中一致。在管道、重定向、简易终端或 NO_COLOR 环境下,它会精确退化为原本会显示的纯文本,因此 dibs board | grep builder 可以正常工作,重定向后的 dibs doctor 也会生成可粘贴到问题帖中的文件。
  • 原生支持 MCP:53 个工具,可通过服务端说明和纠错错误提示实现自我引导,另提供资源、board 提示词,以及按需打开的 MCP Apps 面板。Dibs 面向 2026-07-28 无状态契约,同时也提供旧版 2025-11-25 路径。截至 2026 年 8 月,所有已发布的主机实际协商使用的都是该旧版路径 (见下文)。两者均可用;你无需进行任何操作。
  • 只追加、哈希链式账本:持久化内容本身就是审计历史。 dibs verify 会检查完整性;tail -f ~/.dibs/ledger.jsonl | jq 可监视 实时变化。
  • 如实报告存活状态:崩溃、挂起和无响应是三种不同的情况,并会分别报告。认领过期意味着协调失效,绝不代表“可以安全继续”。
  • 临时和持久 Agent:会话 Agent 会过期;常驻角色(审查者、夜间维护者)会以 dormant 状态休眠,保留持久邮箱,并可通过恢复会话唤醒。
  • 零配置安全:默认仅监听环回地址;将其指向可访问的地址后,它会生成自己的 TLS 证书。无需标志、VPN 或外部 CA。
  • 经过真实 Agent 测试:Codex CLI 会话完成端到端协调(注册 → 感知门控 → 认领并显示冲突 → 请求 → 给出理由后拒绝 → 长轮询唤醒 → 发送方读取答复),在 MCP 2026-07-28 接口上没有互操作障碍。

捕获重复工作

路径声明可以捕获容易检测到的冲突:两个 Agent 指向同一个目录。从 v1.2 开始,Dibs 还可以捕获真正会造成工作浪费的情况:两个 Agent 在不同文件中做同一项工作。

Agent 用自己的话声明正在做什么。Dibs 会结合代码库自身的文件布局和 git 协同变更历史,将其与正在进行的工作进行评分,并显示已经在做这项工作的 Agent,让他们能在重复投入发生前找到彼此:

alice: "I am reworking how the session store handles reconnects"
       → OPENED    reworking-how-session-store-handles
bob:   "looking at session persistence when the socket drops"
       → CONSIDER  reworking-how-session-store-handles   score 0.27
                   "read the agent, and join_space if it is the same job"

无需模型、下载或网络。这属于第 0 层,只读取文件名和提交历史。

评分只是建议,不会替你做决定。 默认值为 auto_join=declared:bob 会看到 alice 的 Agent,然后自行决定。只有存在共同的标识引用(pr:1231、issue:88 或协调键)时,Dibs 才会自动加入某个 Agent,因为这些引用指向一个实际存在的事物,而评分表示的只是相似性。第 0 层的召回率约为 0.3,精确率还不足以在未经询问的情况下转移某人的工作;此示例过去曾显示 bob 已加入,但发布版默认行为从未如此。若需要无条件加入,可使用 -match-auto-join always 恢复此行为。

调整设置

匹配会从第一个 Agent 注册时开始运行,每个代码库建立一个索引;守护进程会根据刚刚挖掘的历史记录,测量自身的通知阈值。无需启用任何功能。

默认关闭的是加入。join_threshold 默认为 0,除非你设置它,否则 Dibs 只会提供建议,绝不会转移任何人的工作:

dibs calibrate --repo .    # measures YOUR repo, prints two numbers
dibd -match-join <join> &  # notify is measured for you; set it only to disagree

-match-repo 仍可用于预热:它会在有人从某个目录注册之前为其建立索引,因此适合在登录时启动的守护进程,其他情况则毫无用处。

先停止任何已在运行的守护进程。 Dibs 不允许同一台机器上启动第二个守护进程,并会指出当前正在运行的那个。这是有意为之:两个守护进程意味着两块看板,指向不同看板的 Agent 无法彼此看到;每次调用仍会成功,而且两块看板看起来都正常。这正是 Dibs 要防止的故障,却变得无从察觉。如果你确实需要两个,请使用 -allow-parallel,并为每个守护进程指定自己的 -dir。有两个合理的用途:隔离你不信任的 Agent(参见 SECURITY.md),以及让某个客户端的 Agent 集群使用独立看板。请了解这样做的代价:分属不同看板的 Agent 完全无法彼此看到,因此在两边同时编辑同一个共享依赖项,正是 Dibs 原本能够捕获的冲突。出于这个原因,默认做法是使用一块看板,并显示每个 Agent 所属的项目。

更好的做法是将数值写入 dibs.toml,完全跳过这些标志;这正是它们的用途。

先校准。 跳过校准会让 join_threshold 保持为 0,这意味着 Dibs 会推荐空间,但绝不会加入任何空间。这是有意为之,因为在未测量阈值的情况下自动加入,会导致所有 Agent 最终进入同一个空间。在五个真实代码库中测得的校准阈值相差达 15 倍(0.022–0.327);不存在一个在所有情况下都不会严重偏离的默认值。

仔细阅读校准结果。如果结果显示只有很少相关工作能达到阈值,这表示匹配无法在该代码库中区分出差异:将 join_threshold 保持为 0,并采用建议的空间。它会明确说明这一点,而不是只打印一个数字,让你自行猜测。

实际效果如何
repositorycommitsrecall@5在惩罚性留出测试下
hermes-agent3100.214 → 0.3620.319
opencode2025-11-25;未重复此前的线协议测量已变更: 2026-10-18(UTC)的源码 501b15af2 为 SDK v2 重做了 MCP 客户端,并支持 2026-07-28 修订版(packages/core/src/mcp/client.ts,提交 cbe882367),会跟踪连接协商使用的是 2026-07-28 还是旧版 initialize 握手。已安装的 opencode --version 输出字面值 local,而非从该头部版本重新构建,因此尚未测量已安装会话协商的版本。源码检查和版本观察并非新的线协议测量
pi-mono源码为 2025-11-25;未测量已安装版本的线协议2026-10-18(UTC)的源码 1402973a 保留了自有 MCP 客户端(packages/mcp),其 LATEST_PROTOCOL_VERSION 仍为 2025-11-25。观察到的已安装版本 pi --version 截至 2026-10-18(UTC)仍为 0.84.2,并非从该头部版本重新构建;未测量 MCP 会话。Dibs 使用 plugins/pi
codex2030.124 → 0.196未测量

(历史索引、tier 0、不涉及模型之前 → 之后。使用 dibs calibrate --repo <path> -n 60 -skip 5 复现;惩罚性列对应 go test ./internal/overlap -run PunitiveHoldout -v。)

Recall@5 接近 0.3 并不意味着“问题已解决”。 这表示大约三分之一的声明中,正确文件位于前五名:足以让两个 Agent 有时进入同一空间,值得一用;但远不足以盲目信任。以 SPEC-CHANNELS §10.1 为准:低分绝不能证明两个 Agent 不会冲突。

这些数字是留出测试的结果,值得了解的是测量方式。 dibs calibrate 以提交说明作为查询,并以该提交变更的文件作为答案进行评估,这正是构建历史索引时使用的配对方式。天真测量时,这项变更将 recall@5 从 0.288 提升到了 0.815,MRR 则达到完美的 1.000:因为查询检索到了它自身所属的提交。现在,Calibrate 会将评估提交从索引中留出,生产环境也是如此:索引过去,预测当前。真实收益比掩盖它的数据泄漏小了一个数量级。

接下来的显而易见的质疑是近似重复:即使留出确切的提交,仍会留下描述同一工作的还原提交、后续提交和压缩后的提交系列。在这些代码仓库中,51–66% 的查询确实有另一条共享两个或更多重要词项的提交。因此,最后一列也排除了这些提交:排除所有与任一查询共享两个词项的提交,约占语料库的一半:与完全没有历史相比,收益仍有 +26% 到 +49%。幅度较小,但真实存在:近似重复对提升有所贡献,却并非提升本身。 TestHistoryGainSurvivesAPunitiveHoldout 通过断言验证了这一点,而不只是描述它。

响应中实际体现重叠的位置

两种机制,两把键。declare 的响应是主要集成入口,因此值得明确说明:

机制键还包含
精确信号:共享 refs: 条目、共享目录overlapswarning
评分器匹配:相关工作之间没有共享字面信号spacesspaces_hint

两者相互独立:一条声明可以产生其中任意一种、两种,或都不产生。 overlaps 无需索引或阈值,因此在首次声明时即可工作,也适用于不同机器。spaces 则需要先为代码仓库建立索引,并将 notify_threshold 设为大于零;守护进程会自行测量该值,并在索引仍在构建时报告 matching: "indexing"。

一名集成 Dibs 的操作人员记录了 overlaps 和 suggestions,连续三次看到空结果,便断定匹配功能失效了。实际上,匹配功能正常运行,并将结果写入了 spaces;没人告诉他们要读取这个键。

语义匹配

楼层无需模型。若要关联既没有共同词语、也没有共同历史的工作,可以让 Dibs 指向一个嵌入服务:只需一个端点,因此 MLX、llama.cpp、Ollama 或托管 API 都能满足要求:

pip install mlx mlx-embeddings
contrib/embed-sidecar/dibs_embed.py --repo . --port 8737
dibd -match-repo . -match-join 0.33 -match-embed-url http://127.0.0.1:8737

如果辅助服务缺失或响应缓慢,系统会降级为内置评分器,并在它促成的任何成员关系上记录 degraded:匹配效果会变差,但不会停止。

依赖之前,请先了解规模上限。 索引按每约 40 行划分一个分块:本仓库有 855 个分块,使用本地 Ollama 需要约 110 秒。一个有 7,400 个文件的仓库生成了 58,710 个分块,服务在处理中途耗尽资源。Dibs 回退到 tier 0,并如实说明了这一点;但这并不等同于正常匹配,因为 tier 0 无法关联既没有共同词语、也没有共同文件历史的工作。如果仓库很大,可以用 -match-repo 预热一个子树,而不是整个目录树。

匹配会自行建立索引

无需进行任何配置。每个 Agent 都会注册一个工作目录,而包含它的仓库正是值得挖掘的历史记录,因此每个目录树都会在 Agent 首次出现在其中时建立索引,最多可为 16 个目录树建立索引。

每个仓库建立一个索引,并根据 Agent 所在的目录树为其评分。针对另一个项目的语句询问共同变更模型时,模型不会拒绝回答;它会自信地给出错误答案,这比完全不匹配更糟。若 Agent 所在的目录树尚未建立索引,它就不会收到语义建议,但仍会收到共享引用和共享目录信号;这些信号由核心计算,无需索引。

对于在登录时启动、并应在首个 Agent 到来前准备好索引的守护进程,-match-repo 仅用于预热。

系统会识别在不同目录树中工作的 Agent,此时匹配器会拒绝声称有证据,而不是凭空捏造;毕竟两个无关项目唯一共有的文件,就是每个项目都有的那些文件。dibs doctor 会指出已建立索引的仓库,并在你于其外工作时发出警告。为多个仓库建立索引的功能见问题 #7。

选择模型

检索模型具有非对称性:任务描述和代码块并非同类文本,而每个经过认真训练的模型都会通过标记说明当前输入属于哪一侧。Dibs 会根据模型名称自动应用正确的标记。标记错误造成的影响,比选择较小的模型更大:

评分器(在此仓库上)recall@5MRR达到门槛的相关工作
snowflake-arctic-embed20.5510.80753%
内置(无模型)0.2840.54250%
qwen3-embedding:0.6b0.5080.76049%
qwen3-embedding:4b0.5620.82642%
nomic-embed-text0.5260.75236%

同一个 4B 模型,不加标记时的得分是 22%:只有一半。大四倍的模型无法找回输入中从未编码的区别。标记错误更糟:arctic-embed 使用其模型卡未指定的文档前缀时得分为 42%,移除该前缀后则为 53%。

因此,Dibs 按模型而非按系列设置标记。一个系列内部的模型并不一致,而且这些差异无法从名称中看出:

  • BGE 需要四种不同的处理方式。bge-large-en-v1.5 需要经过训练的英文指令,bge-large-zh-v1.5 需要不同的中文指令,bge-m3 的文档说明它不需要任何标记,而 bge-code-v1 / bge-en-icl / bge-multilingual-gemma2 需要 <instruct>…\n<query>…。
  • arctic-embed 在 v1 和 v2 之间更改了前缀。只差一个版本,来自同一厂商,但两种字符串毫无相似之处。
  • e5 会为两侧都加标记,唯独 e5-mistral-7b-instruct 采用指令风格,并明确说明文档不需要标记。

Dibs 只采用模型卡明确说明的约定。对于无法识别的模型,它会发出警告并以对称方式处理:这种情况可以补救,不会像自信地使用错误标记那样有害。请在自己的仓库上进行测量,不要盲信此表;这正是 dibs calibrate 的用途。

当子 Agent 停止工作时

一个 Agent 派生另一个 Agent(codex exec、嵌套的 claude、一次 opencode 运行)时,最终只会收到一个信号:退出代码。此前的一切都是沉默,而沉默有四种从外部看起来完全相同的原因:子 Agent 正处于一轮处理中;它被权限提示阻塞,无人响应;它卡在了套接字上;或者设备合上了盖子,根本没有任何任务在运行。
在一台机器上测量两个并行运行的 codex exec 进程:

  alive 22m     CPU 19.6s   1.5%: working, producing output
  alive 7h39m   CPU  0.11s  0.0004%: did nothing since it started

第二个进程的父进程因此被阻塞了 7 个半小时。

随时查询:

dibs probe --pid 48620
pid 48620: stuck: alive 7h40m and has used 100ms of CPU in all of it
(0.0004% busy): it has done nothing since it started

也可以让系统主动告知你。dibd 每 20 秒扫描一次;当子 Agent 卡住时,它会向派生该子 Agent 的 Agent 发送通知,并在该 Agent 下一次 check_in 时送达,无需 Agent 主动查询。只要运行环境允许,归属信息会在派生时确定:在 Claude Code 中,PreToolUse 钩子会用父 Agent 的信息标记命令,操作系统会将该信息传递给所有后代进程,即使进程发生分离、守护进程化和重新托管也不例外;这些情况会让进程祖先关系失效。Codex 没有可供 Dibs 使用、又无需派生子进程的钩子,而 Dibs 不会派生子进程,因此子进程应改为调用 vouch_child,并使用 nonce 注册。

它只报告,绝不采取行动。codex exec resume 虽然存在,但 Dibs 不会调用它:父 Agent 清楚子 Agent 的用途,也知道重新运行是否安全。会悄悄修复问题的监督程序,既不会让操作者有所了解,也会掩盖可能具有系统性的问题。Dibs 会返回命令;是否运行由你决定。

**睡眠不算沉默。**经过时间以单调时钟衡量,因此合上设备盖子不会导致整个 Agent 群被判定为卡住:在开发机器上,自启动以来的最近 80.3 小时中,有 8.45 小时处于睡眠状态。系统会告诉你“已清醒但沉默 3 分钟;设备另有 38 分钟处于睡眠状态”,而不是“沉默 41 分钟”。

设计与测量结果:SPEC-SUPERVISION.md。

配置

设置保存在 <dir>/dibs.toml 中,而不是命令行上,这正是这样设计的原因:你测定的阈值不应该每次重启都得重新输入。

[match]
repo = "/path/to/repo"
join_threshold = 0.327      # from `dibs calibrate`
notify_threshold = 0.163
embed_url = "http://127.0.0.1:8737"
embed_model = "qwen3-embedding:0.6b"
# retrieval markers are inferred from the model name; set these only for a
# family Dibs does not know:
# embed_query_prefix = "query: "
# embed_doc_prefix   = "passage: "
# a bearer token is NOT a config key: export DIBS_MATCH_EMBED_KEY instead

[limits]
agent_ttl = "5m"                 # how long an agent that gave a PID may go silent
idle_ttl = "45m"                # ...and one that did not: probably you, see below
blob_store_bytes = 1073741824   # 1 GiB: hard cap on the attachment store

[supervise]
min_age  = "10m"   # how old before a whole-life idleness verdict is allowed
min_duty = 0.0005  # CPU share below which a long-lived process counts as idle

[roles]
# Standing roles. The daemon grants these at startup and re-applies them as
# agents register, so a role survives a board reset instead of having to be
# re-granted by hand.
coordinator = ["orchestrator"]   # broadcast, force-release, merge, evict
admin       = ["fleet-lead"]     # all of that, plus reading every agent's mail

[roles.identity]
# REQUIRED, and this is the half that makes the block above safe. A name
# authenticates nobody: any agent may register as "fleet-lead". Each entry is
# the FINGERPRINT of the agent allowed to hold that name, which `register`
# returns as `fingerprint` and the daemon prints at startup for you to paste. Never the nonce
# itself, which is that agent's whole recovery credential.
orchestrator = "…64 hex characters, from the startup log…"
fleet-lead   = "…64 hex characters…"

在配置中声明角色是由人做出的决定。 任何 Agent 都不能提升自己的角色:grant_role 不是 MCP 工具,只能通过守护进程的管理路径授予;如果系统操作使用 Agent 令牌,则会被直接拒绝。该文件之所以具有权限,是因为它由你掌控:Agent 无法通过 Dibs 访问它,也无法要求 Dibs 代为访问。

手动授予仍然可行(dibs admin coordinator <agent>),但它会随着所在的账本一起消失。如果一个团队重置了协作板,却悄无声息地变得没有任何人能合并两个发生冲突的 Agent,这正是此设计要避免的故障。

任何未设置的选项都会保留默认值;若只想临时覆盖配置文件,可使用标志。

对你适用的是哪种 TTL 并不显而易见。 agent_ttl 管理已注册 PID 的 Agent,这类 Agent 的死亡状态可以直接检查,因此可以安全地使用较短的租约。idle_ttl 管理未注册 PID 的 Agent,此时沉默是唯一的判断依据;而人类节奏的 Agent 在轮次之间本来就会沉默,因此默认值为 45 分钟。dibs mcp-config 输出的 MCP 配置是一个普通的 HTTP 客户端,不会注册 PID。如果你设置了 agent_ttl 却发现毫无变化,原因就在这里:请设置 idle_ttl。

设置 agent_ttl 前值得仔细考虑。任何经过身份验证的调用都会续期 Agent 的租约,因此频繁调用的 Agent 几乎不会触及期限;但执行长时间构建或缓慢测试套件的 Agent,在此期间不会调用 Dibs,而崩溃的所有者会 释放其独占 Agent。请将它设为长于你最长的静默步骤,否则忙碌的 Agent 可能会失去自己仍在使用的 Agent。如果你希望更早发现崩溃,则可调低该值。

blob_store_bytes 是一个硬性上限,而非目标值:存储超出上限时,系统会驱逐消息仍在引用的内容,而不是突破上限。收件方随后会收到 E_BLOB_EVICTED:这会明确说明问题并非访问权限,而且内容确实已丢失;但产物终究还是没了。如果你的 Agent 团队会交换大型构建输出,请调高此值。

Dibs 会写入磁盘的内容
  • ~/.dibs/:数据目录,包含账本、密钥和 Blob。使用 -dir 移动它。
  • ~/.dibs-run/:每个运行中的守护进程对应一个小文件,以便第二个守护进程知道自己并非唯一实例,而且 dibs doctor 可以报告团队分散在两个协作板上。 此处没有任何持久数据;守护进程退出时会删除条目,崩溃留下的条目会被检测为已失效并清理。它有意不放在数据目录中,因为这样才能发现数据目录位置未知的守护进程;它也有意不放在 $TMPDIR 中,因为 shell、launchd 作业和沙箱中的该目录各不相同:两个值不同的守护进程会彼此发现不了。

安全

让你不信任的 Agent 连接到同一个守护进程之前,请阅读 SECURITY.md。 信任边界是这台机器:所有 Agent 共用一个协调密钥,因此 Dibs 能保护你免受其他用户和网络的影响,并提高你自己的某个 Agent 能获知另一个 Agent 信息的门槛(但无法彻底阻止)。对于任何你不信任的对象,请运行第二个守护进程。

协议版本

Dibs 支持 MCP 2026-07-28(无状态核心)以及旧版 2025-11-25 路径,并会响应客户端提供的任一版本。两者的工具行为相同。

调查数据于 2026-10-18 (UTC) 更新。源代码判断基于获取的 origin/HEAD,而非本地分支。已安装版本另行检查;获取代码检出版本并不会重新构建其工具。源代码发现反映的是项目的发展方向,而非已安装会话的实际行为。如果没有进行新的协议线测量,表格中的行会保留较早的协议线日期。 在 v0.0.15 发布前,于 2026-10-22(UTC) 重新检查:Codex(342ed69a1)、opencode(248bfbe11)、pi-mono(58c0b02c)、Gemini(09d81bf)和 Hermes(4e58c721c8)的最新提交均有变动;ext-apps 没有变动。以下所有判断条件均未改变:opencode 的 2026-07-28 客户端和 Hermes 的 mcp==2.3.0 固定版本已于 2026-10-18 记录。已安装的 ChatGPT 应用版本为 26.1013.40934,应用 CLI 版本为 0.163.0-alpha.10.2(仅观察到该版本,未重新测量);其他已安装版本均未改变,因此各行保留 2026-10-18 的记录。

测试环境协议证据源码和已安装版本证据
Claude Desktop2025-11-25;2026-09-15 在 1.52386.6 上测得其聊天和本地 Agent 客户端发送的是 initialize,而不是 server/discover。**2026-10-18(UTC)观察到的已安装捆绑包版本:2.26454.2;未重新测量线路行为。**仅读取了捆绑包元数据;未打开或重启应用。重新测量需要重启应用,并添加一个临时的应用级 Dibs 条目来覆盖 Code 插件,因此仍暂缓进行。聊天界面没有生命周期钩子。参见 plugins/claude-desktop
Codex2026-07-28 配置的 stdio,2026-10-03 在应用 CLI 0.159.2 上测得;旧版默认行为最后一次测量于 2026-09-12检查的源码于 2026-10-18(UTC)位于 8c076942c,仍保留 CoreHookMcpExecutor(codex-rs/core/src/hook_mcp_executor.rs)和 mcp_2026_07_28 标志,该标志仍处于 UnderDevelopment 状态且默认关闭。stdio 仍需要为每台服务单独设置 CODEX_MCP_PROTOCOL_VERSION。0.159.2 探测发送了 2026-07-28 版的 server/discover 和 tools/list,没有自动发送 resources/list。隔离环境中经审核的钩子信任控制各触发了一次 SessionStart 和 Stop(守护进程轮询两次);完全相同的不受信任测试样例触发了零次轮询。这证明了钩子执行,而非已注册邮件的发送。**2026-10-18(UTC)观察到的已安装应用 CLI 版本:0.162.0-alpha.17.2(ChatGPT 26.1007.71326);未重新测量其线路行为或钩子。**PATH 中的 codex --version 仍报告 0.0.0,这是另一个本地二进制文件。MCP 工具审批(requires_mcp_tool_approval)仍会将缺失的注解视为具有破坏性且采用开放世界假设,因此每个 Dibs 工具都会声明其提示信息。codex_apps_mcp_2026_07_28 仍仅控制由宿主管理的 apps 服务,不控制 Dibs。参见 plugins/codex
opencode2025-11-25;未重复此前的线路测量**已更改:**2026-10-18(UTC)的源码 501b15af2 包含经过重构、适用于 SDK v2 和 2026-07-28 修订版的 MCP 客户端(packages/core/src/mcp/client.ts,提交 cbe882367),会跟踪连接协商的是 2026-07-28 版还是旧版 initialize 握手。已安装的 opencode --version 报告的字面值为 local,并非从该提交重新构建,因此未测量已安装会话实际协商的内容。源码检查和版本观察不构成新的线路测量
pi-mono源码中的版本为 2025-11-25;未测量已安装版本的线路行为2026-10-18(UTC)的源码 1402973a 仍保留自己的 MCP 客户端(packages/mcp),其 LATEST_PROTOCOL_VERSION 仍为 2025-11-25。2026-10-18(UTC)观察到的已安装 pi --version 仍为 0.84.2,并非从该提交重新构建;未测量 MCP 会话。Dibs 使用 plugins/pi
Gemini CLI通过 httpUrl 使用 2025-06-18;2026-09-12 测得线路行为2026-10-18(UTC)观察到的已安装版本仍为 0.54.0-nightly.20260722.gf743ab579;此前发现该 7 月版捆绑包不包含 BeforeAgent、GEMINI_SESSION_ID 或 hook_event_name。2026-10-18(UTC)检查的源码 ed96fae 仍定义了命令/运行时钩子类型。源码中包含已填充的 session_id/转录文本输入,并分发了 BeforeAgent 附加上下文;本次调查仅对已安装捆绑包进行了版本检查。Dibs 的 插件 仍仅支持命令/SessionStart
Hermes已安装适配器使用 2025-11-25,2026-10-03 测得,并非完整模型会话2026-10-18(UTC)观察到的已安装 Hermes 仍为 0.20.2 (2026.8.16);2026-10-07 的元数据查询发现其解释器中使用 MCP SDK 1.28.1。2026-10-03 的适配器探测将最新版本和握手版本设为 2025-11-25;针对隔离的守护进程,它发送了 initialize、notifications/initialized、tools/list,并返回已安装服务的发现数量 52。未测试新的线路行为或模型/提供方会话。**已更改:**2026-10-18(UTC)检查的源码 3752497cc4 现固定使用 mcp==2.3.0(此前为 2.0.0);该源码并非已安装环境中的源码
相关的 ext-apps checkout 也已获取:82221c0,软件包 2.0.3,获取时间为 2026-10-18(UTC),自 2026-09-25 起未有变化。其源码声明了拆分后的 client/core/server 2.0.0 对等依赖,并明确包含一项与已发布 1.x 版本的互操作测试。这是对扩展源码的观察,不是对已安装主机渲染的测试。

配置 Codex stdio 需要同时设置两部分。 源码仍将此功能标记为开发中,且默认关闭。单独设置该标志会让 stdio 继续使用旧版 2025-06-18;每服务器版本设置了错误的非空值时会报错,而不是回退。dibs mcp-config 会输出这两部分:

[features]
mcp_2026_07_28 = true

[mcp_servers.dibs]
command = "/absolute/path/to/dibs"
args = ["mcp-stdio"]
env = { CODEX_MCP_PROTOCOL_VERSION = "2026-07-28" }

名称相似的 codex_apps_mcp_2026_07_28 不能替代它。通过 HTTP url,在 2026-09-12 的测量中,仅启用 Dibs 功能就协商出了现代发现机制;上面的环境变量 opt-in 才是 stdio 的规则。资源工具可以执行实际读取,但协议版本不保证会自动列出资源。

**如果你是阅读本文的 Agent:**不要修改操作员的运行环境配置。只需提及一次相关限制,然后继续;Dibs 同时支持两种路径,你自己的工具调用也不依赖迁移。

云端 Worker

**来宾访问已发布,但尚不受支持。**在后续版本设置支持该功能的桥接器最低版本之前,邀请仍会保持 INCOMPLETE。目前尚未验收任何已安装的云端运行环境或广域网部署;以下说明描述的是已实现的范围,而不是可直接使用的配置指南。

不要将看板的共享密钥放进云容器。仅需配置一次仅限邀请的监听器:dibd --public-url https://board.example.com,并在 TLS 代理后将请求转发到环回地址 127.0.0.1:4778,而不是私有看板端口。或者使用 --public-host board.example.com --acme-accept-terms,并确保 ACME 可通过公共端口 443 访问。该显式标志表示操作员接受 CA 条款;本地尚未测试实际证书签发。

本地 Agent 调用 invite(token) 来签发 Worker 及其可直接粘贴的配置。默认策略允许四个活跃子项、以自身 ID 为前缀的名称,以及七天有效期;协调器可以选择新的非特权名称。CLI 使用 DIBS_TOKEN 获取相同权限(dibs invite <name>);若未设置,则必须由人工证明管理员访问权限。请在云网络允许列表中放行配置中的主机。使用指定名称和你保留的 nonce 注册,并妥善保管返回的 Agent 令牌。公共接口仅包含 POST /mcp 和受限的 /files/ 能力,始终通过远程方式提供且仅支持拉取;它绝不会暴露私有看板路由或 hub 路径。使用 dibs invite revoke <name> 或 --issued-by <issuer> 撤销;关闭签发者也会撤销其子项。部署与范围。

**如果你是操作员:**无需着急。Dibs 同时支持两种路径,全部 53 个工具在两种路径上的行为完全相同;自 2026-07-28 发布之日起,已弃用功能至少保证支持十二个月。

对 Dibs 而言,实际影响是:旧路径承载关键功能,而非遗留功能,移除它会导致所有当前主机无法使用。

Dibs 实现的 2026-07-28 核心功能

已通过运行中的守护进程验证,而非假设:

  • 无需握手。 tools/list 和 tools/call 无需任何 initialize 即可运行,这正是无状态核心的意义所在。
  • 支持 server/discover,用于获取能力和说明。
  • 每个请求都可指定协议版本和客户端身份,可通过标头或 _meta 传递。
  • 确保握手与无状态模式的区分名副其实。 initialize 只协商握手能够承载的版本;如果客户端在其中提供 2026-07-28,服务端会回提 2025-11-25,而不是达成一致,因为该修订版已废除握手。参考 SDK 也体现了相同的区分(HANDSHAKE_PROTOCOL_VERSIONS 与 MODERN_PROTOCOL_VERSIONS)。
  • 列表结果可缓存:server/discover、tools/list、resources/list 和 resources/read 都支持 ttlMs 和 cacheScope。Dibs 需要重新获取的内容比大多数服务端更多:它有 53 个工具,其说明包含实际的纠错细节;一旦没有会话来保存这些内容,每次冷启动路径都会重新获取。静态结果的提示缓存时间为一小时,并标记为 public;看板的提示缓存时间为两秒;Agent 的邮箱是 private,因为若设为 public,共享网关就可能把一个 Agent 的邮件提供给另一个 Agent。
  • 两种路径都支持 订阅(SEP-2575),客户端可立即获知变化,而不必等到 TTL 到期。

平台

本项目已验证可在 macOS 上运行。 所有测试、端到端测试套件和 CI 门禁都在 macOS 上运行;这就是 v0 对支持范围的真实表述。

Mac 仅支持 Apple 芯片。 Apple 正在终止对 Intel 的支持,因此发布的 Mac 归档文件和 Homebrew cask 均为 arm64:Intel Mac 必须从源代码构建,这种方式可行;go install 则可安装两个 Go 二进制文件。Linux 同时提供 amd64 和 arm64 版本。

每次推送都会编译 Linux 和 arm64 版本;自 2026 年 9 月起,整个测试套件也会在 CI 的 ubuntu runner 上运行,并启用竞态检测器:这就是对“Linux 上能否运行”的回答。首次运行发现了两个问题(一个信任 inode 编号的仓库身份缓存,而 ext4 会重用这些编号;另一个是 ps 列会将处理器时间四舍五入到整秒),两者都已修复。Dibs 的大部分代码都是普通的可移植 Go 代码,不受平台影响。需要特别处理的平台相关部分是 internal/liveness:它通过检查其他进程来判断派生出的 Agent 是否仍在工作;在 Linux 上,它读取 /proc;在 macOS 上,它会用 BSD 拼写调用 ps。Linux 作业未覆盖桌面端:Linux 通知器 notify-send 在 CI 中通过桩程序进行测试,而非通知守护进程。协调功能(Agent、认领、邮件、看板)均不依赖这些机制。

Windows 可成功构建并通过 vet;纯代码包(状态机、账本、看板配置、评分器和存活性解析器)会在 CI 的 Windows runner 上运行。Windows 上的首次运行表明状态机存在问题:认领路径使用平台的分隔符进行清理,导致两个 Agent 被授予同一个文件。现在无论主机是什么,认领路径都会统一使用 /,这也正是需要在另一台机器上重放账本时所需的行为。守护进程的锁使用 LockFileEx,存活性检查会询问内核某个 pid 是否仍在运行;树中的其余部分(守护进程、CLI、端到端测试套件)尚未在 Windows 上运行,也没有 Windows 测试框架注册过 Agent。这只是构建情况,并不代表支持承诺。

欢迎提交针对这两个平台的补丁;CONTRIBUTING.md 说明了所需的验证证据。

设计

docs/ARCHITECTURE.md 是实用版:各部分如何协作、验证应放在哪里、哪些条件必须始终成立,以及这里反复出现的四类 Bug。修复问题前请先阅读:通常有用的问题不是“这段代码做什么”,而是“它本该做什么”。

完整设计见 SPEC.md:v1.1,持续演进:已提交而非冻结,并经过五轮外部对抗性审查加固。简而言之:纯状态机上的单写入者事件循环,命令来源写入经 fsync 的哈希链 JSONL 账本;一个单调递增的序列号为所有事件建立全序;重放结果精确一致(state == fold(ledger)),因此整个系统都可以确定性地模拟:测试套件驱动随机的操作/时间序列,并断言重放结果等价。

工程

固定 Go 工具链(mise),golangci-lint v2,零警告,处处启用 -race,基于属性的重放测试,GoReleaser 搭配可复现构建、cosign 和 SBOM。task ci 会运行完整的本地门禁流程,与 CI 运行的内容相同。

.golangci.yml 中的复杂度上限采用有明确名称和理由的例外,而不是一概屏蔽:分派表(状态机的一个 Apply switch、MCP 工具 switch、CLI 动词 switch)得分较高,因为分派表本质上就是分支;拆分它们会掩盖读者需要检查的穷举性。每个例外都会说明涉及哪些函数以及原因;gocognit 在其他所有地方仍会生效,而且它在 spaces 工作中发现了四个确实需要拆分的函数。

端到端测试套件通过真实 HTTP 对真实守护进程运行,浏览器端则通过真实 Chrome 测试:panel(89)、web(101)、space(106)、guard(36)。四者都包含在 task ci 中,同时还有 sidecar 自测、人类工作流测试套件和备用的 dibdev 构建。

space 测试套件会测量自身的加入门槛,而不是将其写死,因为它断言的分数是根据此仓库的 git 历史计算出来的,因此每次有人提交都会变化。固定门槛在失效前都能通过,失效后却会因为贡献者无法采取行动的原因而失败。

除此之外,internal/mcp/e2e/fleet_scenario.py 会运行一支真实的 Agent 队伍。Codex、opencode 和 pi 会话使用真实模型,通过 Dibs 协调,同时还有一位人在看板上操作(37 项检查)。它有意不纳入 task ci:模型调用会产生费用,也依赖服务提供方是否可用。之所以进行这项测试,是因为其他所有测试都通过 Dibs 自己的客户端代码来驱动它;而这无法回答一个真实的测试框架在真实模型自行选择调用内容时,是否确实能协调工作。

贡献

欢迎提出批评,包括认为设计有误的批评:大多数决策背后的推理都有记录,因此可以针对具体内容展开讨论。CONTRIBUTING.md 说明补丁需要满足什么要求,SUPPORT.md 说明在哪里提问,而 CODE_OF_CONDUCT.md 则简明扼要地表达了“针对工作本身讨论,而非针对个人”。

许可证

从下一个版本开始采用 GPL-3.0-or-later。v0.0.13 及之前的版本仍采用 Apache-2.0。有关保留的外部贡献者及第三方授权,请参见 LICENSE 和 NOTICE。Agenxy 还为 Agenxy 编写的部分提供单独的商业许可证。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。