fad4006f60
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
185 lines
10 KiB
Markdown
185 lines
10 KiB
Markdown
---
|
||
id: "0049"
|
||
title: "OSINT graph viewer + GPU graph rendering system"
|
||
status: completado
|
||
type: feature
|
||
domain:
|
||
- osint
|
||
scope: multi-app
|
||
priority: alta
|
||
depends: []
|
||
blocks: []
|
||
related: []
|
||
created: 2026-05-17
|
||
updated: 2026-05-17
|
||
tags: []
|
||
---
|
||
# 0049 — OSINT graph viewer + GPU graph rendering system
|
||
|
||
## Metadata
|
||
|
||
| Campo | Valor |
|
||
|-------|-------|
|
||
| **ID** | 0049 |
|
||
| **Estado** | pendiente |
|
||
| **Prioridad** | alta |
|
||
| **Tipo** | feature — proyecto C++ multi-fase |
|
||
|
||
## Dependencias
|
||
|
||
| ID | Título | Estado | Requerido |
|
||
|----|--------|--------|-----------|
|
||
| 0042 | C++ layout_storage publico | completado | si |
|
||
| 0043 | C++ apps standardize shell | completado | si |
|
||
| 0048 | C++ visual tests CI gate | completado | si |
|
||
|
||
**Bloqueada por:** ninguna (todas las deps cerradas).
|
||
**Desbloquea:** apps tipo Maltego local + cualquier app del registry que necesite visualizacion de grafos a escala.
|
||
|
||
---
|
||
|
||
## Objetivo
|
||
|
||
Construir un **sistema de visualizacion de grafos GPU-accelerated, agnostico del backend de datos**, y sobre el una app `graph_explorer` para OSINT/ontologia. El renderer debe escalar a 50k+ nodos sin caida de fps, soportar layouts (force, grid, circular, radial, jerarquico, fixed), formas/iconos/colores per-tipo, edges direccionales y con estilos, drag-and-drop, multiseleccion, labels con politica, y filtros por tipo. Datos cargables desde `operations.db` de cualquier app del registry como primer source, con abstraccion funcional preparada para JSON/JSONL/GraphML.
|
||
|
||
## Contexto
|
||
|
||
**Lo que existe hoy** (`cpp/functions/viz/`):
|
||
- `graph_renderer` — instanced quad rendering en OpenGL 3.3 con SDF circular. CPU rebuilds vertex buffers cada frame.
|
||
- `graph_force_layout` — Barnes-Hut quadtree en CPU, una iteracion por frame.
|
||
- `graph_viewport` — wrapper ImGui con pan/zoom/hit-testing.
|
||
- `graph_types` — `GraphNode`/`GraphEdge` minimos.
|
||
|
||
**Lo que limita escalar:**
|
||
1. Force layout en CPU domina a partir de ~5k nodos.
|
||
2. Renderer aloca y resube buffers cada frame (`glBufferData`).
|
||
3. Aristas reconstruidas vertex-by-vertex en CPU.
|
||
4. Sin shapes, iconos, edge styles, flechas, filtros, labels.
|
||
5. Bound a OpenGL 3.3 (sin compute shaders ni SSBOs).
|
||
|
||
**Caso de uso final:**
|
||
Visor tipo Maltego local con extraccion de entidades por tipos sobre `analysis/ontology_graph` (OSINT banca espanola, ya en marcha). Recoleccion masiva → entities/relations llegan en streaming → visualizacion en tiempo real.
|
||
|
||
## Arquitectura
|
||
|
||
```
|
||
projects/osint_graph/ # NEW project
|
||
├── project.md # NEW
|
||
├── apps/
|
||
│ └── graph_explorer/ # NEW app (sub-repo dataforge/graph_explorer)
|
||
│ ├── app.md
|
||
│ ├── CMakeLists.txt
|
||
│ ├── main.cpp
|
||
│ ├── data.{h,cpp} # dispatcher de GraphLoadFn
|
||
│ ├── views.{h,cpp} # toolbar/legend/inspector/stats
|
||
│ └── types_registry.{h,cpp} # carga types.yaml para visual override
|
||
├── analysis/ # vacio inicial
|
||
└── vaults/
|
||
└── osint_data -> ~/vaults/osint_graph/ # symlink
|
||
|
||
cpp/functions/viz/ # extensiones + funciones nuevas
|
||
├── graph_types.{h,cpp} # MOD — modelo extendido (type_id, flags, icons...)
|
||
├── graph_renderer.{h,cpp} # MOD — RGBA8, orphan, TBO, shapes, iconos, flechas
|
||
├── graph_force_layout.{h,cpp} # MOD — auto-pause
|
||
├── graph_force_layout_gpu.{h,cpp} # NEW — compute shader + spatial hash
|
||
├── graph_layouts.{h,cpp} # NEW — radial, hierarchical, fixed (consolida)
|
||
├── graph_viewport.{h,cpp} # MOD — lasso, multi-select, drag-pin, callbacks
|
||
├── graph_labels.{h,cpp} # NEW — render con LabelPolicy
|
||
├── graph_icons.{h,cpp} # NEW — atlas Tabler en textura
|
||
└── graph_sources.{h,cpp} # NEW — graph_load_from_operations + stream
|
||
|
||
cpp/framework/app_base.cpp # MOD — bump GL 3.3 → 4.3 core
|
||
|
||
.claude/rules/cpp_apps.md # YA AÑADIDO en sesion previa
|
||
```
|
||
|
||
### Abstraccion funcional `GraphSource`
|
||
|
||
Misma firma para todos los backends — swap por puntero a funcion, sin virtuals:
|
||
|
||
```cpp
|
||
typedef bool (*GraphLoadFn)(const char* uri, GraphData* out, GraphLoadStats* stats);
|
||
|
||
bool graph_load_from_operations(const char*, GraphData*, GraphLoadStats*);
|
||
bool graph_load_from_json (const char*, GraphData*, GraphLoadStats*); // futuro
|
||
bool graph_load_from_jsonl (const char*, GraphData*, GraphLoadStats*); // futuro
|
||
bool graph_load_from_graphml (const char*, GraphData*, GraphLoadStats*); // futuro
|
||
|
||
struct GraphStreamSource;
|
||
GraphStreamSource* graph_stream_operations_open(const char* db_path, int poll_ms);
|
||
int graph_stream_pull(GraphStreamSource*, GraphData*);
|
||
void graph_stream_close(GraphStreamSource*);
|
||
```
|
||
|
||
## Desglose multi-issue
|
||
|
||
Este issue se implementa en 11 sub-issues independientes. Cada sub-issue es autocontenido — debe compilar, pasar tests, no romper master. Trunk-based development obligatorio (ver `.claude/rules/apps_tbd.md`).
|
||
|
||
| Sub-issue | Rama | Alcance | Estado |
|
||
|-----------|------|---------|--------|
|
||
| [0049a](0049a-osint-graph-setup.md) | issue/0049a-osint-graph-setup | Crear proyecto `osint_graph` + vault + sub-repo Gitea de la app | pendiente |
|
||
| [0049b](0049b-cpp-bump-gl-43.md) | issue/0049b-cpp-bump-gl-43 | Bump OpenGL 3.3 → 4.3 core en `app_base` + verificar apps existentes | pendiente |
|
||
| [0049c](0049c-graph-renderer-tier1.md) | issue/0049c-graph-renderer-tier1 | RGBA8, orphan buffers, frustum cull aristas, auto-pause force | pendiente |
|
||
| [0049d](0049d-graph-edges-vertex-pulling.md) | issue/0049d-graph-edges-vertex-pulling | TBO + vertex pulling para aristas | pendiente |
|
||
| [0049e](0049e-graph-types-extended.md) | issue/0049e-graph-types-extended | Modelo extendido: type_id, flags, EntityType/RelationType | pendiente |
|
||
| [0049f](0049f-graph-renderer-symbols.md) | issue/0049f-graph-renderer-symbols | Shapes SDF, icon atlas, flechas, edge styles | pendiente |
|
||
| [0049g](0049g-graph-source-operations.md) | issue/0049g-graph-source-operations | `graph_load_from_operations` + stream variant | pendiente |
|
||
| [0049h](0049h-graph-force-layout-gpu.md) | issue/0049h-graph-force-layout-gpu | Compute shader + spatial hash GPU | pendiente |
|
||
| [0049i](0049i-graph-layouts-static.md) | issue/0049i-graph-layouts-static | radial, hierarchical, fixed + viewport extendido | pendiente |
|
||
| [0049j](0049j-graph-labels.md) | issue/0049j-graph-labels | `graph_labels` con LabelPolicy via ImDrawList | pendiente |
|
||
| [0049k](0049k-graph-explorer-app.md) | issue/0049k-graph-explorer-app | App `graph_explorer` + indexado + push final | pendiente |
|
||
|
||
### Feature flag
|
||
|
||
Nombre: `osint_graph_v1`
|
||
Se activa al cerrar `0049k` cuando `graph_explorer` compila, consume operations.db y muestra grafos OSINT con todas las features (shapes, iconos, layouts, labels, filtros).
|
||
|
||
### Progreso por fase
|
||
|
||
- [ ] **0049a** — proyecto osint_graph + vault + sub-repo
|
||
- [ ] **0049b** — bump GL 4.3
|
||
- [ ] **0049c** — renderer Tier 1 (perf)
|
||
- [ ] **0049d** — edges via vertex pulling (perf)
|
||
- [ ] **0049e** — modelo de datos extendido (breaking change a graph_types)
|
||
- [ ] **0049f** — shapes/iconos/edge-styles/flechas (renderer extendido)
|
||
- [ ] **0049g** — source operations.db + streaming
|
||
- [ ] **0049h** — force layout GPU compute
|
||
- [ ] **0049i** — layouts estaticos + viewport extendido
|
||
- [ ] **0049j** — labels con politica
|
||
- [ ] **0049k** — app graph_explorer + flag activado
|
||
|
||
## Decisiones de diseno
|
||
|
||
1. **OpenGL 4.3 core** (no 3.3): habilita compute shaders + SSBOs, simplifica el layout GPU drasticamente. Trade: GPUs ~2012+ obligatorias (todas las modernas — aceptable).
|
||
2. **Spatial hash grid GPU** en vez de Barnes-Hut: Barnes-Hut quadtree es muy duro en GPU sin punteros. Spatial hash es uniforme en carga y suficiente visualmente para el caso OSINT.
|
||
3. **Modelo de datos extendido es breaking change** controlado: la unica consumidora actual es `demos_graph` en `primitives_gallery`; se migra en el mismo sub-issue (0049e).
|
||
4. **GraphSource es funcional, no OO**: punteros a funcion con misma firma, swap trivial. Sin virtuals, sin templates, sin std::function en hot path.
|
||
5. **types.yaml externo** define visual mapping (color/shape/icon per entity type). El renderer no sabe nada de OSINT — solo lee tablas.
|
||
6. **CPU mirror de posiciones** se mantiene siempre (8 bytes × N) para hit-test, drag, labels — leido via `glGetBufferSubData` 1x/frame. Trivial coste, simplifica todo.
|
||
7. **Cada app C++ es sub-repo Gitea** (`apps_tbd.md` + `cpp_apps.md`): `graph_explorer` se crea con `.git` apuntando a `dataforge/graph_explorer`.
|
||
|
||
## Riesgos
|
||
|
||
| Riesgo | Mitigacion |
|
||
|---|---|
|
||
| Bump GL 4.3 rompe apps existentes en HW antiguo | Validar en 0049b sobre las 4 apps actuales en Linux + Windows cross-compile antes de mergear |
|
||
| Compute shader complexity (0049h) | Caer back a CPU layout es trivial — la API es identica |
|
||
| Streaming desde operations.db sin estabilidad de positions | Pin nodos nuevos cerca del padre por N frames, luego release |
|
||
| Demo `demos_graph` queda roto durante 0049e | Migrar `demos_graph.cpp` en el mismo sub-issue con tests visuales |
|
||
| Atlas de iconos Tabler ocupa espacio | 512×512 RGBA = 1 MB en VRAM, despreciable |
|
||
|
||
## Criterio de done global
|
||
|
||
- [ ] `graph_explorer` abre cualquier `apps/<x>/operations.db` del registry y lo visualiza con tipos descubiertos automaticamente.
|
||
- [ ] 50k nodos + 200k aristas a 60fps en GPU integrada con layout corriendo.
|
||
- [ ] Drag, multi-select (Ctrl+click + Shift+lasso), filter-by-type, fit-view operativos.
|
||
- [ ] Labels visibles para selected/hovered + top-N por tamaño con LabelPolicy configurable.
|
||
- [ ] Iconos Tabler renderizados dentro de cada nodo segun `EntityType.icon_id`.
|
||
- [ ] Edges direccionales con flechas + estilos solid/dashed/dotted segun `RelationType.style`.
|
||
- [ ] `types.yaml` opcional que mergea defaults con override visual por tipo.
|
||
- [ ] `fn index` completa y todas las funciones nuevas aparecen con `uses_functions` correcto.
|
||
- [ ] Tests Catch2 verdes para `graph_layouts`, `graph_icons`, `graph_force_layout_gpu`, `graph_sources`.
|
||
- [ ] Visual test golden actualizado para `demos_graph` con el nuevo modelo.
|
||
- [ ] Sub-repo `dataforge/graph_explorer` pushed con master limpio.
|
||
- [ ] Feature flag `osint_graph_v1` = `true`.
|