Commit Graph
100 Commits
Author SHA1 Message Date
Mikhail ChusavitinandClaude Sonnet 5 2fa0f78f94 fix(inspur): read RESTful FRU info and float fans_power from component.log
Diffing an NF5280M6 BMC dump against its BEE-SP live-CD bundle found two
blind spots in the combined-component.log onekeylog layout (no
devicefrusdr.log / asset.json):

- board manufacturer/product/part/uuid empty and stats.fru 0: the
  "RESTful FRU info:" JSON block was never parsed. New component_fru.go
  (ParseComponentLogFRU) flattens it to []models.FRUInfo, prefers the
  product-area system serial over the board PCB serial, and sets
  BoardInfo.UUID from system_uuid. Wired as a fallback only when
  result.FRU is still empty.
- zero fan sensors: FanRESTInfo.FansPower was int but this firmware
  writes "fans_power": 12.000000, so json.Unmarshal of the whole fan
  block failed. Changed to float64.

Also included: SOL smartd SCSI/SAS device-line parsing and diagnose.go
gofmt from concurrent work on the same live-CD-diff task. See ADL-064.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011LffAvostt3uMkiUbVUiyM
2026-09-01 11:58:55 +03:00
Mikhail ChusavitinandClaude Sonnet 5 ab8636da04 fix(xfusion): parse disk_info Capacity in TB/binary units for size_gb
parseDiskInfo read capacity with Sscanf(cap, "%f GB"), so every iBMC
"Capacity : 6.986 TB" NVMe line failed to match and size_gb stayed 0
while the BEE-SP live-CD export of the same drive had the real size.
The iBMC number is also binary (GiB/TiB) despite the GB/TB label.

parseDiskCapacityGB parses number + unit (TB/GB/MB), treats it as
binary, and emits decimal GB, matching the drive's marketed capacity
and the live-CD inventory. Found by diffing a G5500 V7 BMC dump against
its live-CD bundle. See ADL-063.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011LffAvostt3uMkiUbVUiyM
2026-09-01 11:58:46 +03:00
Mikhail ChusavitinandClaude Sonnet 5 8e7f22077d fix(xfusion): emit OCP NIC ports with no serial so reanimator keys them by MAC
Verified against reanimator/core: it keys a NIC component on serial → MAC →
synthetic(slot). A BMC dump carrying the card serial collapses both ports into
one serial-keyed component, while a live-CD bundle (no serial) keeps two
MAC-keyed components, so alternating the two sources produced a spurious
COMPONENT_REMOVED + 2x COMPONENT_INSTALLED every time. Emitting the per-port
NetworkAdapter entries with an empty serial makes both sources key on the port
MAC and yield the same two components. The card serial still reaches the export
via the FRU record and the legacy NIC entry.

Also records ADL-062 findings from reading the ingesting audit tool: it persists
only vendor/model/serial per component (no size/speed/link/clock/wattage), so the
remaining one-sided field diffs between the two bundles cannot generate change
events.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VFy4m7cVv4cqp25jJh2gSB
2026-08-31 22:55:45 +03:00
Mikhail ChusavitinandClaude Sonnet 5 9b2c654182 fix(parser,exporter): reconcile BMC-dump and live-CD exports of the same server
The audit tool that ingests Reanimator exports treats any per-component field
change between imports as a component replacement. Importing an xFusion BMC dump
and an easy_bee BEE-SP bundle for one server produced large spurious diffs.

xfusion:
- parseMemInfo tolerates a stray 0x0A inside the binary SPD "bom number" column
  (it was splitting a DIMM record in two and emitting a phantom "slot s" module)
- DIMM slot from the "dimm name" column ("DIMM071"), mainboard "location" dropped
- GPU slot = BDF (Reanimator contract)
- NIC emitted per PCI function from netcard_info.txt (BDF + per-port MAC, shared
  card serial) instead of one card-level adapter with the wrong BDF, which had
  been colliding with a GPU and vanishing in dedup
- NIC manufacturer left blank when it is the system OEM so the exporter resolves
  the silicon vendor from pci.ids
- "(U6216)" chip designator stripped from firmware versions

easy_bee:
- PSU bay numbers rebased 0-indexed -> 1-indexed; bare single-letter PSU
  "firmware" (a leaked FRU version) cleared
- board.part_number taken from the bundle's ipmitool-fru.txt chassis
  "Product Part Number" to match the BMC value

exporter (cross-vendor):
- canonicalMemorySlot: drop dmidecode "(J)" channel tag, Memory111 -> DIMM111
- canonicalGPUModel: NVIDIA DC GPUs reduce to the bare chip token
- canonicalStorageMediaAndInterface: NVMe is a bus not a medium
- manufacturerFromStorageModel: fill blank drive vendor from the model prefix
- isRemovableUSBStorageDevice: drop live-CD boot sticks
- isOnboardControllerPCIeDevice: drop SATA/NVMe/MegaRAID/PCIe-switch controller
  functions that only an lspci scan reports (keep add-in cards with an identity)

For the reference server every physical component now appears in both exports
keyed identically; residual diffs are one-sided enrichment only.

Refs ADL-061, ADL-062.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VFy4m7cVv4cqp25jJh2gSB
2026-08-31 22:50:07 +03:00
Mikhail ChusavitinandClaude Sonnet 5 5b65c99b0e fix(server): build ping address with net.JoinHostPort for IPv6 hosts
fmt.Sprintf("%s:%d", host, port) produces a malformed address for IPv6
literal hosts (go vet: "address format does not work with IPv6").

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 17:08:51 +03:00
Mikhail ChusavitinandClaude Sonnet 5 70c939ea4b docs(bible-local): record ADL-054..060 and parser/exporter notes
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 17:05:56 +03:00
Mikhail ChusavitinandClaude Sonnet 5 fc68134ed9 feat(cmd): add logpile-cpu-audit offline CPU identity audit CLI
Non-server entry point over the parser registry: recursively discovers
supported dumps, parses them with bounded concurrency, and writes one
path-mirrored CPU identity report per input plus a deterministic summary.
Failures are isolated as JSON. A -reanimator mode emits a flat CPU-only
dataset via the production exporter.

See ADL-059.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 17:05:52 +03:00
Mikhail ChusavitinandClaude Sonnet 5 a430a8c46f feat(nvidia_bug_report): extract Xid/SXid GPU error events
Parse Xid and SXid entries from the kernel log into GPU error events with
severity and the decoded failure reason.

