proposals: RFC for sfp_modules[] contract extension (v2.10 → v2.11)
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
201
bible-local/proposals/2026-06-19-sfp-modules-contract-rfc.md
Normal file
201
bible-local/proposals/2026-06-19-sfp-modules-contract-rfc.md
Normal file
@@ -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 <iface>` (читает EEPROM SFP/SFP+/QSFP28/QSFP-DD по стандарту MSA SFF-8472 / SFF-8636).
|
||||
|
||||
**Связь с PCIe:** `ethtool -i <iface>` возвращает `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` с описанием поля.
|
||||
Reference in New Issue
Block a user