Перейти к содержимому

Модуль I — инвентаризация и обнаружение

Модуль I — это каталог наблюдённых сущностей estate: пассивная, управляемая шиной инвентаризация агентов, сессий, экземпляров Claude Code, серверов MCP, навыков, инструментов, ресурсов, моделей, провайдеров и нечеловеческих идентичностей, которые коннекторы действительно назвали. Он обнаруживает путём прослушивания, никогда не зондируя. Он записывает связи, идентификаторы и признаки активности — не полезную нагрузку — и это не перепись всего, что существует. Эта страница — справочник по тому, что содержит каталог, как работают происхождение наблюдения и устойчивая свежесть, и чего модуль намеренно не утверждает.

Происхождение наблюдения и устойчивая свежесть входят в 26.10.

Коннекторы испускают наблюдения, а не сущности. Они публикуют нормализованные факты edge.observed и cost.sampled на шину событий; подразумеваемые ими сущности никогда не отправляются. Модуль I материализует базовую сущность, которую называет каждое наблюдение, по её естественной ссылке: инициатора session/agent/identity, сервер MCP, инструмент, ресурс, навык и — из выборок стоимости — провайдера и модель (обнаруженные, без цен; ценами владеет FinOps). Инвентаризация подписывается на эти два типа событий; живые находки относятся к модулю II.

Find-or-create базовой сущности по естественному ключу не дублирует алиас каталога при доставке «не менее одного раза» в текущей модели с одним писателем. Два источника могут сохранять различные наблюдения, разделяющие этот алиас; совпадение не доказывает физическую эквивалентность и не передаёт владельца, workspace или grants. Новый идентификатор события с тем же payload — это новый чек; является ли это другой активностью, остаётся неизвестным. occurrence_count каталога считает доставки, включая повтор того же идентификатора события, а не различные активности.

Помимо алиаса каталога модуль хранит аддитивную, ограниченную арендатором проекцию того, как прибыло наблюдение: чек с ключом по идентификатору события, строку члена на каждую материализованную сущность (нативная ссылка и, когда снимок регистрации действителен, устойчивая наблюдательная идентичность) и строку конфликта, когда тот же идентификатор позднее несёт иные спроецированные факты. Исходный чек сохраняется; конфликт записывается, а не перезаписывается. Отсутствующий идентификатор получает только идентичность хранения и никогда не дедуплицируется по payload. Повтор того же идентификатора и тех же фактов обновляет унаследованный счётчик доставок каталога, не разрешая алиасы заново. Консоль может перечислить сохранённые чеки одной сущности каталога по GET /v1/m/inventory/entities/{kind}/{id}/observations с существующим разрешением на весь арендатор inventory:catalog:read: один элемент на отличимый чек в порядке возрастания идентификатора чека, страницы не более чем из 25. Каждый элемент — исторический снимок регистрации при приёме (не текущая регистрация или здоровье источника), заявленный источником момент если он заявлен, первый и последний приём сохранённых фактов, доставки с совпадающими фактами и удерживается ли конфликтная повторная доставка. Пустая страница не доказывает, что сущность никогда не наблюдалась. has_more, пустой список и итог каталога не являются покрытием. Свежесть каталога на карточке сущности берётся из успешного текущего point read; это отдельное чтение от истории. Покрытие по источнику/семейству и эталонный estate C4 остаются открытыми.

Модуль регистрирует inventory.catalog_entry — наложение обнаружения, прикреплённое к каждой материализованной базовой сущности. Оно фиксирует, как нечто было найдено, а не что оно делало: источники сигналов, хосты когда они известны, метки времени первого и последнего наблюдения, необязательный объявленный источником occurred_at (опускается, если источник ничего не объявил; это не last_seen, то есть момент, когда эта платформа это увидела), счётчик вхождений и признак активности status — active или stale. Поверхность чтения мала и доступна только для чтения: счётчик summary по виду и источнику, постраничный список entities с фильтрацией по виду и статусу, подробный просмотр одной сущности и история наблюдений по сущности выше. Каждое чтение требует разрешения на чтение в области арендатора и в пространстве имён (достаточно низшего уровня viewer). Записи каталога и происхождения высокочастотны и не проходят аудит на каждую запись.

