2026-07-31T05:48:20.517Z

Disler Claude Code Hooks 多代理可观测性:证明事件传递

在信任 Disler Claude Code 仪表板之前,审核配置、HTTP 交付、SQLite 持久性、WebSocket 新鲜度、等待和结果。

安全的答案是:不要将可访问的仪表板或零钩子退出代码视为 Disler 的 Claude Code 钩子多代理可观察性管道健康的证据。要求在每个边界(配置、HTTP 交付、SQLite 持久性、WebSocket 交付和浏览器新鲜度)提供收据,然后验证监控路径之外的工作。 这种区别很重要,因为存储库自己的架构是一条链:Claude 代理 → 挂钩脚本 → HTTP POST → Bun 服务器 → SQLite → WebSocket → Vue 客户端。最后一个框中的明亮事件证明有一个事件跨越了链。安静框不会告诉您证据在哪里停止, Stop 事件也不会证明所请求的文件、测试、部署或切换存在。 我审核了存储库提交 8a6e5cf 并重播了九个无内容的案例。一个简单的规则,仅检查标记为所有九个绿色的钩子进程退出代码。接收规则按预期对所有九个进行了分类;只有一名是健康的。 固定存储库并定义证据合约 从您实际运行的代码开始。在固定的提交中, .claude/settings.json 配置十二个事件组: SessionStart 、 SessionEnd 、 UserPromptSubmit 、 PreToolUse 、 PostToolUse 、 PostToolUseFailure 、 PermissionRequest 、 Notification 、 SubagentStart 、 SubagentStop 、 Stop 和 PreCompact 。 目前的Claude Code 挂钩参考记录三十个生命周期事件。该更大的集合包括较新的团队和故障信号,例如 TaskCreated 、 TaskCompleted 、 TeammateIdle 、 StopFailure 和 PostToolBatch 。比较并不意味着每个安装都应该捕获所有 30 个。这意味着“所有挂钩”是一个版本化声明:定义您的操作决策所需的最少事件,固定 Claude Code 版本,并在配置不再与该清单匹配时使覆盖检查失败。 对于单代理金丝雀,合理的最小值是 SessionStart 、一对 PreToolUse 和 PostToolUse 以及 Stop 。对于团队运行,添加子代理生命周期以及您安装的 Claude Code 版本公开的任务或队友信号。仅当您确定丢失的事件是预期的并已配置后,该事件才有意义。 下一个边界是发送者。固定的 send event.py 使用五秒 HTTP 超时。当请求失败时,它返回 False 并写入 stderr,但 main() 不使用该结果:它无条件以代码零退出,因此监视无法阻止 Claude Code。这是一个合理的可用性选择,但它使退出代码零成为活动信号而不是交付收据。 服务器提供了更强的收据。它是 POST /events path 验证必填字段,插入事件,然后返回保存的记录并将其广播到连接的 WebSocket 客户端。保留返回的 Canary 数据库 ID。没有保存 ID 的 HTTP 连接不是等效证据。 存储库的 just health 配方需要相同的解释。它请求 /health ,但固定的服务器没有专用的运行状况分支;不匹配的路径收到带有 HTTP 200 的通用 Multi Agent Observability Server 响应。这证明了该过程回答了 HTTP。它不执行事件插入、SQLite 可读性、WebSocket 传递或当前浏览器视图。 使用显式契约: 收据 保留证据 它没有证明什么 配置 固定事件清单和源应用程序值 钩子发射了 运输 HTTP 200 加上保存的事件 ID 浏览器收到它 坚持 最近事件中可见的相同 ID 该视图是当前的 推介会 WebSocket或重新连接重放包含ID 所有必需的事件均已到达 覆盖范围 每个必需的事件都在截止日期之前出现 那项工作成功了 结果 对预期交付成果进行确定性检查 未来跑步保持健康 在信任视图之前重播交付审核 我将这些边界编码在固定装置中,没有提示、记录、工具输入、文件路径或秘密。运行它: 重播产生: 分类器使用优先级。它首先检查退出零挂钩是否实际到达服务器。然后,它需要持久性收据,检查浏览器交付是否是最新的,验证配置的清单,使过时的证据过期,在截止日期之前保留合法的等待,然后才询问预期的结果是否存在。 夹具 分类 运营商决策 POST 失败后发件人退出为零 delivery failed hidden 检查发送方 stderr 和服务器可达性 HTTP 已接受但未保存 ID persistence unverified 不要从运输推断存储 SQLite有该事件,但WebSocket没有 dashboard stale 在诊断代理之前重新连接并验证重播 团队活动是必需的但未配置 manifest drift 更新或缩小固定清单 配置的事件永远不会到达 coverage gap 检查匹配器、钩子进程和版本兼容性 权限依赖性在截止日期之前 waiting 将决定传递给其所有者;不要称之为卡住 Stop 到达时没有可交付收据 false complete 清除运行之前验证外部结果 只剩下旧事了 stale 绿色过期并报告证据不可用 每个边界和结果都会过去 healthy 接受此运行,而不是永远接受整个安装 waiting 分支可防止常见的误报。如果权限请求有指定的所有者和未到期的截止日期,则预计不会出现稍后的工具结果。在截止日期之后,或者当不存在所有者时,相同的证据就会成为覆盖范围或进度问题。时间和所有权改变了诊断;单独的事件计数不能。 false complete 分支可以防止相反的错误。 Claude Code的官方参考将 Stop 定义为响应的结束。存储库可以忠实地显示该生命周期事实。两个系统都没有声称目的地发生了变化。文件任务需要进行预期的路径和内容检查;代码任务需要相关测试;远程操作需要目的地收据。将这些检查保留在吊钩运输之外,以便监控系统无法自我认证。 还有隐私权衡。该存储库支持可选的聊天捕获并显示提示相关的数据。交付健康也不需要。金丝雀只能使用不透明标识符,例如 source app 、 session id 、 hook event type 、时间戳和返回的事件 ID。在扩展可观测性之前最小化包络线。 操作小金丝雀,然后验证真实结果 通过五个有限步骤进行审核。 1. 固定版本和范围。 记录存储库提交、Claude Code 版本、源应用程序标识符以及您的决策所需的确切生命周期事件。当任一版本发生更改时,请查看官方 Hooks 参考。 2. 发送一个唯一的金丝雀。 使用一次性会话标识符和无害的 PreToolUse 有效负载。需要HTTP 200并解析返回的保存事件ID。不要单独使用钩子退出代码。 3. 证明存储和呈现。 立即查询 /events/recent 并找到确切的 ID。将 Vue 客户端或测试 WebSocket 重新连接到 /stream ,并要求初始重播或实时消息中存在相同的事件。将检查保留在重播窗口内;当 WebSocket 打开时,固定服务器会发送 300 个最近行。 4. 检查覆盖范围和新鲜度。 运行已知的生命周期序列,将观察到的事件类型与固定清单进行比较,并应用每个事件的截止日期。路由拥有的权限等待作为等待。使旧证据过期而不是保持陈旧的绿色。 5. 单独验证用户的结果。 断言预期的文件、测试结果、任务状态或外部效果。当生命周期在没有收据的情况下关闭时,监视器应报告 false complete 。 这个过程有局限性。它通过固定存储库测试配置的交付;它不会为每个有效负载建立语义正确性。添加每个可用的挂钩可能会增加延迟、存储和敏感数据暴露。最小化的、版本化的清单通常比不加区别的收集更安全。九个案例的固定装置展示了决策规则,而不是生产中失败的普遍性。 Sidewisp 作为健康层适合此边界,而不是作为另一个 Claude Code 运行时或存储库的替代品。 Sidewisp 目前处于私密预览阶段。 公共站点和交互式演示已上线,但生产 Claude Code 监控适配器、实时运行状况收集器和自动恢复执行器尚未发货。恢复仍然是一项有计划的、受批准的能力;如果此收据模型与您操作代理的方式相匹配,当前诚实的下一步是加入私人预览候补名单。 对于此存储库,请保持规则紧凑:仪表板事件是观察到的活动的证据。仅当所需的事件清单是最新的,金丝雀具有传输、持久性和呈现收据,任何等待都有所有者和截止日期,并且预期结果通过其自己的确定性检查时,才声明运行正常。