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>
14 KiB
id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
| id | title | status | type | domain | scope | priority | depends | blocks | related | created | updated | tags | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0107 | Estandarizar sistema de modulos C++: limpiar drift data_table + politica API + version pinning + /version command | pendiente | refactor |
|
multi-app | alta |
|
|
2026-05-17 | 2026-05-17 |
|
0107 — Estandarizar sistema de modulos C++
Problema
Auditoria 2026-05-17 sobre modules/ (framework + data_table) revela que el sistema de modulos C++ esta a medio camino: la idea (modulos opt-in versionados con manifest auditable) es solida, pero su implementacion tiene fugas que invalidan el contrato.
Drift uses_modules ↔ uses_functions (7/7 apps consumidoras)
module.md dice "cuando declaras uses_modules, NO repetir los miembros en uses_functions". Realidad medida hoy:
| App | uses_functions total | miembros data_table duplicados |
|---|---|---|
| services_monitor | 12 | 12 |
| dag_engine_ui | 13 | 12 |
| odr_console | 5 | 5 |
| navegator_dashboard | 20 | 12 |
| graph_explorer | 42 | 12 |
| registry_dashboard | 37 | 11 |
| app_gestion | 12 | 12 |
7 de 7 apps violan la regla clave que justifica el sistema. fn doctor cpp-apps no detecta el drift.
data_table.cpp = 4777 LOC
El "modulo" es un god-file con UI entera (chips, viz, grid, drill, joins, AI, button, color rules) dentro de un .cpp. Imposible auditar consumidores parciales, imposible registrar miembros como funciones reales del registry (cada uno con su .md).
Boundary modulo vs funcion borrosa
lua_engine, llm_anthropic, join_tables son members de data_table. Pero lua/llm/join son utiles fuera de tablas. Forzar membership infla el surface del modulo y obliga a las apps a tragarse lua+llm+anthropic+join aunque solo quieran render simple. No hay tier "data_table_core" vs "data_table_full".
Versionado declarado, no enforced
module.md tiene version: 1.4.0. app.md dice uses_modules: [data_table_cpp] sin version. Bump breaking de modulo → todas las apps rompen sin warning hasta compile error.
Codegen silencioso
execute_process(... codegen_app_modules) emite WARNING solo si rc != 0 y != 2. Si Python falta → stub vacio sin error. About panel muestra "0 modules" en apps que SI deberian tener 1.
Hard dep oculto
fn_module_data_table linkea fn_framework PRIVATE para fn::local_path(). module.md no lo documenta como precondicion publica. Si alguien intenta usar el modulo en una app no-framework, falla en link sin mensaje claro.
Sin doc API de modulos
No hay un sitio canonico que diga "para usar el modulo X, incluye Y.h, llama X::render(...), pasa State Z". Cada modulo lo improvisa en su module.md.
Sin /version command
No hay flujo estandar para bumpear semver de un modulo o framework. Cada PR lo hace a ojo, sin coherencia entre module.md::version y ## Capability growth log.
Decision
Issue desglosado en 6 sub-issues independientes detras de feature flag modules-v2:
- 0107a —
fn doctor modulesque detecta drift uses_modules vs uses_functions. - 0107b — Limpiar
uses_functionsde las 7 apps consumidoras de data_table (eliminar miembros duplicados). - 0107c — Partir
modules/data_table/data_table.cpp(4777 LOC) en sub-funciones del registry (data_table_chips,data_table_grid,data_table_viz_panels,data_table_drill,data_table_ai_panel,data_table_color_rules). Cada una con.mdpropio. Entrypoint queda thin. - 0107d — Mover members generales (
lua_engine,llm_anthropic,join_tables,auto_detect_type) fuera dedata_tablemodule. Quedan funciones sueltas que el modulo USA pero no posee. Crear tiers explicitos. - 0107e — Version pinning en
uses_modules(uses_modules: [{name: data_table_cpp, min_version: "1.4"}]) + codegen fail-loud (error si Python falta o count=0 cuando deberia ser >0). - 0107f —
modules/README.md(catalogo) +docs/MODULES_API.md(contrato publico por modulo: header path, namespace, entry function, State struct, lifecycle).
Ademas:
/versionslash command para bumpear semver de modulo/framework consistentemente (module.md::version+## Capability growth log+ git commit)./fix-issuereferenciara/versioncuando el cambio toque framework/modules.
Feature flag modules-v2 activado solo cuando 0107a-f cierran. Antes de cerrar, recompilar TODAS las apps cpp para verificar que el refactor no rompe linkage. Aceptamos coste de recompilacion total.
Restriccion explicita
Prohibido empezar chat_ia (proximo modulo planeado) hasta que 0107 cierre. Razon: si arrancamos otro modulo sin estandar estable, replicamos los mismos bugs en el doble de superficie.
Tareas (resumen — detalle en sub-issues)
- 1 Auditoria automatizada →
fn doctor modules(0107a) - 2 Limpiar drift en 7 apps consumidoras (0107b)
- 3 Partir
data_table.cppen sub-funciones del registry (0107c) - 4 Politica members generales + tiers (0107d)
- 5 Version pinning + codegen fail-loud (0107e)
- 6 Docs API publica modulos (0107f)
- 7 Recompilar todas las apps cpp + verificar smoke (al cerrar)
- 8 Activar feature flag
modules-v2 - 9
/version+/fix-issue(no son sub-issues; tareas inline en este issue principal)
Desglose multi-issue
| Sub-issue | Rama | Alcance | Estado |
|---|---|---|---|
| 0107a-fn-doctor-modules | issue/0107a-fn-doctor-modules | Check drift uses_modules vs uses_functions + version skew | pendiente |
| 0107b-clean-data-table-consumers | issue/0107b-clean-data-table-consumers | Eliminar miembros duplicados en 7 app.md | pendiente |
| 0107c-split-data-table | issue/0107c-split-data-table | Partir data_table.cpp 4777 LOC en sub-funciones del registry | pendiente |
| 0107d-module-tiers-policy | issue/0107d-module-tiers-policy | Sacar lua/llm/join del modulo data_table; tiers + politica | pendiente |
| 0107e-version-pinning-codegen | issue/0107e-version-pinning-codegen | min_version en uses_modules + codegen fail-loud | pendiente |
| 0107f-modules-api-docs | issue/0107f-modules-api-docs | modules/README.md + docs/MODULES_API.md | pendiente |
Feature flag
Nombre: modules-v2
Se activa cuando 0107a-f cierran + recompilacion total verificada + fn doctor modules reporta 0 drift.
Progreso por tarea
- 1.1 Implementar check drift en
fn doctor cpp-appso sub-comando nuevo — 0107a - 1.2 Output JSON con apps que violan regla — 0107a
- 1.3 Tests sobre fixture sintetica (1 modulo, 3 apps simuladas) — 0107a
- 2.1 Editar 7
app.mdremoviendo miembros data_table — 0107b - 2.2 Verificar build pasa post-clean (no rompe nada — solo metadata) — 0107b
- 3.1 Identificar fronteras funcionales en data_table.cpp 4777 LOC — 0107c
- 3.2 Crear
cpp/functions/viz/data_table_chips.cpp+ .h + .md — 0107c - 3.3 Crear
cpp/functions/viz/data_table_grid.cpp+ .h + .md — 0107c - 3.4 Crear
cpp/functions/viz/data_table_viz_panels.cpp+ .h + .md — 0107c - 3.5 Crear
cpp/functions/viz/data_table_drill.cpp+ .h + .md — 0107c - 3.6 Crear
cpp/functions/viz/data_table_ai_panel.cpp+ .h + .md — 0107c - 3.7 Crear
cpp/functions/viz/data_table_color_rules.cpp+ .h + .md — 0107c - 3.8
data_table.cppqueda como entrypoint thin que compone las sub-funciones — 0107c - 3.9 Bump
module.md::versiona 2.0.0 (breaking interno, API publicadata_table::renderintacta) — 0107c - 4.1 Crear
cpp/functions/core/lua_engine.cpp(ya existe) como funcion suelta; quitar demodule.md::members— 0107d - 4.2 Idem
llm_anthropic,join_tables,auto_detect_type— 0107d - 4.3 Actualizar
modules/data_table/CMakeLists.txt: estos.cppya no se enlazan dentro del modulo; apps que los necesiten los anaden a su CMakeLists — 0107d - 4.4 Definir tiers en
module.md:core_members(esenciales) vsoptional_members(deps externas pesadas) — 0107d - 5.1 Parser
app.md::uses_modulesacepta string corto y dict largo — 0107e - 5.2 Codegen comprueba
min_versionvsmodule.md::version— error si no cumple — 0107e - 5.3 Codegen: si
Python3 NOT FOUNDy app tieneuses_modules→ CMake FATAL_ERROR — 0107e - 5.4 Codegen: si parser devuelve count=0 pero app.md declara
uses_modulesno-vacio → FATAL_ERROR — 0107e - 6.1
modules/README.mdcon tabla modulos + version + descripcion + link a contrato — 0107f - 6.2
docs/MODULES_API.mdcon contrato canonico (template + ejemplos data_table + framework) — 0107f - 6.3 Actualizar
.claude/rules/cpp_apps.mdreferenciandodocs/MODULES_API.md— 0107f - 7.1
redeploy_all_cpp_apps_bash_pipelines+ verificar 0 errores de link — issue principal, al cerrar - 7.2 Smoke manual de cada app con
data_table::render— issue principal, al cerrar - 8 Flip
modules-v2: enabled: trueendev/feature_flags.json— issue principal - 9.1 Crear
.claude/commands/version.md(slash command bump semver) — issue principal, ya en este turno - 9.2 Crear
.claude/commands/fix-issue.mdque referencie/version— issue principal, ya en este turno
Arquitectura
Archivos afectados
0107a (fn doctor modules):
functions/infra/audit_modules_drift.go(NEW) — funcion del registryfunctions/infra/audit_modules_drift.md(NEW)cmd/fn/doctor.go— subcomandomodulesapps/registry_mcp/...— exponer viamcp__registry__fn_doctor subcommand="modules"
0107b:
- 7
app.mdeditados: services_monitor, dag_engine_ui, odr_console, navegator_dashboard, graph_explorer, registry_dashboard, app_gestion.
0107c:
modules/data_table/data_table.cpp— pasa de 4777 LOC a ~400 (entrypoint que compone).cpp/functions/viz/data_table_chips.cpp/.h/.md(NEW) — ~600 LOCcpp/functions/viz/data_table_grid.cpp/.h/.md(NEW) — ~1200 LOCcpp/functions/viz/data_table_viz_panels.cpp/.h/.md(NEW) — ~800 LOCcpp/functions/viz/data_table_drill.cpp/.h/.md(NEW) — ~300 LOCcpp/functions/viz/data_table_ai_panel.cpp/.h/.md(NEW) — ~500 LOCcpp/functions/viz/data_table_color_rules.cpp/.h/.md(NEW) — ~400 LOCmodules/data_table/module.md— bump version + actualizar members.modules/data_table/CMakeLists.txt— anadir las sub-funciones a la static lib.
0107d:
modules/data_table/module.md— quitarlua_engine,llm_anthropic,join_tables,auto_detect_typede members.modules/data_table/CMakeLists.txt— estos.cppsalen.- Apps consumidoras que necesiten lua/llm/join → declarar en
uses_functions+ anadir el.cppa su CMake.
0107e:
python/functions/infra/codegen_app_modules.py— soporte dict largo{name, min_version}.cpp/CMakeLists.txt::add_imgui_app— fail-loud en codegen errors.registry/parser.go— indexer entiende dict largo.
0107f:
modules/README.md(NEW)docs/MODULES_API.md(NEW).claude/rules/cpp_apps.md— link nuevo doc.
Slash commands (este issue):
.claude/commands/version.md(NEW).claude/commands/fix-issue.md(NEW si no existe)
pkg/ puro vs shell/ impuro
audit_modules_drift_go_infra (0107a) es impuro — lee registry.db + filesystem (app.md, module.md). Vive en functions/infra/. Core logico (comparar listas de IDs, detectar miembros duplicados) es puro y vive como sub-funcion interna del paquete infra.
Ejemplo de uso
# 1. Detectar drift
fn doctor modules
# Output:
# Module drift report
# ===================
# data_table_cpp (v1.4.0): 7/7 consumers list members in uses_functions
# services_monitor — duplicates: data_table_cpp_viz, viz_render_cpp_viz, ...
# dag_engine_ui — duplicates: ...
# Total apps with drift: 7
# Total modules: 2
# Exit: 1
# 2. Bump version de un modulo (slash command)
/version modules/data_table minor "split data_table.cpp into 6 sub-functions; API publica intacta"
# - Detecta version actual en module.md (1.4.0)
# - Calcula proxima (1.5.0 si minor, 2.0.0 si major)
# - Anade entrada a ## Capability growth log con fecha de hoy
# - Stage en git pero NO commit
# 3. Pinning version en una app
# app.md:
# uses_modules:
# - name: data_table_cpp
# min_version: "1.4"
# Codegen falla en cmake si module.md::version < 1.4
# 4. fix-issue referencia /version
/fix-issue 0107c
# Flow normal del fix-issue + "¿este cambio bumpea version de modulo/framework? si si → /version"
Decisiones de diseno
- No tocar API publica
data_table::render(...). Refactor interno. Apps existentes no cambian su llamada. - Aceptamos recompilacion total. El usuario lo dijo explicito. Coste de tiempo razonable a cambio de limpieza.
- Feature flag
modules-v2no protege codigo runtime — protege la "promesa" del sistema. Cuando flag flip,fn doctor modulesdebe pasar verde. /versionNO hace commit. Solo edita archivos + stage. El commit final lo hace el flujo normal del fix-issue.- Bloqueamos
chat_ia. Si saltamos a otro modulo sin estandar, el caos se duplica.
Prerequisitos
- Issue 0097 (modules infra inicial) — completado, esto es la evolucion.
fn doctor cpp-appsexiste (0081) — reutilizamos paths.
Riesgos
- Refactor 4777 LOC: alto riesgo de regresion visual/funcional. Mitigacion: smoke manual app-por-app +
primitives_gallery --capturegolden images antes/despues. - Apps que dependen indirectamente de lua/llm/join sin declararlo: post-0107d podrian fallar en link. Mitigacion:
fn doctor uses-functions+ recompilacion total como gate. - Codegen fail-loud rompe builds que hoy pasan con stub: deliberado, parte de la idea — pero hay que arreglar todos los app.md antes de mergear 0107e.
Notas
/versionse referenciara desde/fix-issuecon prompt: "este cambio tocamodules/ocpp/framework/? si si → run/version <path> [major|minor|patch] [reason]antes de commit".- Politica: bump de modulo SIN bump de version = bug.
fn doctor moduleslo detectara via diff hash demembers+descriptionvs ultima version registrada.