Gunnar

nordisk/facett

.nornir/facett-error-codes-registry.md

# facett UI error-code registry — THE LIST

<!-- GENERATED FILE — do not hand-edit.
     Regenerate: cargo run -p facett-core --bin errcode_registry_md > .nornir/facett-error-codes-registry.md
     Source of truth: facett-core/src/errcode.rs (errcode::REGISTRY). -->

The canonical catalog of every `facet-<component>-<n>` code. **Append-only / frozen:**
an `<n>` is assigned once and never reused. The uniqueness guard (`errcode` tests)
fails the build on any repeat.

* **Source base:** `https://gunnar.rs/nordisk/facett/blob/main/`
* **status:** `wired` = raised at a real pane site today (a11y code + `Severity::Error` when empty, `error_code` in `state_json`, a `severity()` override, pink code on painter panes). `reserved` = catalogued, unique, guard-checked and shown in the matrix slide, awaiting an explicit failure branch on that load / GPU-fallback path.
* **reaction (Phase 2):** what a CONSUMER must do when the code is raised — the vocabulary is `facett_core::errcode::Reaction`. This is what the (code × mount) reaction tests assert, never a string match.
* **consumer mounts:** the `app/surface` mount points that react. A consumer namespaces the code with its mount, e.g. `korp/cases:facet-map-2` vs `korp/infra:facet-map-2` — same facet code, distinct mount points a robot test pins apart.

**Totals:** 14 components, 43 codes — **15 wired**, **28 reserved**. Reaction matrix: **31 (code × mount) pairs**.

