From cca3adb65da14f4f5a3dae89f6ccce4d6aab74d3 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Mon, 18 May 2026 18:30:37 +0200 Subject: [PATCH] docs(viz): frontmatter + self-doc para dod_evidence_panel (issue 0117) Ejemplo lanzable con DodPanelState mock + Cuando usarla (HITL DoD validation) + Gotchas (screenshot stub, URL no validada, log read each-frame, callbacks pueden mutar state, frame ImGui activo requerido). Tag agents para capability group. Co-Authored-By: Claude Opus 4.7 (1M context) --- cpp/functions/viz/dod_evidence_panel.md | 87 +++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 cpp/functions/viz/dod_evidence_panel.md diff --git a/cpp/functions/viz/dod_evidence_panel.md b/cpp/functions/viz/dod_evidence_panel.md new file mode 100644 index 00000000..c7546060 --- /dev/null +++ b/cpp/functions/viz/dod_evidence_panel.md @@ -0,0 +1,87 @@ +--- +name: dod_evidence_panel +kind: function +lang: cpp +domain: viz +version: "0.1.0" +purity: impure +signature: "void fn_viz::render_dod_evidence_panel(DodPanelState& state)" +description: "Panel ImGui que renderiza items DoD + evidencias (screenshot/log/url/cmd) con botones validate/reject por item y badge required-missing" +tags: [agents, dod, evidence, imgui, viz, panel, cpp-dashboard-viz] +uses_functions: [tokens_cpp_core] +uses_types: [] +returns: [] +returns_optional: false +error_type: "error_go_core" +imports: [imgui] +tested: true +tests: + - "count_status: total = items.size" + - "count_status: unknown status counts as pending" + - "count_status: missing_required only when required+no evidence+unresolved" + - "find_evidence: returns matching evidence" + - "find_evidence: empty state returns nullptr" + - "status_icon_id: mapping per status" + - "status_color_token: mapping per status" +test_file_path: "cpp/tests/test_dod_evidence_panel.cpp" +file_path: "cpp/functions/viz/dod_evidence_panel.cpp" +framework: imgui +params: + - name: state + desc: "DodPanelState con items (DodItem[]), evidences (DodEvidence[]), run_id y callbacks on_validate/on_reject (std::function)" +output: "void — renderiza header (run_id + counts) + tabla 6-col (status icon | id | kind | expected | evidence preview | actions) inline en current ImGui window" +--- + +# dod_evidence_panel + +Panel ImGui reutilizable para validar la **Definition of Done** de un agente o run. Compone: + +- Header con `run_id` y counts por status (`total / done / validated / failed`) + badge rojo si hay items required sin evidence. +- Tabla con icono de status (TI_CIRCLE_DASHED/DOT/CHECK/X), id, kind, expected, preview de la evidence segun kind, y botones Validate/Reject. + +Logica pura (count, find, status mappers) en `dod_evidence_panel_helpers.{h,cpp}` — testeada sin ImGui. El `.cpp` del panel hace render real y se compila SOLO cuando una app lo lista en su CMakeLists. + +## Ejemplo + +```cpp +#include "viz/dod_evidence_panel.h" + +fn_viz::DodPanelState state; +state.run_id = "run_abc123"; + +fn_viz::DodItem it1; +it1.id = "screenshot_home"; +it1.kind = "screenshot"; +it1.expected = "Landing page con KPI cards visibles"; +it1.required = true; +it1.status = "done"; +state.items.push_back(it1); + +fn_viz::DodEvidence ev1; +ev1.item_id = "screenshot_home"; +ev1.kind = "screenshot"; +ev1.payload_path = "/tmp/screenshots/home.png"; +state.evidences.push_back(ev1); + +state.on_validate = [&](const std::string& id) { db.mark_validated(id); }; +state.on_reject = [&](const std::string& id) { db.mark_failed(id); }; + +// En el render callback de fn::run_app: +ImGui::Begin("DoD evidence"); +fn_viz::render_dod_evidence_panel(state); +ImGui::End(); +``` + +## Cuando usarla + +Usala cuando una app necesita mostrar al humano los items pendientes de validacion de un run de agente (DoD) con sus evidencias para aprobar/rechazar a mano. Encaja en dashboards de orquestador (`fn-orquestador`), kanban de issues con sub-checks visuales, o paneles "human-in-the-loop" donde se requiere firma manual antes de marcar `done`. + +## Gotchas + +- **Screenshot preview es stub textual**. La carga real PNG requiere GL context y un cache `map` que el panel no posee. Si necesitas thumbnails reales, mantenlos en la app consumidora y pasalos a un callback custom (issue futura). +- **URL open**: en Linux usa `system("xdg-open '' &")`, en Windows `ShellExecuteA`. NO valida la URL antes — si la URL viene de input no confiable, sanitizar antes de poner en `payload_url`. +- **Log preview** lee primeras 5 lineas con `std::ifstream` por frame. Para logs muy grandes o cuando el panel se redibuja a 60fps, considera cachear externamente. +- **Cmd diff** compara strings exactamente (`==`). No hace trimming ni normalizacion de whitespace — el caller decide. +- **Callbacks pueden mutar `state`**: las apps suelen mover el item a `validated`/`failed` desde el `on_validate`/`on_reject`. El panel re-renderiza con el nuevo status en el siguiente frame. +- **`required` + `missing_required`**: solo se cuenta `missing_required` cuando el item es required, NO tiene evidence, y el status NO es `done`/`validated`. Un item required marcado `done` sin evidence no aparece como missing (la app ya lo cerro a mano). +- Llamar dentro de un frame ImGui activo (entre `NewFrame`/`Render`). Fuera, `ImGui::BeginTable` aborta.