py/facett_demo/panes/errcode_pane.py
"""ERROR-CODES pane — the Python/Streamlit mirror of facett-demo's ``Errors`` tab.
LAW #2: a facett component that lands in facett-demo lands HERE too, in lockstep.
This pane is the Streamlit counterpart of the native error-code showcase:
* the ``facet-<component>-<n>`` catalog (component → code → message → source
source → status → the Phase-2 consumer REACTION),
* the Phase-2 **reaction matrix** — every ``(code × mount)`` pair the consumer
robot tests assert,
* the triggered example errors rendered with their code in **CLEAR PINK**, exactly
like the native demo's debug build.
ONE SOURCE OF TRUTH: the catalog is NOT re-authored here. It is read from
``errcodes.json``, generated from the compiled Rust ``facett_core::errcode::REGISTRY``
(``cargo run -p facett-core --bin errcode_registry_json``), so the two demos can never
disagree about which codes exist or how a consumer must react.
Both matrices are mounted as the REAL facett ``table`` component (via
``facet-wrapped``), not drawn with ``st.dataframe``/pandas — the same rule the map,
graph and population panes follow. A demo whose *error* tab is a Streamlit lookalike
contradicts the very tab it is showing.
"""
from __future__ import annotations
import json
import os
from functools import lru_cache
from typing import Any
import streamlit as st
from ..facet_host import facett_component, is_data_driven
#: The clear pink the native demo paints an error CODE in (facett_core::look::PINK).
PINK = "#FF40B4"
#: The warm red facett paints a failure MESSAGE in (facett_core::look::RED).
RED = "#E05A5A"
_REGISTRY_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "errcodes.json")
#: The facett component both matrices are mounted as (registry name in `facet-wrapped`).
TABLE_COMPONENT = "table"
@lru_cache(maxsize=1)
def registry() -> dict[str, Any]:
"""The generated facett error-code catalog (cached)."""
with open(_REGISTRY_PATH, encoding="utf-8") as fh:
return json.load(fh)
def code_chip(code: str) -> str:
"""A CLEAR-PINK code chip — the same diagnostic stripe the native demo paints."""
return (
f'<code style="background:{PINK};color:#fff;padding:1px 6px;'
f'border-radius:4px;font-weight:600">{code}</code>'
)
#: (column header, how to read it off one registry row) for the error-code matrix.
_CODE_COLUMNS: list[tuple[str, Any]] = [
("component", lambda c: c["component"]),
("code", lambda c: c["code"]),
("message", lambda c: c["message"]),
("source", lambda c: f'{c["crate"]}/{c["src_file"]}'),
("status", lambda c: c["status"]),
("reaction (Phase 2)", lambda c: c["reaction"]),
("who reacts", lambda c: c["consumer"] or "— (none today)"),
]
#: The same, for the Phase-2 (code × mount) reaction matrix.
_MATRIX_COLUMNS: list[tuple[str, Any]] = [
("mounted code", lambda r: r["mounted_code"]),
("base code", lambda r: r["code"]),
("mount", lambda r: r["mount"]),
("expected reaction", lambda r: r["reaction"]),
]
def _payload(title: str, columns: list[tuple[str, Any]], records: list[dict[str, Any]]) -> dict[str, Any]:
"""The facett `table` payload contract: {title, columns, rows} of strings."""
return {
"title": title,
"columns": [name for name, _ in columns],
"rows": [[str(get(rec)) for _, get in columns] for rec in records],
}
def _mount_table(title: str, columns: list[tuple[str, Any]], records: list[dict[str, Any]],
*, key: str, height: int) -> None:
"""Mount the REAL facett table, or refuse — never fall back to a Python renderer."""
if not records:
st.info(f"`{title}` has no rows (honest empty).")
return
if not is_data_driven(TABLE_COMPONENT):
st.error(
f"`{TABLE_COMPONENT}` is not available as a data-driven facett component — the "
"`facet-wrapped` wasm bundle is missing or stale. Rebuild it with "
"`cargo xtask wrap-wasm`. Refusing to render this matrix in Python."
)
return
facett_component(TABLE_COMPONENT, data=_payload(title, columns, records), height=height, key=key)
def render(client=None) -> None: # noqa: ARG001 — signature parity with the other panes
"""Render the error-code showcase. Takes no live RPC — the catalog is static."""
reg = registry()
st.subheader("facett UI error codes")
st.caption(
"Every facett UI part carries a STABLE, UNIQUE code `facet-<component>-<n>` so "
"tests + consumers react to the CODE, not a matched string."
)
c1, c2, c3, c4 = st.columns(4)
c1.metric("components", reg["component_count"])
c2.metric("codes", reg["code_count"])
c3.metric("wired", reg["wired_count"])
c4.metric("reaction pairs", reg["reaction_pairs"])
# ── Triggered examples: message + CLEAR-PINK code (mirrors the native tab) ──
st.markdown("**Triggered examples (message + pink code):**")
for c in reg["codes"]:
if c["component"] != "demo":
continue
st.markdown(
f'<span style="color:{RED}">{c["message"]}</span> {code_chip(c["code"])}',
unsafe_allow_html=True,
)
# ── Consumer mount-prefix (Phase 2) ──
st.markdown("**Consumer mount-prefix (Phase 2 — same facet, two mount points):**")
st.code("korp/cases:facet-map-2\nkorp/analysis:facet-map-2", language=None)
st.divider()
# ── The error-code MATRIX slide ──
st.markdown(
f"**Error-code MATRIX — {reg['code_count']} codes across "
f"{reg['component_count']} components:**"
)
_mount_table("Error codes", _CODE_COLUMNS, reg["codes"], key="err_codes", height=460)
# ── The Phase-2 REACTION matrix slide ──
st.markdown(
f"**Reaction MATRIX (Phase 2) — {reg['reaction_pairs']} (code × mount) pairs "
"the consumer tests assert:**"
)
_mount_table("Reaction matrix", _MATRIX_COLUMNS, reg["reaction_matrix"],
key="err_matrix", height=460)
# ── The reaction vocabulary ──
with st.expander("Reaction vocabulary — what a consumer must DO"):
for r in reg["reactions"]:
st.markdown(f"- `{r['token']}` — {r['describes']}")
# ── Source per facet-component ──
with st.expander("Source per facet-component"):
seen: set[str] = set()
for c in reg["codes"]:
if c["component"] in seen:
continue
seen.add(c["component"])
st.markdown(f"- `facet-{c['component']}` → [{c['crate']}/{c['src_file']}]({c['source_url']})")