| component | code | visible message | source | status | reaction (Phase 2) | consumer mounts |
|-----------|------|-----------------|-----------------|--------|--------------------|------------------|
| map | `facet-map-1` | map basemap tiles did not load | facett-map/src/lib.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | `korp/infra, korp/cases` |
| map | `facet-map-2` | map has no vessels / no positions to plot | facett-map/src/lib.rs | wired | `empty_state` — show an honest empty state — never a blank pane | `korp/infra, korp/cases` |
| map | `facet-map-3` | map GPU renderer not present — CPU painter fallback | facett-map/src/gpu/mod.rs | reserved | `fallback` — note the degrade in diagnostics; keep working on the slow path | `korp/infra, korp/cases` |
| map | `facet-map-4` | map vessel/position source could not be read — the plot is empty because the READ failed, not because there are no vessels | facett-map/src/lib.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | — (none today) |
| map3d | `facet-map3d-1` | 3D map has no ways/buildings to extrude | facett-map3d/src/lib.rs | wired | `empty_state` — show an honest empty state — never a blank pane | `korp/infra` |
| map3d | `facet-map3d-2` | 3D map GPU depth renderer not present — CPU depth-sort fallback | facett-map3d/src/gpu.rs | reserved | `fallback` — note the degrade in diagnostics; keep working on the slow path | `korp/infra` |
| map3d | `facet-map3d-3` | 3D map terrain/relief tile did not load | facett-map3d/src/lib.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | `korp/infra` |
| map3d | `facet-map3d-4` | 3D map ways/buildings source could not be read — nothing is extruded because the READ failed, not because the area is empty | facett-map3d/src/lib.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | — (none today) |
| geomap | `facet-geomap-1` | geomap GeoParquet source did not load | facett-geomap/src/lib.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | `korp/infra` |
| geomap | `facet-geomap-2` | geomap has no points / hotspots in view | facett-geomap/src/lib.rs | wired | `empty_state` — show an honest empty state — never a blank pane | `korp/infra` |
| geomap | `facet-geomap-3` | geomap tile fetch did not complete | facett-geomap/src/osm2d.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | `korp/infra` |
| osm | `facet-osm-1` | OSM WKB geometry of an unsupported type was refused — those features are missing because the DECODER could not read them, not because the area is empty | facett-osm/src/wkb.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | — (none today) |
| osm | `facet-osm-2` | OSM WKB blob disagrees with its own header — it ended inside a promised field, opened with a bad byte-order byte, or left bytes over after the geometry | facett-osm/src/wkb.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | — (none today) |
| graph | `facet-graph-1` | graph has an empty scene — no nodes to draw | facett-graph/src/lib.rs | wired | `empty_state` — show an honest empty state — never a blank pane | — (none today) |
| graph | `facet-graph-2` | graph scene source could not be read — the pane is empty because the READ failed, not because the graph has no nodes | facett-graph/src/lib.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | — (none today) |
| graph3d | `facet-graph3d-1` | graph3d has no nodes to render | facett-graph3d/src/lib.rs | wired | `empty_state` — show an honest empty state — never a blank pane | `korp/infra, nornir/viz` |
| graph3d | `facet-graph3d-2` | graph3d GPU instanced-cloud renderer not present — CPU painter fallback | facett-graph3d/src/lib.rs | reserved | `fallback` — note the degrade in diagnostics; keep working on the slow path | `korp/infra, nornir/viz` |
| graph3d | `facet-graph3d-3` | graph3d force layout did not converge (degenerate positions) | facett-graph3d/src/lib.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | `korp/infra, nornir/viz` |
| graph3d | `facet-graph3d-4` | graph3d node source could not be read — the cloud is empty because the READ failed, not because the graph has no nodes | facett-graph3d/src/lib.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | — (none today) |
| graph3d | `facet-graph3d-5` | graph3d host placement (layout `given`) does not cover every node — the grid lattice drew it instead | facett-graph3d/src/lib.rs | wired | `fallback` — note the degrade in diagnostics; keep working on the slow path | `korp/infra` |
| graphview | `facet-graphview-1` | graphview has an empty scene — nothing to lay out | facett-graphview/src/metro.rs | wired | `empty_state` — show an honest empty state — never a blank pane | `nornir/viz, dwarves/funnel` |
| graphview | `facet-graphview-2` | graphview L0 CPU raster produced no pixels | facett-graphview/src/lib.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | `nornir/viz, dwarves/funnel` |
| graphview | `facet-graphview-3` | graphview graph source did not load | facett-graphview/src/falkor.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | `nornir/viz, dwarves/funnel` |
| population | `facet-population-1` | population query returned no people at this scale/filter | facett-demo/src/pop_tab.rs | wired | `empty_state` — show an honest empty state — never a blank pane | — (none today) |
| population | `facet-population-2` | population model could not build the sample | facett-demo/src/pop_model.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | — (none today) |
| systemmap | `facet-systemmap-1` | system map has no components/pipes to draw | facett-graph3d/src/pipes.rs | wired | `empty_state` — show an honest empty state — never a blank pane | — (none today) |
| systemmap | `facet-systemmap-2` | system map fluid solver diverged (non-finite state) | facett-cfd/src/lib.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | — (none today) |
| systemmap | `facet-systemmap-3` | system map topology source could not be read — nothing is drawn because the READ failed, not because the system is empty | facett-graph3d/src/pipes.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | — (none today) |
| syschart | `facet-syschart-1` | system chart has no peers to show | facett-syschart/src/lib.rs | wired | `empty_state` — show an honest empty state — never a blank pane | `holger/mannequin` |
| syschart | `facet-syschart-2` | system chart peer reported an error badge | facett-syschart/src/lib.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | `holger/mannequin` |
| syschart | `facet-syschart-3` | system chart peer roster could not be read — the chart is empty because the READ failed, not because there are no peers | facett-syschart/src/lib.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | — (none today) |
| cfd | `facet-cfd-1` | fluid step produced a non-finite cell (NaN/Inf) | facett-cfd/src/lib.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | — (none today) |
| cfd | `facet-cfd-2` | fluid pipe network is empty — nothing to simulate | facett-cfd/src/lib.rs | wired | `empty_state` — show an honest empty state — never a blank pane | — (none today) |
| korp | `facet-korp-1` | korp backend connection not established | facett-korp/src/lib.rs | wired | `reconnect` — surface the disconnected state + a reconnect action | `korp/cases, korp/analysis` |
| korp | `facet-korp-2` | korp case view has no cases to display | facett-korp/src/search.rs | wired | `empty_state` — show an honest empty state — never a blank pane | `korp/cases, korp/analysis` |
| korp | `facet-korp-3` | korp case query failed on a LIVE connection — the list is empty because the QUERY failed, not because there are no cases | facett-korp/src/search.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | — (none today) |
| korp | `facet-korp-4` | korp backend REFUSED the connection — nothing is listening at the endpoint | facett-korp/src/lib.rs | reserved | `reconnect` — surface the disconnected state + a reconnect action | — (none today) |
| korp | `facet-korp-5` | korp backend did not answer in time — it is listening but not responding | facett-korp/src/lib.rs | reserved | `retry` — re-attempt the load (with backoff) + show a retry affordance | — (none today) |
| korp | `facet-korp-6` | korp backend REJECTED the identity — connected, but not authorised; retrying will not help | facett-korp/src/lib.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | — (none today) |
| demo | `facet-demo-1` | example error: a triggered demo condition (showcase) | facett-demo/src/errcode_tab.rs | wired | `diagnose` — record a diagnostic with the code + surface the fault to the operator | — (none today) |
| demo | `facet-demo-2` | example note: a triggered demo degrade (showcase) | facett-demo/src/errcode_tab.rs | wired | `fallback` — note the degrade in diagnostics; keep working on the slow path | — (none today) |
| gpu | `facet-gpu-1` | no GPU adapter enumerated — facett has no render lane | facett-core/src/render/gpu/adapter_wgpu.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | — (none today) |
| gpu | `facet-gpu-2` | every GPU adapter was rejected (software rasteriser / management console) | facett-core/src/render/gpu/adapter_wgpu.rs | reserved | `diagnose` — record a diagnostic with the code + surface the fault to the operator | — (none today) |

