From 518082c2e262e9f165699184170fe876b2807c38 Mon Sep 17 00:00:00 2001 From: Mikhail Chusavitin Date: Fri, 19 Jun 2026 18:14:46 +0300 Subject: [PATCH] =?UTF-8?q?proposals:=20RFC=20for=20sfp=5Fmodules[]=20cont?= =?UTF-8?q?ract=20extension=20(v2.10=20=E2=86=92=20v2.11)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bible-local/README.md | 1 + .../2026-06-19-sfp-modules-contract-rfc.md | 201 ++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 bible-local/proposals/2026-06-19-sfp-modules-contract-rfc.md diff --git a/bible-local/README.md b/bible-local/README.md index b939942..d1a4ee5 100644 --- a/bible-local/README.md +++ b/bible-local/README.md @@ -13,6 +13,7 @@ Generic engineering rules live in `bible/rules/patterns/`. | `docs/hardware-ingest-contract.md` | Current Reanimator hardware ingest JSON contract | | `docs/validate-vs-burn.md` | Validate and Validate -> Stress hardware test policy | | `decisions/` | Architectural decision log, including read-only submodule policy | +| `proposals/` | RFCs and contract change proposals for Reanimator Core | ## Validate Test Matrix diff --git a/bible-local/proposals/2026-06-19-sfp-modules-contract-rfc.md b/bible-local/proposals/2026-06-19-sfp-modules-contract-rfc.md new file mode 100644 index 0000000..42d0225 --- /dev/null +++ b/bible-local/proposals/2026-06-19-sfp-modules-contract-rfc.md @@ -0,0 +1,201 @@ +# RFC: SFP Module Identity and Telemetry in Hardware Ingest Contract + +**Date:** 2026-06-19 +**Status:** proposal +**Target:** Reanimator Core — ingest schema, validation, and storage +**Requested by:** bee (hardware audit LiveCD) +**Contract version affected:** 2.10 → 2.11 + +--- + +## Задача для агента + +Внести изменения в контракт ingest и реализовать их в Reanimator Core: + +1. Добавить массив `sfp_modules[]` внутри `pcie_devices[]`. +2. Обновить JSON-схему и валидатор ingest endpoint. +3. Реализовать хранение/upsert данных SFP-модулей. +4. Пометить скалярные поля `sfp_*` на уровне `pcie_devices[]` как deprecated. +5. Обновить документ контракта (`hardware-ingest-contract.md`) до версии 2.11. + +Ниже — всё необходимое для принятия решений без дополнительных вопросов. + +--- + +## Контекст: откуда берутся данные + +**Источник в bee:** `ethtool -m ` (читает EEPROM SFP/SFP+/QSFP28/QSFP-DD по стандарту MSA SFF-8472 / SFF-8636). + +**Связь с PCIe:** `ethtool -i ` возвращает `bus-info` = BDF (`0000:3b:00.0`), который совпадает с `pcie_devices[].slot`. Так bee связывает SFP-данные конкретного интерфейса с PCIe-устройством. + +**Один NIC — несколько модулей:** карта ConnectX-6 Dx (2 порта), Intel X710 (4 порта), Mellanox HDR (2 порта). Каждый порт — отдельный `ethtool -m`, отдельный SFP-модуль. Одного скаляра на устройство недостаточно. + +**QSFP28/QSFP-DD:** 4-канальные модули возвращают telemetry отдельно по каждому каналу (lane). В предложенной схеме lane-уровень не включён в первую версию — только агрегированные значения модуля в целом. Расширение до lane-уровня — отдельный RFC если понадобится. + +--- + +## Проблема с текущим контрактом v2.10 + +В `pcie_devices[]` есть пять скалярных полей: + +``` +sfp_temperature_c float +sfp_tx_power_dbm float +sfp_rx_power_dbm float +sfp_voltage_v float +sfp_bias_ma float +``` + +Ограничения: +- **Нет идентификации модуля** — vendor, part_number, serial_number, wavelength отсутствуют; модуль нельзя инвентаризировать как самостоятельный компонент. +- **Только один набор значений на устройство** — невозможно описать 4-портовый NIC. +- **Нет типа модуля** — SFP, QSFP28, DAC-кабель не различаются. +- **Нет connector/transceiver_type** — невозможно понять, оптика это или медь. + +--- + +## Предлагаемое изменение схемы + +### Новая структура `sfp_modules[]` + +Добавляется как необязательное поле внутри каждого объекта `pcie_devices[]`. + +```json +"pcie_devices": [ + { + "slot": "0000:3b:00.0", + "device_class": "EthernetController", + "model": "ConnectX-6 Dx", + "manufacturer": "Mellanox", + "serial_number": "MT2012X12345", + "status": "OK", + "sfp_modules": [ + { + "port": 0, + "identifier": "QSFP28", + "connector": "LC", + "vendor": "Mellanox", + "part_number": "MFA1A00-C003", + "serial_number": "MT2124VS09999", + "revision": "A", + "wavelength_nm": 850, + "transceiver_type": "100GBase-SR4", + "temperature_c": 36.4, + "voltage_v": 3.29, + "tx_power_dbm": -1.8, + "rx_power_dbm": -2.1, + "bias_ma": 7.2 + }, + { + "port": 1, + "identifier": "QSFP28", + "connector": "LC", + "vendor": "Mellanox", + "part_number": "MFA1A00-C003", + "serial_number": "MT2124VS09998", + "revision": "A", + "wavelength_nm": 850, + "transceiver_type": "100GBase-SR4", + "temperature_c": 35.9, + "voltage_v": 3.28, + "tx_power_dbm": -1.9, + "rx_power_dbm": -2.3, + "bias_ma": 7.1 + } + ] + } +] +``` + +### Поля `sfp_modules[]` + +| Поле | Тип | Обязательно | Описание | +|---|---|---|---| +| `port` | int | **да** | Номер порта на NIC (0-based). Ключ дедупликации внутри устройства. | +| `identifier` | string | нет | Тип модуля: `SFP`, `SFP+`, `SFP28`, `QSFP+`, `QSFP28`, `QSFP-DD`, `DAC` | +| `connector` | string | нет | Тип разъёма: `LC`, `MPO`, `RJ45`, `DAC`, `AOC`, `No separable connector` | +| `vendor` | string | нет | Производитель модуля из EEPROM | +| `part_number` | string | нет | Партномер из EEPROM | +| `serial_number` | string | нет | Серийный номер из EEPROM | +| `revision` | string | нет | Ревизия из EEPROM | +| `wavelength_nm` | int | нет | Длина волны, нм (0 для DAC/медных кабелей) | +| `transceiver_type` | string | нет | `10GBase-SR`, `10GBase-LR`, `25GBase-SR`, `100GBase-SR4`, `DAC`, … | +| `temperature_c` | float | нет | Температура модуля, °C (DOM telemetry) | +| `voltage_v` | float | нет | Напряжение питания, В (DOM telemetry) | +| `tx_power_dbm` | float | нет | TX оптическая мощность, dBm (DOM telemetry) | +| `rx_power_dbm` | float | нет | RX оптическая мощность, dBm (DOM telemetry) | +| `bias_ma` | float | нет | Bias current, мА (DOM telemetry) | + +**Ключ дедупликации:** `(pcie_device.slot, sfp_modules[].port)`. + +**Модули без серийного номера** — допустимы; многие DAC-кабели не имеют SN. Не игнорировать, сохранять по ключу `(slot, port)`. + +--- + +## Deprecated поля + +Следующие поля на уровне `pcie_devices[]` помечаются как **deprecated** начиная с v2.11: + +``` +sfp_temperature_c +sfp_tx_power_dbm +sfp_rx_power_dbm +sfp_voltage_v +sfp_bias_ma +``` + +**Поведение при получении deprecated полей:** +- Продолжать принимать и сохранять (не ломать существующих интеграторов). +- Если одновременно присутствуют `sfp_modules[]` и deprecated скаляры — приоритет у `sfp_modules[]`; скаляры игнорируются. +- В документации пометить как `deprecated since 2.11, will be removed in 3.0`. + +**Не удалять** deprecated поля из валидации в этом PR — только пометить в документации и changelog. + +--- + +## Правила ingest для `sfp_modules[]` + +- `sfp_modules[]` хранится как snapshot-атрибут PCIe-компонента (аналогично `mac_addresses`). +- При каждом импорте — полная замена `sfp_modules[]` для данного `pcie_devices[].slot` (upsert всего массива целиком, не merge по портам). +- Если `sfp_modules` отсутствует или `null` — существующие данные SFP не трогать (не затирать). +- Если `sfp_modules: []` (пустой массив) — трактовать как «модули не обнаружены», очистить сохранённые данные. +- Изменение `serial_number` или `part_number` модуля на порту — создавать событие `COMPONENT_CHANGED` для PCIe-устройства с описанием «SFP module replaced on port N». + +--- + +## Изменения в документе контракта + +Файл: `bible-local/docs/hardware-ingest-contract.md` + +1. Заголовок версии: `2.10` → `2.11`, дата → `2026-06-19`. +2. Добавить в changelog: + ``` + | 2.11 | 2026-06-19 | В `pcie_devices[]` добавлен необязательный массив `sfp_modules[]` + с идентификацией и DOM telemetry SFP/QSFP-модулей. Скалярные поля + sfp_temperature_c / sfp_tx_power_dbm / sfp_rx_power_dbm / sfp_voltage_v / + sfp_bias_ma помечены как deprecated (принимаются, но sfp_modules[] имеет приоритет). | + ``` +3. В секции `pcie_devices` добавить строку в таблицу полей: + ``` + | `sfp_modules` | array | нет | Установленные SFP/QSFP-модули по портам (см. sfp_modules[]) | + ``` +4. Добавить подсекцию `#### pcie_devices[].sfp_modules[]` с таблицей полей и примером JSON (из раздела выше). +5. Пометить deprecated поля в таблице: добавить суффикс `*(deprecated since 2.11)*`. +6. Обновить полный пример JSON — добавить `sfp_modules` к NIC-записи в `pcie_devices`. + +--- + +## Что не нужно делать в этом PR + +- Не добавлять lane-level данные QSFP (tx_power_dbm_lane_0 и т.п.) — отдельный RFC. +- Не удалять deprecated поля — только пометить. +- Не создавать отдельную top-level секцию `network_ports` — данные остаются вложенными в `pcie_devices`. +- Не менять логику идентификации PCIe-компонента — `serial_number` SFP-модуля не является ключом для самостоятельного компонента. + +--- + +## Валидация + +Единственное обязательное поле в `sfp_modules[]` — `port` (int, >= 0). +Все остальные поля опциональны. +Дубли по `port` внутри одного `pcie_devices[]` — невалидны, возвращать `400` с описанием поля.