# Fi-Wi framework — design

This document is for engineers changing or extending the Fi-Wi code. For command syntax, see [fiwi-cli.md](fiwi-cli.md). For automation and “test case” style usage, see [fiwi-test-authoring.md](fiwi-test-authoring.md).

## Purpose

The Fi-Wi stack ties together **USB power-control hubs** (BrainStem API), a **patch panel** model, and a **fiber map** (`fiber_map.json`) so operators can discover hubs, power downstream ports, walk calibration, and record per-fiber metadata (SSH routing, wireless, optional PCIe hints). Commands may run **locally** (Python loads BrainStem) or **on a remote host** over SSH when the map or CLI says the hardware lives elsewhere.

## Repository layout

| Piece | Role |
|--------|------|
| `fiwi.py` | Entry point; configures `fiwi.paths` with the install directory, then runs `fiwi.cli.main`. |
| `fiwi/` | Library: concentrator, SSH transport, fiber map I/O, USB/wireless probes, diagnostics. |
| `fiber_map.json` | Lives next to `fiwi.py` (see `fiwi.paths`). Operator-edited or calibrate-produced. |
| `config/*.ini` | Optional profiles under `config/` (`default.ini` when `FIWI_CONFIG` unset). `[remote_hubs] hosts` sets `FIWI_REMOTE_HUBS` (merged with `FIWI_CALIBRATE_REMOTES` for panel calibrate). Merged after `remote_ssh.env` via `setdefault`. |
| `remote_ssh.env` / `.fiwi_remote` | Optional dotenv next to the install; merged into process env for SSH defaults (see `SshNodeConfig`). |

## Core components

- **`FiWiConcentrator`** (`fiwi/concentrator.py`): Main Fi-Wi object — BrainStem discovery, power, reboot, panel + fiber workflows, and **panel calibrate** (interactive and hybrid local/remote ordering).
- **`FiberRadioPort`** (`fiwi/fiber_radio_port.py`): View of one `fiber_ports[]` entry: power routing, SSH node resolution, previews for map-driven UIs.
- **`SshNode` / `SshNodeConfig`** (`fiwi/ssh.py`): Builds `ssh` argv (optional `FIWI_SSH_OPTS`), runs remote `FIWI_REMOTE_PYTHON` + `FIWI_REMOTE_SCRIPT` with forwarded subcommands, or **raw** `ssh target …` for helpers like `dmesg` / `lspci` in diagnostics. Supports **deferred** capture (`RemoteCallHandle`, `asyncio.Task`) when `defer=True` or `FIWI_REMOTE_DEFER` / `--async` so overlapping subprocesses do not require Python threads.
- **`ssh_dispatch`** (`fiwi/ssh_dispatch.py`): Early CLI path: if `fiber_map.json` routes a **power fiber-port** (or certain fiber flows) to another host, dispatch runs `SshNode.invoke` **without** importing BrainStem on the workstation.
- **`fiber_map_io`**: Load/save map, PCIe prompt helpers during calibrate, previews.
- **`patch_panel`**: Effective front-panel port count from the map, or ``default_ports`` from config / env.
- **`ieee80211_dev` / `usb_probe`**: Machine-readable snapshots used by calibrate (including over SSH via `wlan-info-json`, `lsusb-lines-json`).

## Data flow

1. **Local BrainStem path**: `fiwi.cli.main` loads BrainStem, constructs `FiWiConcentrator`, runs subcommand.
2. **Fiber-mapped SSH path**: Before BrainStem load, `dispatch_fiber_mapped_ssh_if_needed` may forward specific argv patterns based on the map.
3. **Explicit `--ssh user@host`**: Runs `SshNode.invoke` with TTY-friendly SSH when needed; no local BrainStem required for that invocation.
4. **Hybrid calibrate**: Local hub/port list first, then each remote host’s list (from `--ssh`, `calibrate_remotes` in JSON, or `FIWI_CALIBRATE_REMOTES`). Remote enumeration uses `calibrate-ports-json` or `discover` fallback on the remote.

## Diagnostic timeline (`fiwi/diag_log.py`)

A **central, append-only log** records ordered events (`NoteEvent`, `DmesgEvent`, `PcieEvent`, `KernelDumpEvent`) with wall-clock timestamps. JSONL export is a straight `dataclasses.asdict` per line. **Kernel crash dump collection is not implemented**; `KernelDumpEvent` and `alog_kernel_dump` / `kernel_dump_event` exist so future kdump/vmcore steps append to the same timeline without changing `DiagLog` storage.

## Extension points

- New **CLI subcommands**: `fiwi/cli.py` dispatch; heavy logic stays in `FiWiConcentrator` or focused modules.
- New **map-driven behavior**: extend `fiber_ports` schema carefully; teach `FiberRadioPort` / `ssh_dispatch` if routing changes.
- New **remote machine-readable commands**: add branches in `fiwi/cli.py` (remote runs the same script).
- New **diagnostic event kinds**: add a frozen dataclass, widen `DiagEvent`, keep `dump_jsonl` as dict-per-line.

## Dependencies and constraints

- BrainStem Python API is required for local hub control paths.
- Remote hosts need a working `fiwi.py` (or configured script path), udev for hubs where applicable, and consistent `fiber_map` semantics so SSH forwarding does not loop.