## The reaction MATRIX (Phase 2 test table)

Every row below is one `(code × mount)` pair the consumer reaction tests assert.
The test harness is TABLE-DRIVEN over `errcode::reaction_matrix()`, so adding a code
(or a mount) adds rows — never a hand-written copy.

| mounted code | base code | mount | expected reaction |
|--------------|-----------|-------|-------------------|
| `korp/infra:facet-map-1` | `facet-map-1` | `korp/infra` | `retry` |
| `korp/cases:facet-map-1` | `facet-map-1` | `korp/cases` | `retry` |
| `korp/infra:facet-map-2` | `facet-map-2` | `korp/infra` | `empty_state` |
| `korp/cases:facet-map-2` | `facet-map-2` | `korp/cases` | `empty_state` |
| `korp/infra:facet-map-3` | `facet-map-3` | `korp/infra` | `fallback` |
| `korp/cases:facet-map-3` | `facet-map-3` | `korp/cases` | `fallback` |
| `korp/infra:facet-map3d-1` | `facet-map3d-1` | `korp/infra` | `empty_state` |
| `korp/infra:facet-map3d-2` | `facet-map3d-2` | `korp/infra` | `fallback` |
| `korp/infra:facet-map3d-3` | `facet-map3d-3` | `korp/infra` | `retry` |
| `korp/infra:facet-geomap-1` | `facet-geomap-1` | `korp/infra` | `retry` |
| `korp/infra:facet-geomap-2` | `facet-geomap-2` | `korp/infra` | `empty_state` |
| `korp/infra:facet-geomap-3` | `facet-geomap-3` | `korp/infra` | `retry` |
| `korp/infra:facet-graph3d-1` | `facet-graph3d-1` | `korp/infra` | `empty_state` |
| `nornir/viz:facet-graph3d-1` | `facet-graph3d-1` | `nornir/viz` | `empty_state` |
| `korp/infra:facet-graph3d-2` | `facet-graph3d-2` | `korp/infra` | `fallback` |
| `nornir/viz:facet-graph3d-2` | `facet-graph3d-2` | `nornir/viz` | `fallback` |
| `korp/infra:facet-graph3d-3` | `facet-graph3d-3` | `korp/infra` | `diagnose` |
| `nornir/viz:facet-graph3d-3` | `facet-graph3d-3` | `nornir/viz` | `diagnose` |
| `korp/infra:facet-graph3d-5` | `facet-graph3d-5` | `korp/infra` | `fallback` |
| `nornir/viz:facet-graphview-1` | `facet-graphview-1` | `nornir/viz` | `empty_state` |
| `dwarves/funnel:facet-graphview-1` | `facet-graphview-1` | `dwarves/funnel` | `empty_state` |
| `nornir/viz:facet-graphview-2` | `facet-graphview-2` | `nornir/viz` | `diagnose` |
| `dwarves/funnel:facet-graphview-2` | `facet-graphview-2` | `dwarves/funnel` | `diagnose` |
| `nornir/viz:facet-graphview-3` | `facet-graphview-3` | `nornir/viz` | `retry` |
| `dwarves/funnel:facet-graphview-3` | `facet-graphview-3` | `dwarves/funnel` | `retry` |
| `holger/mannequin:facet-syschart-1` | `facet-syschart-1` | `holger/mannequin` | `empty_state` |
| `holger/mannequin:facet-syschart-2` | `facet-syschart-2` | `holger/mannequin` | `diagnose` |
| `korp/cases:facet-korp-1` | `facet-korp-1` | `korp/cases` | `reconnect` |
| `korp/analysis:facet-korp-1` | `facet-korp-1` | `korp/analysis` | `reconnect` |
| `korp/cases:facet-korp-2` | `facet-korp-2` | `korp/cases` | `empty_state` |
| `korp/analysis:facet-korp-2` | `facet-korp-2` | `korp/analysis` | `empty_state` |

## How a consumer reacts

```rust
// The consumer catches a facett error, namespaces it with ITS mount, records the
// MOUNTED code into its own diagnostics, and reacts per the canonical table.
let reaction = errcode::reaction_for(&mounted_code).expect("a registered code");
match reaction {
    Reaction::EmptyState => show_honest_empty_state(),
    Reaction::Retry      => retry_with_backoff(),
    Reaction::Reconnect  => surface_reconnect_action(),
    Reaction::Fallback   => note_degrade_and_keep_working(),
    Reaction::Diagnose   => record_diagnostic_and_surface_fault(),
}
// The robot test pins the REACTION for the MOUNTED code — never a matched string:
assert_eq!(reaction_for("korp/cases:facet-map-2"), Some(Reaction::EmptyState));
```