See ADL-055.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 17:05:52 +03:00
Mikhail ChusavitinandClaude Sonnet 5 e7b8a8badc feat(inspur): source-PRI timezone timeline, PPIN serial, NVMe fault storage status
Event ingestion now uses the source syslog PRI and an explicit-offset
timezone timeline instead of assuming host-local time. CPU PPIN is
exported as the source-backed CPU serial, and an active NVMe fault SEL
event promotes the matching drive's storage status.

See ADL-056, ADL-057.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 17:05:45 +03:00
Mikhail ChusavitinandClaude Sonnet 5 07c270cda2 feat(models): resolve CPU serial from source PPIN as common fallback
Centralize CPU identity in models.ResolveCPUSerialNumber: an explicit
source serial wins, otherwise a valid source PPIN is used, placeholders
rejected. Dell, H3C and Redfish apply it while parsing; canonical-device
and Reanimator conversion apply it again at the output boundary. No
identity is synthesized from socket/model/board serial.

See ADL-058.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 17:05:40 +03:00
Mikhail ChusavitinandClaude Sonnet 5 9d701885da feat(parser): bound single-file gzip by ratio guard instead of fixed byte cap
Plain gzipped logs (nvidia-bug-report-*.log.gz) routinely exceed the old
50MB decompression cap, which silently dropped the tail. Replace it with a
decompression-ratio bomb guard plus a 1GB absolute memory ceiling.

See ADL-054.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 17:05:33 +03:00
Mikhail ChusavitinandClaude Sonnet 5 632067fef5 fix(parser): dedupe HPE AHS DIMM inventory per slot, newest snapshot wins
The AHS blackbox stores a DIMM inventory snapshot per POST cycle and
parseDIMMs flattens all of them. dedupeMemory keyed on serial, so a slot
whose module was swapped between captures survived once per historical
occupant — a 24-slot board reported 26 modules and "same P/N" vs
"mixed P/N" configs looked identical.

dedupeMemory now collapses to one entry per non-empty slot with the last
(most recent, since token order follows chronological blackbox-record
order) occurrence winning. Slotless entries keep the serial/part fallback.

See ADL-060.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 16:49:12 +03:00
Mikhail ChusavitinandClaude Sonnet 5 99d8f098ac fix(parser): match easy_bee bee-audit.json/runtime-health.json outside export/
bee-support v12.x bundles place bee-audit.json under tasks/_state/ and
runtime-health.json under status/, not export/. Detection was path-locked
to export/, dropping confidence to 50 and relying on a coincidental
export/reanimator.json duplicate to find the snapshot at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 17:22:24 +03:00
Mikhail ChusavitinandClaude Sonnet 5 6599ab49c2 fix(collector): surface RAID/HBA controller cards from Storage.StorageControllers[]
The RAID controller (XFusion XC170-M-8i / Broadcom SAS3808) never appeared
in inventory at all: it isn't listed in any Chassis/Systems PCIeDevices
collection on this BMC, and its dedicated Board resource link 404s (id
contains parentheses, same class of bug as the OCP NIC fixed earlier). Its
full identity -- model, firmware, BDF, vendor/device IDs -- was sitting
unread in the Storage resource's embedded StorageControllers[] array the
whole time.

Added parseStorageControllerPCIeDevice + collectStorageControllers to read
that array and surface the controller as a PCIeDevice entry, merged into
the existing pcie_devices list.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 14:30:56 +03:00
Mikhail ChusavitinandClaude Sonnet 5 1e4ec513e1 fix(collector): dedup GPUs and resolve model text on xFusion boards without PCI identity
A re-run against the G5500 V7 (previous fix commit a3567dd) surfaced two
follow-on bugs once the GPUs started being classified correctly:

- gpuDocDedupKey fell straight through to the full @odata.id path when a
  GPU had neither SerialNumber nor BDF, so the same physical H100 exposed
  under both Systems/1/PCIeDevices and Chassis/1/PCIeDevices (identical
  resource Id, different collection root) was kept twice, doubling the
  reported GPU count. Added an Id + resolved VendorID/DeviceID fallback
  tier that collapses same-Id duplicates without collapsing genuinely
  distinct GPUs that happen to share a vendor/device pair.

- isMissingOrRawPCIModel/isGenericRedfishInventoryName didn't recognize
  xFusion's generic "PCIeCardN"/"OCPCardN" slot labels, so when the doc's
  actual Model field was empty and GPU.Model fell back to the slot-like
  Name field, the pci.ids VendorId/DeviceId resolution never fired and the
  GPU surfaced with a meaningless model like "PCIeCard1" instead of the
  real chip name.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 14:24:49 +03:00
Mikhail ChusavitinandClaude Sonnet 5 a3567dd5f6 fix(collector): recover GPUs/NICs dropped on xFusion G5500 Redfish exports
looksLikeGPU now falls back to resolving VendorId/DeviceId through the
pci.ids database when the BMC leaves Name/Model/Manufacturer/ClassCode
empty, so GPUs identifiable only by raw PCI IDs (e.g. NVIDIA H100 SXM5
0x10de/0x2330) are no longer misclassified as generic PCIe devices.

The replay pipeline's "backed by canonical NIC" dedup used to trust a
PCIeDevice's Links.NetworkDeviceFunctions reference at face value and
drop the device, assuming a NetworkAdapters record existed elsewhere.
On BMCs that expose resource IDs with characters (parentheses) that
404 on fetch, that canonical NIC never gets captured, so the device
carrying its actual hardware identity vanished from the export
entirely. hasResolvableLinkedMember now verifies the linked resource
is actually present in the snapshot before treating it as authoritative.

Also normalize PartNumber through normalizeRedfishIdentityField in the
GPU/PCIe parsers so a BMC-supplied literal "null" string doesn't leak
into exports verbatim.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 14:17:25 +03:00
Mikhail ChusavitinandClaude Sonnet 5 2c3072cf10 fix(exporter): fix memory dedup collapsing distinct DIMMs, disambiguate slots
dedupeMemory keyed on slot before serial, unlike dedupeStorage/dedupePSUs
which both prefer serial. Some collectors (observed on MSI CG480-S6053 with
older BEE-SP versions — confirmed reproducible across multiple servers,
fixed in newer BEE-SP versions) report every memory module at the same slot
label ("DIMM 0") even though each has a distinct real serial. Slot-first
keying collapsed all of them into a single record on export — 16 real 32GB
DIMMs (512GB) reduced to 1, discarding 15 physical modules' worth of data.