Устойчивая свежесть держит второе наложение, inventory.freshness_sweep: не более одной лениво созданной строки на арендатора с отсечкой открытого цикла, непрозрачным курсором каталога и последней отсечкой, чей цикл завершился. Эта последняя отсечка фиксирует законченный обход, а не то, что какой-либо источник был полностью перечислен. Полные формы описаны в справочнике по шине событий и в типизированных интерфейсах продукта.

Периодический обход помечает запись каталога как stale, когда эта платформа не видела её с отсечки цикла, и возвращает её в active в момент повторного появления. Пороги по умолчанию — 30 минут тишины и каденция 5 минут; это значения модуля по умолчанию, а не YAML-поверхность оператора в текущем двоичном файле (корень композиции регистрирует модуль с пустыми настройками хоста).

Модуль не перечисляет арендаторов и не откатывается к арендаторам, которых этот процесс случайно наблюдал. Закрытый адаптер композиции читает устойчивый каталог организаций и возвращает только кандидатов: активных бизнес-арендаторов, которых обслуживает резидентность этого экземпляра — никогда системный раздел, никогда приостановленную организацию, никогда арендатора, привязанного к региону, который этот экземпляр не обслуживает. Каждый ход по-прежнему открывает обычную tenant-scoped запись в store, поэтому резидентность, снятие обслуживания и лидерство проверяются снова; арендатор, чьё состояние изменилось между снимком и ходом, там отклоняется.

Без авторитетного каталога обход явно завершается ошибкой и ничего не изменяет. В PostgreSQL для этой власти нужен выделенный admin-пул чтения NOSUPERUSER BYPASSRLS, уже используемый для межтенантных чтений каталога (--admin-dsn). Без этого засвидетельствованного пула обход не считает строки, видимые роли приложения, полным каталогом. У SQLite такого требования к пулу нет. Новые наблюдения продолжают сохраняться, когда подключён handle данных; обход, который не может выполниться, не отписывает приём.

Каждый проход даёт каждому кандидату один ход. Каждый ход классифицирует не более одной страницы из 1 000 активных записей старше отсечки и сохраняет курсор, чтобы перезапуск продолжался без нового события. Перечисление и каждый ход арендатора имеют отдельные бюджеты времени, поэтому один медленный арендатор не расходует остаток прохода. Локальный сбой не мешает последующим арендаторам получить ход в живом процессе. Нет глобального курсора арендаторов, нет справедливости при повторных перезапусках и нет утверждения о высокой доступности.

Если ход не завершился успешно, эта страница не считается помеченной. Страница и прогресс остаются вместе; следующий ход заново читает то, что было сохранено последним — прежнюю границу или уже продвинутую — и продолжает оттуда. Продукт не восстанавливает прогресс из памяти.

Модуль I — потребитель. Он подписан на edge.observed и cost.sampled и записывает своё наложение каталога, выводимые базовые сущности и аддитивные строки происхождения и свежести выше. Он не испускает собственных событий и не предоставляет поверхности воздействия. Сохраняемые им ссылки и выбранные факты наблюдения записываются как получены; модуль не проводит их дополнительную санацию. Минимизация данных лежит на производителе и должна быть выполнена до публикации наблюдений; этот модуль не может засвидетельствовать её для каждого производителя. Сохранённая ссылка может сохранить query string, учётные данные или иные чувствительные данные, если производитель их опубликовал. Инвентаризация не собирает по собственной инициативе полное сырое содержимое активности и не добавляет собственной сырой полезной нагрузки, секретов, промптов, команд или SQL.