---
id: "0117"
title: "Funcion cpp dod_evidence_panel: render screenshots/logs/urls/cmd-output"
status: pendiente
type: feature
domain:
  - cpp-stack
  - agents
  - registry-quality
scope: registry
priority: alta
depends:
  - "0110"
  - "0114"
blocks: []
related:
  - "0008"
  - "0112"
  - "0116"
created: 2026-05-18
updated: 2026-05-18
tags: [dod, evidence, cpp, imgui, viz, registry-gap]
flow: "0008"
---

# 0117 — Funcion `dod_evidence_panel_cpp_viz`

## Problema

kanban_cpp (0112) y skill_tree v2 (0116) necesitan ambos un panel que muestre items DoD + evidencias adjuntas. Sin funcion compartida, se duplica logica (regla `delegation.md`).

## Decision

Funcion C++ en `cpp/functions/viz/dod_evidence_panel.{cpp,h,md}`. API:

```cpp
namespace fn_viz {
    struct DodItem {
        std::string id;
        std::string kind;        // "screenshot" | "log" | "url" | "cmd"
        std::string expected;
        bool        required;
        std::string status;      // "pending" | "done" | "validated" | "failed"
    };
    struct DodEvidence {
        std::string item_id;
        std::string kind;
        std::string payload_path;  // para screenshot/log
        std::string payload_url;   // para url
        std::string payload_text;  // para cmd output
        int64_t     attached_at;
        bool        validated;
        std::string validated_by;
    };
    struct DodPanelState {
        std::vector<DodItem>     items;
        std::vector<DodEvidence> evidences;
        std::string run_id;
        std::function<void(const std::string&)> on_validate;   // callback(evidence_id)
        std::function<void(const std::string&)> on_reject;     // idem
    };
    void render_dod_evidence_panel(DodPanelState& state);
}
```

Renderiza:
- Lista de items con icono por status (`TI_CIRCLE_DASHED`/`TI_CIRCLE_CHECK`/`TI_CIRCLE_DOT`/`TI_CIRCLE_X`).
- Por item: evidencia adjunta segun kind:
  - `screenshot`: thumbnail via `stb_image_load` + `ImGui::Image`. Click -> open full-size en popup.
  - `log`: `selectable_text_cpp_core` (registry) con scroll + grep pattern de `expected` highlighted.
  - `url`: `TI_EXTERNAL_LINK` clickable -> `ShellExecuteW` (Win) / `xdg-open` (Linux).
  - `cmd`: dos columnas (expected vs actual) usando `data_table_cpp_viz`. Diff highlight rojo si mismatch.
- Botones por evidencia: `Validate` (verde, callback `on_validate`) / `Reject` (rojo, callback `on_reject`).

## Criterios de aceptacion

- [ ] `cpp/functions/viz/dod_evidence_panel.{cpp,h,md}` registrado.
- [ ] `params_schema` y `output` completos en frontmatter.
- [ ] Tag `agents` aplicado.
- [ ] `.md` cumple contrato self-doc (`## Ejemplo` con DodPanelState concreto, `## Cuando usarla`, `## Gotchas`).
- [ ] Demo en `cpp/apps/primitives_gallery/demos_viz.cpp` con DodPanelState dummy (4 kinds + 2 validados + 2 pending).
- [ ] `kanban_cpp::panel_dod` usa la funcion (declarado en `uses_functions`).
- [ ] `skill_tree` (panel inferior cuando hay run activo) usa la funcion.
- [ ] Tests visuales: golden image en `primitives_gallery --capture`.
- [ ] `fn doctor capabilities` muestra grupo `agents` con esta funcion listada.
- [ ] `uses_functions` declara: `selectable_text_cpp_core`, `data_table_cpp_viz`, `icons_tabler_cpp_core`.

## Gotchas

- `stb_image_load` para PNGs grandes (screenshots full HD): clamp dimensions del thumbnail a 320x180. Liberar texturas con `glDeleteTextures` al cerrar panel.
- WSL paths vs Windows: si `payload_path` viene como `/mnt/c/...`, convertir a `C:\...` solo para `ShellExecuteW`. Para `stb_image` da igual.
- Cache de texturas: re-cargar PNG cada frame es caro. Map `path -> GLuint` con LRU. Invalidar si mtime cambia.
- Callbacks `on_validate`/`on_reject`: invocan POST HTTP al `agent_runner_api`. NO bloquear frame; spawn thread.
- `cmd` evidence con stdout largo: clip a 50 lineas + boton `Show full`.

## Out of scope

- Editor de schema DoD (vive en kanban_cpp o futura UI).
- Comparacion AI de screenshots (futuro: visual diff).
- Persistencia local de validaciones offline.