Serial now takes priority, matching storage/PSU. Also add
disambiguateMemorySlots (same pattern as the existing PSU slot fix): when
multiple already-distinct DIMMs still share a slot label, renumber them to
"DIMM {n}" by ascending serial order so Reanimator can track them by
position and results are deterministic across re-imports.

Updated the existing dedup test (was asserting the old collapse-by-slot
behavior on a same-slot/different-serial case, which was exactly the bug)
and added a dedicated regression test for the collision case.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 11:05:19 +03:00
Mikhail ChusavitinandClaude Sonnet 5 6827c1fe20 fix(exporter): assign PSU slot positions by serial order, not encounter order
disambiguatePSUSlots previously renumbered colliding PSU slots in whatever
order the devices happened to appear in after parsing/dedup, which isn't
guaranteed stable across runs. Sort each colliding group by serial number
ascending before assigning 0-based positions, so the same PSU always lands
in the same slot on re-conversion regardless of incidental ordering upstream.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 09:56:13 +03:00
Mikhail ChusavitinandClaude Sonnet 5 a590242382 fix(exporter): disambiguate PSU slot collisions to avoid Reanimator "other"
Some collectors (BEE-SP observed so far) report every PSU at slot "0". The
export itself already keeps every PSU as a separate record (dedupePSUs keys
on serial first), but Reanimator relies on slot to track installed position,
so PSUs sharing a slot value land in "other components" instead of being
tracked as PSU installations.

Renumber colliding slots to stable 0-based positions by encounter order.
This doesn't invent a serial or other identity — the PSUs are already
distinguished by serial — it only assigns the position field Reanimator
needs when the source failed to. Files where every PSU already has a
unique slot are unaffected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 09:52:33 +03:00
Mikhail ChusavitinandClaude Sonnet 5 48baae41f4 fix(exporter): key PCIe canonical dedup by BDF before serial
canonicalKey used serial_number as the primary merge key for pcie-class
devices (PCIe/GPU/Network), falling back to BDF only when serial was empty.
Multi-port NICs commonly report one serial for the whole physical card
across all of its ports/BDFs (e.g. a dual-port ConnectX-5: same serial,
distinct BDFs 0000:65:00.0/.1, distinct MACs). Keying on serial first
collapsed every port sharing that serial into a single canonical device,
silently dropping all but one port from the export.

BDF now takes priority for pcie-class devices, since it uniquely identifies
one physical PCI function; other device kinds (storage, memory, PSU, etc.)
keep the existing serial-first behavior, which is correct there since a
serial genuinely maps 1:1 to a physical unit for those.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 09:42:34 +03:00
Mikhail ChusavitinandClaude Sonnet 5 8665f79fd6 fix(parser,exporter): fix large tar.gz truncation and empty device_class defaulting
- archive.go: extractTarGzFromReader truncated decompressed tar.gz content
  at a hard 50MB byte boundary before checking whether it was a tar archive,
  corrupting the tar structure mid-entry for any legitimately large archive
  (e.g. a 200MB decompressed NVIDIA bug-report bundle) and causing the whole
  file to fail with "tar read: unexpected EOF" instead of extracting what's
  there. Now peeks the first 512-byte tar block to detect tar vs. single
  gzipped file without consuming the stream, and streams tar entries with a
  cumulative (not raw-byte) size limit that only ever stops at an entry
  boundary. The byte-level cap still applies to the single-gzipped-file case,
  where it's safe since there's no container structure to corrupt.

