跳转到内容

模块 I——清点与发现

模块 I 是 estate 中已观测实体的目录:一份被动的、由总线驱动的清单,涵盖连接器 实际命名过的 agent、会话、Claude Code 实例、MCP 服务器、skill、工具、资源、模型、 提供商以及非人类身份。它通过监听来发现,从不通过探测。它记录关系、标识符和 存活性——而不是载荷——并且不是对一切存在之物的普查。本页说明目录所持有的内容、 观测来源与持久新鲜度如何工作,以及本模块刻意不主张什么。

观测来源与持久新鲜度是 26.10 的一部分。

连接器(connector)发出的是观测,而非实体。它们将规范化的 edge.observed 和 cost.sampled 事实发布到事件总线上;它们所隐含的实体从不被发送。模块 I 从每条观测的自然引用中 物化出它所命名的核心实体:一个发起方 session/agent/identity、一个 MCP 服务器、一个工具、一个资源、一个 skill,以及——从成本采样中——一个提供商和一个模型 (被发现,不含定价;定价归 FinOps 所有)。清点本身订阅这两种事件;实时 finding 属于模块 II。

按自然键对核心实体做 find-or-create,可在当前单写者模型的至少一次投递下避免重复 目录别名。两个来源仍可保留共享该别名的不同观测;共享并不能证明它们是同一物理对象, 也不会转移所有者、workspace 或授权。带有相同载荷的新事件 ID 是一张新收据—— 这是否为另一项活动仍属未知。目录的 occurrence_count 统计的是投递次数(包括 同一事件 ID 的重放),而不是互不相同的活动。

在目录别名之外,本模块还保存一份按租户限定的加法投影,记录观测如何到达:以事件 ID 为键的收据、每个被物化实体的成员行(原生引用,以及在注册快照有效时一份稳定的 观测身份),以及同一事件 ID 随后携带不同投影事实时的冲突行。原始收据予以保留; 冲突被记录而非覆盖。缺失的事件 ID 只获得存储身份,从不按载荷去重。同一 ID、同一 事实的重放会刷新目录的既有投递计数,而不会重新解析别名。控制台可用既有的租户范围 权限 inventory:catalog:read,通过 GET /v1/m/inventory/entities/{kind}/{id}/observations 列出某一目录实体的已存储 收据:每个不同收据一项,按收据 ID 升序,每页最多 25 条。每项是接收时记录的历史登记 快照(不是来源当前的登记或健康状况)、来源已声明时的发生时刻、所保留事实的首次与 最近接收、相符事实的投递,以及是否保留了冲突的再次投递。空页不能证明该实体从未被 观测。has_more、空列表和目录总数都不是覆盖率。实体页上的目录新鲜度来自当前成功的 点读;它与历史是彼此独立的读取。按来源/家族的覆盖以及 C4 参考资产域仍未完成。

本模块注册 inventory.catalog_entry——一个附加到每个被物化核心实体上的发现叠加层。 它记录一个事物是如何被发现的,而非它做了什么:信号来源、已知主机、首次与最后 一次出现的时间戳、来源声明的可选 occurred_at(来源未声明时省略;不同于 last_seen, 后者是本平台看见它的时刻)、一个出现计数,以及值为 active 或 stale 的存活性 status。读取面很小且为只读:一个按 kind 和 source 计数的 summary、一个可按 kind 和 status 过滤的分页 entities 列表、单实体详情视图,以及上文的按实体观测历史。每次读取都需要一个按租户 限定、带命名空间的读取权限(最低的查看者层级即足够)。目录与来源的写入是高频的, 且不按写入逐条审计。

持久新鲜度另有一层叠加 inventory.freshness_sweep:每个租户至多一行、按需创建, 保存进行中周期的截止时刻、不透明的目录游标,以及其周期已结束的最近截止。该最近 截止记录的是一次已完成的扫描,而不是任何来源已被完整枚举。完整形状见 事件总线参考以及产品的类型化接口。

周期性扫描会在本平台自该周期截止以来未见某目录条目时将其标记为 stale,并在它 重新出现时立即翻回 active。默认阈值是 30 分钟沉默与 5 分钟节拍;这是模块默认值, 不是当前二进制中的操作者 YAML 面(组合根以空的主机设置注册该模块)。

本模块不枚举租户,也不回退到本进程碰巧观测过的租户。私有组合适配器读取 持久的组织目录,并只返回候选:本实例驻留所服务的活跃业务租户——从不是系统 分区、从不是已暂停的组织、从不是钉在本实例不服务的区域上的租户。每一轮仍打开 普通的按租户限定的存储写入,因此驻留、服务撤回与领导权会再次检查;在快照与其 回合之间状态已变的租户会在那里被拒绝。

没有权威目录时,扫描会明确失败且不改写任何内容。在 PostgreSQL 上,该权威需要 已用于跨租户目录读取的专用 NOSUPERUSER BYPASSRLS 管理只读池(--admin-dsn)。 没有该经核验的池时,扫描不会把应用角色能看见的行当作完整目录。SQLite 没有对等的 池要求。在数据句柄已接线时,新观测会继续持久化;无法运行的扫描不会取消摄取订阅。

每一轮给每个候选一次回合。每一回合至多分类一页 1,000 条早于截止的活跃条目, 并保存游标,以便重启后无需新事件即可继续。枚举与每个租户回合有分开的时间预算, 因此一个缓慢的租户不会耗尽该轮其余部分。局部失败不会阻止后续租户在仍在运行的 进程中获得回合。没有跨租户的重启游标,没有在反复重启下的公平性,也没有高可用 主张。

若某回合未能成功完成,该页不算已标记。页与进度保持在一起;下一回合会重读最后 存下的内容——先前的边界,或已经前进的边界——并从那里继续。产品不会从内存重建 进度。

模块 I 是一个消费方。它订阅 edge.observed 和 cost.sampled,并写入它自己的 目录叠加层、所派生的核心实体,以及上面的加法来源与新鲜度行。它不发出任何自己的 事件,也不暴露任何执行(actuation)面。它所持久化的引用与选定观测事实按接收原样存储;本模块不会进一步净化这些值。 数据最小化属于生产者,必须在发布观测之前完成;本模块不能为每个生产者作出 该项证明。若生产者发布了查询串、凭据或其他敏感数据,持久化的引用可以保留 它们。清点不会自行收集完整的原始活动内容,也不添加任何自己的原始载荷、密钥、 提示、命令或 SQL。