b9716a7cd6
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1 del flow 0008 (kanban_cpp + agent_runner_api + DoD schema). Incluye: - dev/flows/0008-kanban-cpp-and-agent-workflows.md - dev/issues/0112-0119*.md (7 sub-issues) - WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
161 lines
7.8 KiB
Markdown
161 lines
7.8 KiB
Markdown
---
|
|
id: "0109"
|
|
title: "App skill_tree: mapa interactivo de issues+flows en anillos concentricos por estado (roadmap)"
|
|
status: in-progress
|
|
type: epic
|
|
domain:
|
|
- meta
|
|
- cpp-stack
|
|
scope: cross-stack
|
|
priority: media
|
|
depends: []
|
|
blocks: []
|
|
related:
|
|
- "0069"
|
|
- "0085"
|
|
- "0086"
|
|
- "0087"
|
|
- "0100"
|
|
created: 2026-05-17
|
|
updated: 2026-05-17
|
|
tags:
|
|
- skill-tree
|
|
- roadmap
|
|
- meta
|
|
- cpp
|
|
- imgui
|
|
- gamification
|
|
---
|
|
|
|
# 0109 — skill_tree app (roadmap)
|
|
|
|
## Vision
|
|
|
|
App C++ ImGui que muestra los **79 issues + 7 flows** del registry como un mapa de capacidades en **anillos concentricos por estado** (centro = `completado`, exterior = `locked`/`deferred`), con **sectores radiales por dominio**. Click en nodo → panel `Inspector` con DoD + funciones del registry asociadas + 2 botones:
|
|
|
|
- **Generate ideas (`claude -p`)** → escribe a tabla `idea_drafts` para revision manual.
|
|
- **Run autonomous-task (`fn-orquestador`)** → spawn subagente en sandbox `auto/<issue>` con tail de logs.
|
|
|
|
Centro NO es nodo — es **HUD overlay** con LV, XP, conteos por dominio. Animacion lerp 1s cuando un nodo migra de anillo (cambio de status). Sin fisicas — layout estatico y determinista.
|
|
|
|
## Por que
|
|
|
|
- Discovery visual: lo que hoy es `ls dev/issues/` + lectura individual de 79 .md, se reduce a panoramica de 5s.
|
|
- Dispatcher unificado: lanzar `claude -p` o `/autonomous-task` desde 1 click contextual (hoy: copiar ID + tipear comando).
|
|
- Gamificacion derivada (XP/nivel) sin inflar nada artificial — todo deriva de trabajo real (status frontmatter + telemetria).
|
|
|
|
## No-goals (fuera de scope)
|
|
|
|
- NO editor de issues. Solo lectura + dispatch. Editar issue = boton "Open in editor" → `code <path>`.
|
|
- NO orquestador propio. Reusa `fn-orquestador` + `/autonomous-task` (issue 0069).
|
|
- NO base de datos paralela de issues. `registry.db` y `dev/issues/*.md` siguen siendo fuente unica.
|
|
|
|
## Modelo
|
|
|
|
### Tipos de nodo
|
|
|
|
| Tipo | Origen | Ring | Render |
|
|
|---|---|---|---|
|
|
| Issue (epic) | `dev/issues/NNNN-*.md` (`type=epic`) | segun status | nodo grande, color accent del dominio |
|
|
| Issue (feature/bugfix/refactor/...) | mismo, otros types | segun status | nodo medio, tono mas claro |
|
|
| Flow | `dev/flows/NNNN-*.md` | segun status (flow.status) | nodo distinto shape (rombo) |
|
|
|
|
### Aristas
|
|
|
|
- `issue.depends` / `issue.blocks` → DAG (linea solida).
|
|
- `flow.related_issues` → linea punteada flow → issue.
|
|
- On-hover: aristas al cinturon perimetral de funciones del registry (`uses_functions` cruzado con tags del issue).
|
|
|
|
### Estado lock/unlock (DERIVADO — nunca manual)
|
|
|
|
| Status visual | Regla |
|
|
|---|---|
|
|
| `done` | `status=completado` (issues) o `status=completed` (flows) |
|
|
| `in-progress` | `status=in-progress` |
|
|
| `unlocked` | `status=pendiente` Y todos `depends[]` resueltos |
|
|
| `locked` | `status=pendiente` Y algun `depends[]` no resuelto |
|
|
| `bloqueado` | `status=bloqueado` |
|
|
| `deferred` | `status=deferred` |
|
|
|
|
Flows sin `depends` usan `related_issues` — flow unlocked si todos los related estan done.
|
|
|
|
### XP / nivel
|
|
|
|
- `xp_value` por tipo: `epic=10, feature=3, bugfix=1, refactor=2, chore=1, docs=1, flow=5`.
|
|
- `xp_total = SUM(xp_value WHERE status in {completado, completed})`.
|
|
- `level = floor(sqrt(xp_total))`.
|
|
- HUD muestra: `LV X · N done · M open · K in-progress · domains mastered: ...`.
|
|
|
|
## Layout: anillos concentricos
|
|
|
|
| Ring | Radio (px) | Que contiene | Notas |
|
|
|---|---|---|---|
|
|
| 0 | 0 - 150 | `completado` | Si > 30 nodos, mostrar top-N por recencia + bucket "+N mas" |
|
|
| 1 | 150 - 280 | `in-progress` | Pulse animation suave |
|
|
| 2 | 280 - 450 | `unlocked` pendiente | Color pleno, clickable |
|
|
| 3 | 450 - 650 | `locked` (depends sin cumplir) | Gris, aristas hacia bloqueantes |
|
|
| 4 | 650+ | `deferred` + `bloqueado` | Semi-transparente |
|
|
|
|
Cada ring subdividido en **18 sectores radiales = 1 dominio** (allowlist de `dev/TAXONOMY.md`). Aristas curvas hacia el centro siguiendo el sector. Cuando un issue cambia status → lerp 1s entre posicion vieja y nueva.
|
|
|
|
## Stack tecnico
|
|
|
|
- **App C++ ImGui** via `fn::run_app` (scaffolder `init_cpp_app_bash_pipelines`).
|
|
- **Viz**: `graph_renderer_cpp_viz` (solo draw — sin force layout) + `graph_viewport_cpp_viz` + `graph_labels_cpp_viz` + `graph_spatial_hash_cpp_core` (picking O(1)).
|
|
- **Layout**: nueva fn `compute_ring_layout_cpp_core` (pure) — input `[{node_id, status, domain, recency}]`, output `[{node_id, x, y, ring, sector}]`.
|
|
- **Parser**: nueva fn `parse_md_frontmatter_cpp_core` (pure) — extrae bloque `---...---` + parse YAML simple (subset: key:value, key:list).
|
|
- **BD propia**: `apps/skill_tree/local_files/skill_tree.db` con tablas:
|
|
- `node_state_cache` (denormalizacion para render rapido)
|
|
- `agent_jobs` (claude -p + fn-orquestador spawns)
|
|
- `xp_events` (append-only para timeline)
|
|
- `idea_drafts` (drafts de `claude -p` antes de promover a proposal)
|
|
- **Registry.db**: read-only (`?mode=ro`), solo para enriquecer Inspector con info de `functions/types`.
|
|
|
|
## Sub-issues (rompimiento)
|
|
|
|
| ID | Titulo | DoD resumido |
|
|
|---|---|---|
|
|
| 0109a | App shell + parsers | Scaffolder corre. App abre. Lee 79 issues + 7 flows. Log conteos en stdout. e2e_checks build OK. |
|
|
| 0109b | Layout anillos + render estatico | Nodos pintados en su ring+sector. Aristas depends/related visibles. Sin interaccion clic. |
|
|
| 0109c | Panel Inspector + estado derivado | Click nodo → panel derecho con DoD + uses_functions. Lock/unlock derivado de depends. Reload manual F5. |
|
|
| 0109d | HUD XP + animacion migracion | Overlay HUD arriba-izq. Lerp 1s en cambio de status. xp_events append-only. |
|
|
| 0109e | Boton Ideas (claude -p → drafts) | Spawn `claude -p` con prompt contextual. Persiste en `idea_drafts`. UI aprobar/rechazar → proposals. |
|
|
| 0109f | Boton Auto-run (fn-orquestador) | Spawn `Agent(fn-orquestador)` background. Panel inferior con tail logs. Barra progreso vive (`task_runs.checks_pass/total`). |
|
|
|
|
## Riesgos / mitigaciones
|
|
|
|
| Riesgo | Mitigacion |
|
|
|---|---|
|
|
| Ring 0 con ~72 done satura visualmente | Top-N por recencia + bucket "+N mas..." expandible |
|
|
| 18 sectores * 158 nodos = legibilidad pobre | Zoom semantico: zoom-out muestra solo epics + flows |
|
|
| `claude -p` puede consumir tokens en bucle | Rate-limit UI: 1 invocacion por nodo por hora (`idea_drafts.last_request_at`) |
|
|
| Drift status del .md vs cache | F5 manual fuerza re-scan. Sin file watcher en fase A. |
|
|
| Parser YAML C++ frágil con campos exoticos | Test golden sobre los 79 issues actuales antes de mergear 0109a |
|
|
|
|
## DoD del epic
|
|
|
|
- [ ] App `skill_tree` indexada en `registry.db` con `framework=imgui`, trio icon completo, `e2e_checks` declarados, `uses_functions` no vacio.
|
|
- [ ] Compila en Linux + Windows. Desplegada via `redeploy_cpp_app_windows`.
|
|
- [ ] Tarjeta visible en `app_hub_launcher`.
|
|
- [ ] Los 6 sub-issues (a-f) mergeados a master de su sub-repo Gitea.
|
|
- [ ] Pipeline `fn doctor cpp-apps` limpio para `skill_tree`.
|
|
- [ ] `fn doctor uses-functions` sin drift para `skill_tree`.
|
|
|
|
## Funciones nuevas previstas (delegar a fn-constructor)
|
|
|
|
1. `parse_md_frontmatter_cpp_core` (pure) — parser frontmatter YAML simple en C++.
|
|
2. `compute_ring_layout_cpp_core` (pure) — posiciones determinsticas por anillo+sector.
|
|
3. `spawn_claude_p_bash_infra` o `_go_infra` — lanza `claude -p "<prompt>"` con timeout + captura stdout JSON. Reusable.
|
|
|
|
## Decisiones
|
|
|
|
| Tema | Decision | Razon |
|
|
|---|---|---|
|
|
| Centro del mapa | HUD overlay, NO nodo | Centro = "estado actual del usuario" — no es un item, es un agregado. |
|
|
| Layout | Estatico anillos+sectores | Sin fisicas. Usuario dijo "no quiero que se muevan, nos volveran locos". |
|
|
| Animacion | Lerp 1s entre rings | Da sensacion de progreso sin caos visual. |
|
|
| Boton Ideas dest | `idea_drafts` (revision manual) | Evita ruido en `proposals`. |
|
|
| Refresh | F5 manual | Simplicidad MVP. File watcher en fase posterior. |
|
|
| Service tag | NO | App interactiva, no daemon. |
|
|
| Ubicacion | `apps/skill_tree/` | Meta-tool del registry entero, no de proyecto. |
|