- reanimator_converter.go: normalizeLegacyPCIeDeviceClass mapped an empty
  device_class to "NetworkController" by accident (grouped into the same
  case as "network"/"ethernet" aliases). Sources that never populate a class
  at all (e.g. Dell's DCIM_PCIDeviceView) got every such device — including
  NVMe drives and SATA controllers — mislabeled as network controllers.
  Empty now stays empty instead of being guessed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 14:00:55 +03:00
Mikhail Chusavitin 4fa16c78a5 perf(convert): parallelize batch conversion across worker pool
Batch convert processed files strictly sequentially. Parsing/converting
is CPU-bound and stateless per file, so run it across a GOMAXPROCS-sized
worker pool; zip writing and progress updates stay serialized in
original file order.
2026-08-15 12:43:21 +03:00
Mikhail ChusavitinandClaude Sonnet 5 42cfa3aa94 fix(exporter): drop dead bmc_event_summary field, fix status loss for inspur CPU/GPU
bmc_event_summary was a derived Assert/Deassert summary added in 4409594
alongside real fixes for GPU fault handling. It's not part of the Reanimator
hardware-ingest contract (event_logs is the only accepted log channel) and
was silently dropped on import — pure dead weight, removed.

Three related status bugs surfaced while auditing converted exports against
the contract, all specific to Inspur/onekeylog dumps:
- CPU status from RESTful CPU info was parsed but never assigned to
  models.CPU, and was skipped entirely whenever asset.json already supplied
  a CPU list (its own inventory has no status field) — CPUs always exported
  as Unknown even when the source reported OK.
- PCIe device status (RESTful "status": 1) was parsed but never mapped onto
  models.PCIeDevice, so RESTful-only devices always lost status.
- For GPUs specifically, asset.go emits two device records per physical GPU
  (a generic pcie_devices entry enriched with real status, and a separate
  gpus entry with a resolved model name but no status). dedupePCIe picks a
  single winner by quality score, and a better model name outweighed having
  a real status — the winner kept "Unknown" even when a losing duplicate had
  the real value. dedupePCIe now backfills status onto the winner from a
  losing duplicate when the winner's is Unknown.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 12:11:16 +03:00
Mikhail ChusavitinandClaude Sonnet 5 0867123a91 feat(exporter): flag PCIe/GPU/NIC devices with degraded link width as Warning
Applies a single universal check (negotiated LinkWidth < MaxLinkWidth) in
convertPCIeFromDevices, the shared conversion path all vendor parsers feed
into, so a narrower-than-supported link (bad seat, bent connector, wrong
riser) surfaces as a Warning status regardless of which parser produced the
reading — instead of the previous OtrdDiagnoseComponent.json-only check that
only covered the newer HGX dump layout.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 18:15:08 +03:00
Mikhail ChusavitinandClaude Sonnet 5 93f0897b81 fix(exporter): dedup NICs by normalized MAC, fix garbage redis serial fallback
MAC-format mismatches between collector sources (dash vs colon separators)
were preventing duplicate NIC/PCIe entries from merging in the canonical
device dedup pass. Add MAC address normalization and merge devices that
share a normalized MAC before the existing serial/BDF-based dedup runs.

Also fix a bug in the Inspur redis-dump serial fallback parser: when a
field's inline value was the placeholder "N/A", the code incorrectly fell
through to a window-scan fallback that could pick up an unrelated adjacent
Redis key name (e.g. "AssetInfoPCIEMMIOSpace") as a fake serial number.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 18:09:49 +03:00
Mikhail ChusavitinandClaude Sonnet 5 399eca5f49 feat(exporter): collect and export storage.vendor_id/device_id (contract v2.13)
Add PCI Vendor ID / Device ID to hardware.storage[] per the updated Reanimator
ingest contract, mirroring the existing pcie_devices[] fields. Populated for
Redfish-collected NVMe drives (live + TSR replay, via linked PCIeFunctions)
and for Inspur (from asset.json's own PcieInfo[], joined by PcieSlot). Also
fixes canonicalDevicesForExport dropping the fields when converting Storage
into the canonical HardwareDevice list used by the actual export path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 16:04:54 +03:00
Mikhail Chusavitin 063587958e Merge remote-tracking branch 'origin/main'
# Conflicts:
#	bible-local/10-decisions.md
#	internal/chart
#	internal/models/models.go
2026-08-11 12:12:03 +03:00
Mikhail ChusavitinandClaude Sonnet 5 3ab6f28323 chore(chart): bump submodule to licenses section commit
Points internal/chart at reanimator/chart@ba751c8, which adds the
hardware.licenses[] section (preferred order/title/columns) to the
viewer, matching the reanimator export from the previous commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 11:58:19 +03:00
Mikhail ChusavitinandClaude Sonnet 5 eaaf5c09d3 feat(hardware): collect and export licenses via Dell iDRAC10 Redfish walk
Implements the hardware.licenses[] contract section (v2.12, refreshed from
reanimator/core's hardware-ingest-contract.md — was v2.11 locally).

- models.License / HardwareConfig.Licenses mirror the contract field set.
- collector.collectLicenses() reads the standard DMTF
  /redfish/v1/LicenseService/Licenses collection during Redfish-walk replay;
  it's a generic DMTF resource, not Dell-specific, so any future vendor's
  Redfish walk gets license collection for free through
  ReplayRedfishFromRawPayloads.
- vendors/dell merges replayed Licenses like every other category.
- exporter.convertLicenses/dedupeLicenses wire hw.Licenses into the
  reanimator export directly (no canonical-devices merge — licenses have no
  physical identity to merge on), setting Present on every record from the
  start (per the ADL-049 round-trip lesson).
- chart viewer renders a licenses section in /chart/current.

Verified end-to-end on the PowerEdge R7715 (1TVFYL4) TSR: 3 system-level
licenses extracted and correctly exported/rendered.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 11:48:21 +03:00
Mikhail ChusavitinandClaude Sonnet 5 eb6cc207ce fix(exporter): populate Present on exported Memory/PSU so reanimator re-import keeps them
ReanimatorMemory.Present and ReanimatorPSU.Present were already declared as
*bool fields (matching ReanimatorStorage.Present), but convertMemoryFromDevices
and convertPSUsFromDevices never set them, unlike convertStorageFromDevices.
Exported JSON therefore had "present" for storage but not for memory/PSU
items. Re-importing a previously exported reanimator.json via
parseUploadedSnapshot (a direct json.Unmarshal into models.AnalysisResult)
left Present=false on those two categories, and the existing
IsInstalledInventory()/present-required filters then dropped them on the next
/chart/current render — reproduced live: fresh TSR upload showed Memory and
Power Supplies correctly, re-uploading the exported reanimator.json for the
same result did not.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 11:11:39 +03:00
Mikhail ChusavitinandClaude Sonnet 5 f599215760 fix(parser): parse Dell iDRAC10 TSR inventory from captured Redfish walk
iDRAC10-generation TSR bundles no longer ship sysinfo_dcim_view.xml /
sysinfo_dcim_softwareidentity.xml, so the dell parser produced events but
no hardware inventory for them. These bundles instead carry
redfishidracwalk.tar.gz, a captured dump of the iDRAC's own Redfish tree.

Add vendors/redfishtree, a shared helper that reconstructs a path->document
map from a tar.gz/zip-packaged Redfish walk (vendor-independent detection:
path hint + /redfish/v1 service-root/Systems/Chassis structural check) and
replays it through the existing collector.ReplayRedfishFromRawPayloads.
vendors/dell uses it to enrich DCIM-XML-derived data (append-only, existing
dedupe passes resolve overlaps). Also register vendors/redfishwalk, a
low-confidence fallback VendorParser using the same helpers, so any other
vendor that starts shipping this kind of raw Redfish walk is picked up
automatically without a dedicated parser.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 10:49:32 +03:00
Mikhail Chusavitin 6e1a8232ec fix(parser): dedup IDL events by timestamp to stop dropping recurring alarms
ParseIDLLog deduped by eventID|eventType|description, which is identical
across every occurrence of a recurring alarm (e.g. the flapping PCIe
presence check on Inspur HGX boards). That collapsed every later
occurrence into the first one, so applyGPUStatusFromEvents computed GPU
health from a stale, truncated event list and marked failed GPUs as OK.
2026-07-28 19:38:36 +03:00
Mikhail ChusavitinandClaude Sonnet 5 3e7f02e497 chore(releases): remove stale v1.22 release notes
releases/ is gitignored going forward; drop the leftover tracked
v1.22 notes file so the working tree is clean for future releases.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 12:25:50 +03:00
Mikhail ChusavitinandClaude Sonnet 5 5677c49998 fix(parser): support Inspur onekeylog per-file component/*.txt D-Bus layout
Some onekeylog BMC firmware variants split the combined component.log
into per-file D-Bus GetAll transcripts under component/ (e.g.
PowerSupplyInfo.txt, FanInfo.txt), which the inspur parser did not
read, leaving PSU and fan data empty. Add a GETALL block parser and
wire it as a fallback for PSU and fan telemetry when component.log is
absent; document the layout and known gaps in bible-local.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 12:24:17 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 4ce0251ce4 docs(bible-local): add backlog with sfp_modules implementation plan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 18:39:28 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 994d46f3b3 docs: update hardware ingest contract to v2.11
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 18:28:38 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 ee3e8a6e33 docs: release notes for v1.23
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 15:21:35 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 e2c81758b5 fix(parser): raise file size limit for .ahs to 1 GB
AHS files can exceed 100 MB; the previous 10 MB universal cap silently
truncated them and caused incomplete event parsing. Per-extension limits
are now used: .ahs gets 1 GB, all other single-file types keep 10 MB.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 15:20:57 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 6b52a1876f docs: release notes for v1.22
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 15:13:42 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 3e3c48bc08 feat(hpe-ilo): parse AHS files, fix event logs export, add logs CSV export
- HPE iLO AHS parser: handle truncated last entry gracefully, recognize
  Alletra product line, expand event type/severity inference, trim iLO
  frame separators from event messages
- Fix event_logs always 0 in Reanimator export: normalizeEventLogSource
  now maps "HPE iLO" → "bmc"
- Fix chart JS not loading in LOGPile: rewriteChartStaticPaths now also
  rewrites src="/static/view.js" → /chart/static/view.js
- Add "Logs Export" button (CSV, semicolon-delimited, UTF-8 BOM) and
  remove PDF button
- Fix collector test broken by pciids rename of Intel VMD device
- Update submodules: chart v2.7, pciids, bible

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 15:11:46 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 cd864c3d6c docs: release notes for v1.21
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:56:17 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 5128ac5303 fix(server): remove PrintMode from RenderOptions after chart submodule update
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:53:55 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 53cda82c79 chore: update submodules (bible, chart, pciids)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:52:51 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 a18d8fe648 feat(inspur): enrich storage serials from SOLHostCapture.log smartd output
When the BMC HDD API returns an empty array (RAID controller attached via
PCIe, e.g. PM8204-2GB), disk serial numbers are now recovered from smartd
startup messages in SOLHostCapture.log.

Enrichment runs in three passes: model-match on existing slots, positional
fill of empty backplane placeholders, then new entries for any remainder.
Both log/ and runningdata/var/ copies are merged with serial deduplication.

Parser version bumped to 2.1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 17:52:07 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 f3836a34cc chore: update chart submodule to v2.0 and refresh pci.ids (2026-05-21)
chart: feat(viewer): replace severity dropdown with per-column header filters
pci.ids: 2026-02-17 → 2026-05-21

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 14:37:26 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 ba9a52a61a fix(ui): parse-errors panel full width
Removed max-width/padding constraints — panel now stretches to grid
column width like the viewer-panel above it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 14:32:47 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 27373aa104 feat: surface BMC collection errors in parse-errors panel and event log
When Inspur component.log sections return {"error":"...","code":N} instead
of hardware data, the parser now:
- stores them in AnalysisResult.CollectionErrors (new model field)
- mirrors each one into result.Events with Source="BMC/<section>"
  so the chart viewer event table shows the specific BMC module
- feeds them into /api/parse-errors as bmc_collection_error entries

UI adds a collapsible "Collection diagnostics" panel below the chart
iframe (outside /chart) that appears when /api/parse-errors returns
any items; resets on data clear.

Affected sections in this dump: HDD (1458), PCIe Devices (1458),
Network Adapters (1458), Disk Backplane.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 14:30:01 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 4f7b5b826a fix(inspur): fix PSU section regex when PCIE section precedes Network
The PSU regex used "RESTful Network" as its end anchor, but in standard
Inspur component.log layout the PCIE Device section sits between PSU and
Network Adapter. The lazy [\s\S]*? captured across the PCIE error block,
producing invalid JSON and silently dropping all PSU data.

Changed anchor to RESTful (?:PCIE|Network) — matches whichever section
immediately follows PSU in a given archive.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 14:21:13 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 dfd64550cf fix(inspur): infer DIMM size from part number when BMC reports size=0
When BMC firmware fails to read capacity for a present DIMM, size_mb stays
0. If another DIMM with the same part number in the same batch has a known
size, use it to fill the gap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 14:18:15 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 9505303d1d fix(inspur): show microcode version for every CPU, not just the first
Dedup by version caused CPU1 Microcode to be omitted when both CPUs run
the same version, leaving the firmware column blank for the second socket.
Each CPU gets its own firmware entry keyed by index.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 14:15:28 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 f2c04cf0e8 fix(inspur): parse CPUs from component.log and fix DIMM present detection
Two bugs in onekeylog archives that lack asset.json:

- CPU count was always 0: ParseComponentLog never parsed the "RESTful CPU
  info" section. Added parseCPUInfo as a fallback when hw.CPUs is empty
  (asset.json remains the primary source when present). Also worked around
  a Go JSON case-insensitive collision between "proc_id" (int) and
  "PROC_ID" (string CPUID) by adding an explicit PROC_ID field with an
  exact-case tag.

- Only 1 of 2 DIMMs shown: Present condition required mem_mod_size > 0,
  but some BMC firmware reports size=0 for a physically installed module
  while still providing serial and part number. Now treats a DIMM as
  present when status=1 and any of size/serial/partnum is non-empty.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 14:13:55 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 ca457ac72b fix(exporter): propagate iommu_group through PCIe export pipeline
IOMMUGroup was added to models.PCIeDevice but never wired into the
converter — missing from Details in buildDevicesFromLegacy, no field
in ReanimatorPCIe, and convertPCIeFromDevices never read it.

Add IOMMUGroup *int to ReanimatorPCIe, propagate through Details,
add intPtrFromDetailMap helper.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 16:05:30 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 78d0e26fd0 feat: sync with hardware ingest contract v2.10
- PCIeDevice: add model, firmware, present, iommu_group, telemetry fields
  (temperature_c, power_w, ecc_corrected_total, ecc_uncorrected_total,
  hw_slowdown) — were silently dropped on JSON parse, breaking bee audit display
- buildDevicesFromLegacy: use pcie.Model as fallback (PartNumber > Model >
  Description), copy MACAddresses/Present/Firmware, propagate telemetry into
  Details so convertPCIeFromDevices picks them up
- Storage: add logical_block_size_bytes, physical_block_size_bytes,
  metadata_bytes_per_block (contract v2.10, 2026-04-29) to models, exporter
  struct and converter pipeline
- ReanimatorHardware: add platform_config map[string]any (contract v2.9)
- Update internal/chart submodule to v2.0 (contract 2.10 viewer support:
  event_logs section, platform_config section, storage block size columns)
- Update bible submodule

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 15:55:26 +03:00
Mikhail Chusavitin 88e4e8dd49 Trim noisy Lenovo Redfish collection paths 2026-04-30 15:55:26 +03:00
Mikhail Chusavitin cf9cf5d0cf Improve Lenovo XCC inventory enrichment 2026-04-30 15:55:26 +03:00
Mikhail Chusavitin a82fb227e5 submodule update 2026-04-16 15:33:48 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 becdca1d7e fix(redfish): read PCIeInterface link width for GPU PCIe devices
parseGPUWithSupplementalDocs did not read PCIeInterface from the device
doc, only from function docs. xFusion GPU PCIeCard entries carry link
width/speed in PCIeInterface (LanesInUse/Maxlanes/PCIeType/MaxPCIeType)
so GPU link width was always empty for xFusion servers.

Also apply the xFusion OEM function-level fallback for GPU function docs,
consistent with the NIC and PCIeDevice paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 13:35:29 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 e10440ae32 fix(redfish): collect PCIe link width from xFusion servers
xFusion iBMC exposes PCIe link width in two non-standard ways:
- PCIeInterface uses "Maxlanes" (lowercase 'l') instead of "MaxLanes"
- PCIeFunction docs carry width/speed in Oem.xFusion.LinkWidth ("X8"),
  Oem.xFusion.LinkWidthAbility, Oem.xFusion.LinkSpeed, and
  Oem.xFusion.LinkSpeedAbility rather than the standard CurrentLinkWidth int

Add redfishEnrichFromOEMxFusionPCIeLink and parseXFusionLinkWidth helpers,
apply them as fallbacks in NIC and PCIeDevice enrichment paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 13:35:29 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 9df13327aa feat(collect): remove power-on/off, add skip-hung for Redfish collection
Remove power-on and power-off functionality from the Redfish collector;
keep host power-state detection and show a warning in the UI when the
host is powered off before collection starts.

Add a "Пропустить зависшие" (skip hung) button that lets the user abort
stuck Redfish collection phases without losing already-collected data.
Introduces a two-level context model in Collect(): the outer job context
covers the full lifecycle including replay; an inner collectCtx covers
snapshot, prefetch, and plan-B phases only. Closing the skipCh cancels
collectCtx immediately — aborts all in-flight HTTP requests and exits
plan-B loops — then replay runs on whatever rawTree was collected.

Signal path: UI → POST /api/collect/{id}/skip → JobManager.SkipJob()
→ close(skipCh) → goroutine in Collect() → cancelCollect().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 13:12:38 +03:00
Mikhail Chusavitin 7e9af89c46 Add xFusion file-export parser support 2026-04-04 15:07:10 +03:00
Mikhail Chusavitin db74df9994 fix(redfish): trim MSI replay noise and unify NIC classes 2026-04-01 17:49:00 +03:00
Mikhail Chusavitin bb82387d48 fix(redfish): narrow MSI PCIeFunctions crawl 2026-04-01 16:50:51 +03:00
Mikhail Chusavitin 475f6ac472 fix(export): keep storage inventory without serials 2026-04-01 16:50:19 +03:00
Mikhail Chusavitin 93ce676f04 fix(redfish): recover MSI NIC serials from PCIe functions 2026-04-01 15:48:47 +03:00
Mikhail Chusavitin c47c34fd11 feat(hpe): improve inventory extraction and export fidelity 2026-03-30 15:04:17 +03:00
Mikhail Chusavitin d8c3256e41 chore(hpe_ilo_ahs): normalize module version format — v1.0 2026-03-30 13:43:10 +03:00
Mikhail Chusavitin 1b2d978d29 test: add real fixture coverage for HPE AHS parser 2026-03-30 13:41:02 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 0f310d57c4 feat: HPE iLO support — profile, post-probe hang fix, replay parser fixes, AHS parser
- Add HPE iLO Redfish profile (priority 20): matches on manufacturer/OEM/iLO signals,
  adds SmartStorage/SmartStorageConfig to critical paths, sets realistic ETA baseline
  and rate policy for iLO's known slowness
- Fix post-probe hang on HPE iLO: skip numeric probing of collections where
  Members@odata.count == len(Members); add 4s postProbeClient timeout as safety net
- Exclude /WorkloadPerformanceAdvisor from crawl paths
- Fix replay parser: skip absent CPU sockets, absent DIMM slots, absent drive bays
- Filter N/A version entries from firmware inventory
- Remove drive firmware from general firmware list (already in Storage[].Firmware)
- Add HPE AHS (.ahs) archive parser with hybrid SMBIOS/Redfish extraction

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 13:39:14 +03:00
Mikhail Chusavitin 3547ef9083 Skip placeholder firmware versions in API output 2026-03-26 18:42:54 +03:00
Mikhail Chusavitin 99f0d6217c Improve Multillect Redfish replay and power detection 2026-03-26 18:41:02 +03:00
Mikhail Chusavitin 8acbba3cc9 feat: add reanimator easy bee parser 2026-03-25 19:36:13 +03:00
Mikhail Chusavitin 8942991f0c Add Inspur Group OEM Redfish profile 2026-03-25 15:08:40 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 9b71c4a95f chore: update bible submodule
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 11:22:33 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 125f77ef69 feat: adaptive BMC readiness check + ghost NIC dedup fix + empty collection plan-B retry
BMC readiness after power-on (waitForStablePoweredOnHost):
- After initial 1m stabilization, poll BMC inventory readiness before collecting
- Ready if MemorySummary.TotalSystemMemoryGiB > 0 OR PCIeDevices.Members non-empty
- On failure: wait +60s, retry; on second failure: wait +120s, retry; then warn and proceed
- Configurable via LOGPILE_REDFISH_BMC_READY_WAITS (default: 60s,120s)

Empty critical collection plan-B retry (EnableEmptyCriticalCollectionRetry):
- Hardware inventory collections that returned Members=[] are now re-probed in plan-B
- Covers PCIeDevices, NetworkAdapters, Processors, Drives, Storage, EthernetInterfaces
- Enabled by default in generic profile (applies to all vendors)

Ghost NIC dedup fix (enrichNICsFromNetworkInterfaces):
- NetworkInterface entries (e.g. Id=2) that don't match existing NIC slots are now
  resolved via Links.NetworkAdapter cross-reference to the real Chassis NIC
- Prevents duplicate ghost entries (slot=2 "Network Device View") from appearing
  alongside real NICs (slot="RISER 5 slot 1 (7)") with the same MAC addresses

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 11:19:36 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 063b08d5fb feat: redesign collection UI + add StopHostAfterCollect + TCP ping pre-probe
- Single "Подключиться" button flow: probe first, then show collect options
- Power management checkboxes: power on before / stop after collect
- Modal confirmation when enabling shutdown on already-powered-on host
- StopHostAfterCollect flag: host shuts down only when explicitly requested
- TCP ping (10 attempts, min 3 successes) before Redfish probe
- Debug payloads checkbox (Oem/Ami/Inventory/Crc, off by default)
- Remove platform_config BIOS settings collection (unreliable on AMI)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 18:50:01 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 e3ff1745fc feat: clean up collection job log UI
- Filter out debug noise (plan-B per-path lines, heartbeats, timing stats, telemetry)
- Strip server-side nanosecond timestamp prefix from displayed messages
- Transform snapshot progress lines to show current path instead of doc count + ETA
- Humanize recurring message patterns (plan-B summary, prefetch, snapshot total)
- Raw collect.log and raw_export.json are unaffected

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 00:50:13 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 96e65d8f65 feat: Redfish hardware event log collection + MSI ghost GPU filter + inventory improvements
- Collect hardware event logs (last 7 days) from Systems and Managers/SEL LogServices
- Parse AMI raw IPMI dump messages into readable descriptions (Sensor_Type: Event_Type)
- Filter out audit/journal/non-hardware log services; only SEL from Managers
- MSI ghost GPU filter: exclude processor GPU entries with temperature=0 when host is powered on
- Reanimator collected_at uses InventoryData/Status.LastModifiedTime (30-day fallback)
- Invalidate Redfish inventory CRC groups before host power-on
- Log inventory LastModifiedTime age in collection logs
- Drop SecureBoot collection (SecureBootMode, SecureBootDatabases) — not hardware inventory
- Add build version to UI footer via template
- Add MSI Redfish API reference doc to bible-local/docs/

ADL-032–ADL-035

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 23:47:22 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 30409eef67 feat: add xFusion iBMC dump parser (tar.gz format)
Parses xFusion G5500 V7 iBMC diagnostic dump archives with:
- FRU info (board serial, product name, component inventory)
- IPMI sensor readings (temperature, voltage, power, fan, current)
- CPU inventory (model, cores, threads, cache, serial)
- Memory DIMMs (size, speed, type, serial, manufacturer)
- GPU inventory from card_manage/card_info (serial, firmware, ECC counts)
- OCP NIC detection (ConnectX-6 Lx with serial)
- PSU inventory (4x 3000W, serial, firmware, voltage)
- Storage: RAID controller firmware + physical drives (model, serial, endurance)
- iBMC maintenance log events with severity mapping
- Registers as vendor "xfusion" in the parser registry

All 11 fixture tests pass against real G5500 V7 dump archive.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 15:31:28 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 65e65968cf feat: add xFusion iBMC Redfish profile
Matches on ServiceRootVendor "xFusion" and OEM namespace "xFusion"
(score 90+). Enables GenericGraphicsControllerDedup unconditionally and
ProcessorGPUFallback when GPU-type processors are present in the snapshot
(xFusion G5500 V7 exposes H200s simultaneously in PCIeDevices,
GraphicsControllers, and Processors/Gpu* — all three need dedup).

Without this profile, xFusion fell into fallback mode which activated all
vendor profiles (Supermicro, HGX, MSI, Dell) unnecessarily. Now resolves
to matched mode with targeted acquisition tuning (120k cap, 75s baseline).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 15:13:15 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 380c199705 chore: update chart submodule
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 08:50:56 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 d650a6ba1c refactor: unified ingest pipeline + modular Redfish profile framework
Implement the full architectural plan: unified ingest.Service entry point
for archive and Redfish payloads, modular redfishprofile package with
composable profiles (generic, ami-family, msi, supermicro, dell,
hgx-topology), score-based profile matching with fallback expansion mode,
and profile-driven acquisition/analysis plans.

Vendor-specific logic moved out of common executors and into profile hooks.
GPU chassis lookup strategies and known storage recovery collections
(IntelVROC/HA-RAID/MRVL) now live in ResolvedAnalysisPlan, populated by
profiles at analysis time. Replay helpers read from the plan; no hardcoded
path lists remain in generic code.

Also splits redfish_replay.go into domain modules (gpu, storage, inventory,
fru, profiles) and adds full fixture/matcher/directive test coverage
including Dell, AMI, unknown-vendor fallback, and deterministic ordering.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 08:48:58 +03:00
Mikhail Chusavitin d8d3d8c524 build: use local go toolchain in release script 2026-03-16 00:32:09 +03:00
Mikhail Chusavitin 057a222288 ui: embed reanimator chart viewer 2026-03-16 00:20:11 +03:00
Mikhail Chusavitin f11a43f690 export: merge inspur psu sensor groups 2026-03-15 23:29:44 +03:00
Mikhail Chusavitin 476630190d export: align reanimator contract v2.7 2026-03-15 23:27:32 +03:00
Mikhail Chusavitin 9007f1b360 export: align reanimator and enrich redfish metrics 2026-03-15 21:38:28 +03:00
Mikhail Chusavitin 0acdc2b202 docs: refresh project documentation 2026-03-15 16:35:16 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 47bb0ee939 docs: document firmware filter regression pattern in bible (ADL-019)
Root cause analysis for device-bound firmware leaking into hardware.firmware
on Supermicro Redfish (SYS-A21GE-NBRT HGX B200):

- collectFirmwareInventory (6c19a58) had no coverage for Supermicro naming.
  isDeviceBoundFirmwareName checked "gpu " / "nic " (space-terminated) while
  Supermicro uses "GPU1 System Slot0" / "NIC1 System Slot0 ..." (digit suffix).

- 9c5512d added _fw_gpu_ / _fw_nvswitch_ / _inforom_gpu_ patterns to fix HGX,
  but checked DeviceName which contains "Software Inventory" (from Redfish Name),
  not the firmware Id. Dead code from day one.

09-testing.md: add firmware filter worked example and rule #4 — verify the
filter checks the field that the collector actually populates.

10-decisions.md: ADL-019 — isDeviceBoundFirmwareName must be extended per
vendor with a test case per vendor format before shipping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 14:03:47 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 5815100e2f exporter: filter Supermicro Redfish device-bound firmware from hardware.firmware
isDeviceBoundFirmwareName did not catch Supermicro FirmwareInventory naming
conventions where a digit follows the type prefix directly ("GPU1 System Slot0",
"NIC1 System Slot0 AOM-DP805-IO") instead of a space. Also missing: "Power supply N",
"NVMeController N", and "Software Inventory" (generic label for all HGX per-component
firmware slots — GPU, NVSwitch, PCIeRetimer, ERoT, InfoROM, etc.).

On SYS-A21GE-NBRT (HGX B200) this caused 29 device-bound entries to leak into
hardware.firmware: 8 GPU, 9 NIC, 1 NVMe, 6 PSU, 4 PCIeSwitch, 1 Software Inventory.

Fix: extend isDeviceBoundFirmwareName with patterns for all four new cases.
Add TestIsDeviceBoundFirmwareName covering both excluded and kept entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 13:48:55 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 1eb639e6bf redfish: skip NVMe bay probe for non-storage chassis types (Module/Component/Zone)
On Supermicro HGX systems (SYS-A21GE-NBRT) ~35 sub-chassis (GPU, NVSwitch,
PCIeRetimer, ERoT/IRoT, BMC, FPGA) all carry ChassisType=Module/Component/Zone
and expose empty /Drives collections. shouldAdaptiveNVMeProbe returned true for
all of them, triggering 35 × 384 = 13 440 HTTP requests → ~22 min wasted per
collection (more than half of total 35 min collection time).

Fix: chassisTypeCanHaveNVMe returns false for Module, Component, Zone. The
candidate selection loop in collectRawRedfishTree now checks the parent chassis
doc before adding a /Drives path to the probe list. Enclosure (NVMe backplane),
RackMount, and unknown types are unaffected.

Tests:
- TestChassisTypeCanHaveNVMe: table-driven, covers excluded and storage-capable types
- TestNVMePostProbeSkipsNonStorageChassis: topology integration, GPU chassis +
  backplane with empty /Drives → exactly 1 candidate selected (backplane only)

Docs:
- ADL-018 in bible-local/10-decisions.md
- Candidate-selection test matrix in bible-local/09-testing.md
- SYS-A21GE-NBRT baseline row in docs/test_server_collection_memory.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 13:38:29 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 a9f58b3cf4 redfish: fix GPU duplication on Supermicro HGX, exclude NVSwitch, restore path dedup
Three bugs, all related to GPU dedup in the Redfish replay pipeline:

1. collectGPUsFromProcessors (redfish_replay.go): GPU-type Processor entries
   (Systems/HGX_Baseboard_0/Processors/GPU_SXM_N) were not deduplicated against
   existing PCIeDevice GPUs on Supermicro HGX. The chassis-ID lookup keyed on
   processor Id ("GPU_SXM_1") but the chassis is named "HGX_GPU_SXM_1" — lookup
   returned nothing, serial stayed empty, UUID was unseen → 8 duplicate GPU rows.
   Fix: read SerialNumber directly from the Processor doc first; chassis lookup
   is now a fallback override (as it was designed for MSI).

2. looksLikeGPU (redfish.go): NVSwitch PCIe devices (Model="NVSwitch",
   Manufacturer="NVIDIA") were classified as GPUs because "nvidia" matched the
   GPU hint list. Fix: early return false when Model contains "nvswitch".

3. gpuDocDedupKey (redfish.go): commit 9df29b1 changed the dedup key to prefer
   slot|model before path, which collapsed two distinct GPUs with identical model
   names in GraphicsControllers into one entry. Fix: only serial and BDF are used
   as cross-path stable dedup keys; fall back to Redfish path when neither is
   present. This also restores TestReplayCollectGPUs_DedupUsesRedfishPathBeforeHeuristics
   which had been broken on main since 9df29b1.

Added tests:
- TestCollectGPUsFromProcessors_SupermicroHGX: Processor GPU dedup when
  chassis-ID naming convention does not match processor Id
- TestReplayCollectGPUs_DedupCrossChassisSerial: same GPU via two Chassis
  PCIeDevice trees with matching serials → collapsed to one
- TestLooksLikeGPU_NVSwitchExcluded: NVSwitch is not a GPU

Added rule to bible-local/09-testing.md: dedup/filter/classify functions must
cover true-positive, true-negative, and the vendor counter-case axes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 15:09:27 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 d8ffe3d3a5 redfish: add service root to critical endpoints, tolerate missing root in replay
Add /redfish/v1 to redfishCriticalEndpoints so plan-B retries the service
root if it failed during the main crawl. Also downgrade the missing-root
error in ReplayRedfishFromRawPayloads from fatal to a warning so analysis
can complete with defaults when the root doc was not recovered.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 08:31:00 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 9df29b1be9 fix: dedup GPUs across multiple chassis PCIeDevice trees in Redfish collector
Supermicro HGX exposes each GPU under both Chassis/1/PCIeDevices and a
dedicated Chassis/HGX_GPU_SXM_N/PCIeDevices. gpuDocDedupKey was keying
by @odata.id path, so identical GPUs with the same serial were not
deduplicated across sources. Now stable identifiers (serial → BDF →
slot+model) take priority over path.

Also includes Inspur parser improvements: NVMe model/serial enrichment
from devicefrusdr.log and audit.log, RAID drive slot normalization to
BP notation, PSU slot normalization, BMC/CPLD/VR firmware from RESTful
version info section, and parser version bump to 1.8.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 14:44:36 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 62d6ad6f66 ui: deduplicate files by name and SHA-256 hash before batch convert
On folder selection, filter out duplicate files before conversion:
- First pass: same basename → skip (same filename in different subdirs)
- Second pass: same SHA-256 hash → skip (identical content, different path)

Duplicates are excluded from the convert queue and shown as a warning
in the summary with reason (same name / same content).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 12:45:09 +03:00
Mikhail ChusavitinandClaude Sonnet 4.6 f09344e288 dell: filter chipset/embedded noise from PCIe device list
Skip FQDD prefixes that are internal AMD EPYC fabric or devices
already captured with richer data from other DCIM views:
- HostBridge/P2PBridge/ISABridge/SMBus.Embedded: AMD internal bus
- AHCI.Embedded: AMD FCH SATA (chipset, not a slot)
- Video.Embedded: BMC Matrox G200eW3, not user-visible
- NIC.Embedded: duplicates DCIM_NICView entries (no model/MAC in PCIe view)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 12:09:40 +03:00
Mikhail Chusavitin ddab93a5ee Add release notes for v1.7.0 2026-02-25 13:31:54 +03:00
Mikhail Chusavitin 000199fbdc Add parse errors tab and improve error diagnostics UI 2026-02-25 13:28:19 +03:00
Mikhail Chusavitin 68592da9f5 Harden Redfish collection for slow BMC endpoints 2026-02-25 12:42:43 +03:00
Mikhail Chusavitin b1dde592ae Expand Redfish best-effort snapshot crawling 2026-02-25 12:24:06 +03:00
Mikhail Chusavitin 693b7346ab Update docs and add release artifacts 2026-02-25 12:17:17 +03:00