Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
10 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 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0171 | Manifest de sub-repos por project + re-clonado y auditoría de cobertura en Gitea | pendiente | enhancement |
|
registry-only | alta |
|
2026-06-10 | 2026-06-10 |
|
Actualización 10/06/2026 — implementado el núcleo (enfoque KISS). El manifest
subrepos.yamlpropuesto abajo se descartó:registry.db(tablasapps/analysisconproject_id, propagadas entre PCs porfn sync) ya es el manifest de sub-repos, yclone_project_subrepos_bash_pipelinesya lo consume. No hace falta un archivo nuevo. Lo que faltaba era integración + auditoría. Ver## Estado de implementaciónal final.
0171 — Manifest de sub-repos por project + re-clonado y auditoría de cobertura en Gitea
APP Metadata
| Campo | Valor |
|---|---|
| ID | 0171 |
| Estado | pendiente |
| Prioridad | alta (riesgo de pérdida de datos) |
| Tipo | enhancement — metadata de projects + /full-git-pull + fn doctor |
Contexto
El 10/06/2026, al preparar un dashboard sobre el project aurgi, se descubrió que el project
paraguas no existía en Gitea (dataforge/aurgi → 404). Sus 3 analyses sí estaban a salvo como
sub-repos independientes (dataforge/venta_web, dataforge/sale_prices_comprobation,
dataforge/presupuestos_callcenter), pero el project.md, vault.yaml y CONVENTIONS.md de
nivel-project no estaban versionados en ningún sitio. Reconstruir el project obligó a adivinar
los nombres de los sub-repos hijos uno a uno desde la lista completa de repos de Gitea.
Una auditoría de cobertura projects ↔ Gitea confirmó el agujero:
| Project | Repo Gitea | Riesgo |
|---|---|---|
| fleet_monitoring, fn_monitoring, message_bus, web_scraping | ✅ | ninguno |
| obsidian, osint | ❌ (solo en disco local) | alto — resuelto en esta sesión (subidos a dataforge/obsidian, dataforge/osint) |
| aurgi | ❌ (404, paraguas inexistente) | pendiente — analyses salvados, docs nivel-project no |
Dos problemas estructurales quedan abiertos:
-
Projects sin repo Gitea: su contenido de nivel-project vive solo en disco. Si se borra el disco (o el project no se sincroniza a otro PC), se pierde. La regla
projects.mddice que cada project debe ser su propio repo Gitea, pero no hay nada que lo verifique ni lo fuerce. -
Sub-repos hijos no referenciados: el
.gitignorede cada project excluyeapps/*/yanalysis/*/(son sub-repos independientes). Por tanto, un clon fresco del project NO trae sus hijos, y no existe ningún manifest que diga qué hijos clonar. Hoy/full-git-pullsolo descubre repos víadiscover_git_repos_bash_infra(busca.gitya presentes en disco): si el hijo nunca se clonó, es invisible. Resultado: para reconstruir un project en una máquina nueva hay que adivinar sus sub-repos (exactamente lo que pasó con aurgi).
Objetivo
Que todo project (a) tenga su repo Gitea garantizado y (b) referencie declarativamente sus sub-repos hijos (apps + analyses), de modo que clonar el project en cualquier PC permita re-clonar automáticamente todo su árbol sin adivinar nada.
Propuesta
1. Manifest de sub-repos por project
Añadir a cada project un manifest declarativo de sus hijos. Dos opciones de formato (decidir una):
-
Opción A (KISS, preferida):
subrepos.yamlen la raíz del project, análogo avault.yaml:# projects/<p>/subrepos.yaml — sub-repos hijos de este project (apps + analyses) subrepos: - kind: analysis # app | analysis name: venta_web path: analysis/venta_web repo: dataforge/venta_web url: https://gitea-.../dataforge/venta_web - kind: analysis name: sale_prices_comprobation path: analysis/sale_prices_comprobation repo: dataforge/sale_prices_comprobation url: https://gitea-.../dataforge/sale_prices_comprobation -
Opción B: sección
## Sub-reposenproject.mdcon una tablakind | name | path | url.
subrepos.yaml (Opción A) es más fácil de parsear por las funciones de git y se versiona con el
project (no está en el .gitignore). El manifest se autogenera/actualiza escaneando los .git
hijos presentes en disco + su remote get-url origin (reusar discover_git_repos_bash_infra).
2. Generación y mantenimiento del manifest
Función/pipeline nueva (delegar a fn-constructor, grupo infra/git) que, dado un project:
- Escanea
apps/*/.gityanalysis/*/.git, lee su remote origin. - Escribe/actualiza
subrepos.yaml. - Idempotente. Se invoca dentro de
/full-git-push(ofn index) para mantener el manifest al día.
3. Re-clonado desde el manifest en /full-git-pull
Extender /full-git-pull para que, tras actualizar cada project, lea su subrepos.yaml y clone
los hijos que falten (url → path). Así, en un PC nuevo: clonar dataforge/<project> →
/full-git-pull → reconstruye apps + analyses automáticamente. Requiere una función
clone_missing_subrepos_bash_infra(project_dir) (delegar a fn-constructor).
4. Garantizar repo Gitea de cada project + auditoría en fn doctor
- Subcomando nuevo
fn doctor projects(funciónaudit_projects_coverage_go_infra): por cada project en disco reportarepo_gitea(existe en Gitea sí/no),repo_url(declarado en project.md sí/no), ysubrepos_manifest(presente + cuántos hijos en disco sin entrada / en manifest sin clonar). Salida--json. Cero hallazgos = sano. - Acción derivada documentada:
repo_gitea=no→ensure_repo_synced_bash_infra projects/<p> dataforge <p> master "init: project <p>".
5. Backfill inicial
aurgi: traer suproject.md/vault.yaml/CONVENTIONS.mddeaurgi-pc(ohome-wsl) y creardataforge/aurgi+subrepos.yamlcon los 3 analyses ya conocidos. No reconstruir a mano unproject.mdmínimo (divergiría del real).- Resto de projects con hijos (
fleet_monitoring,fn_monitoring,message_bus,web_scraping): generar susubrepos.yamlcon la función del punto 2.
Definition of Done
| Escenario | Tipo | Comando / evidencia | Resultado esperado |
|---|---|---|---|
| Golden: clon fresco reconstruye árbol | e2e | clonar dataforge/<p> en dir limpio → /full-git-pull |
apps + analyses del project re-clonados desde subrepos.yaml |
| Edge: project sin hijos (obsidian) | e2e | generar manifest | subrepos.yaml válido y vacío (o ausente), sin error |
Edge: hijo en disco sin .git |
unit | auditoría | fn doctor projects lo reporta como "hijo sin sub-repo" |
| Error: project sin repo Gitea | e2e | fn doctor projects --json |
lo marca repo_gitea=false, sugiere ensure_repo_synced |
| Cobertura | audit | fn doctor projects |
0 projects sin repo, 0 hijos sin referenciar |
Decisiones abiertas
- Formato del manifest:
subrepos.yaml(A) vs. sección enproject.md(B). Recomendado A. - ¿Auto-generar el manifest en
fn indexo solo en/full-git-push? (evitar I/O de red enfn index; preferible en push). - aurgi: ¿traer de
aurgi-pcpor SSH ahora, o dejarlo para cuando el project se sincronice?
Notas
En esta sesión ya se resolvió el riesgo inmediato: obsidian y osint se subieron a Gitea
(dataforge/obsidian, dataforge/osint) con ensure_repo_synced_bash_infra y se les añadió
repo_url en su project.md. Este issue cubre la solución estructural y reutilizable para que
el caso no vuelva a ocurrir con ningún project. Relacionado con #0166 (dependencias app→app para
build reproducible): ambos persiguen que clonar el ecosistema en un PC nuevo sea determinista.
Estado de implementación (10/06/2026)
Implementado con enfoque KISS, sin subrepos.yaml (registry.db + fn sync ya cumplen esa
función). Cambios:
Funciones nuevas:
ensure_project_gitignore_bash_infra— garantiza idempotente el.gitignorecanónico de un project (apps/*/,analysis/*/,vaults/*+ excepciones) antes de cualquiergit add -A, para no trackear el contenido de los sub-repos hijos.audit_projects_coverage_go_infra(+FormatProjectsCoverage) — motor defn doctor projects. Reporta por project:git/remote/repo_url/children (cloned/inDB)+ issues (no_gitea_repo,children_missing,dir_not_found). Solo git local + registry.db, sin red.
Integraciones:
full_git_pushv1.1.0 — paso 1c: auto-inicializa y pushea los projects paraguas sin repo (antes solo apps/analyses), asegurando el.gitignorecanónico primero. Cierra el agujero aurgi/obsidian/osint.full_git_pullv1.1.0 — paso 6: trasfn sync, reclona los sub-repos hijos faltantes de cada project conclone_project_subrepos+ re-index. Clonar el paraguas +/full-git-pullreconstruye el árbol entero.fn doctor projects— nuevo subcomando (cmd/fn/doctor.go). Hoy reporta 0 projects con problemas.
Hecho aparte (riesgo inmediato): dataforge/obsidian + dataforge/osint creados, repo_url
en sus project.md.
Pendientes (no bloquean el núcleo)
- Check inverso — HECHO (10/06/2026).
FindOrphanProjectRefs+FormatOrphanProjectRefsenaudit_projects_coverage_go_infra, enchufado enfn doctor projects. Detecta apps/analysis conproject_idsin fila enprojects. Hoy reporta 4 paraguas huérfanos (existen en otro PC, nunca subidos a Gitea — mismo caso que aurgi):element_agents(6 apps: agents_and_robots, agents_dashboard, device_agent, element_matrix_chat, matrix_admin_panel, matrix_client_pc)imagegen(image_to_3d_studio)osint_graph(graph_explorer)aurgi(sus analyses sí están en Gitea; el paraguas no)
- Fix de datos de los 4 paraguas huérfanos — pendiente, requiere el PC origen. No están en disco
ni en Gitea en este PC (
lucas-linux), así que no se pueden reconstruir aquí sin inventar. El fix correcto: correr/full-git-pushen el PC donde cada paraguas existe en disco (aurgi-pc/home-wsl). Confull_git_pushv1.1.0 (paso 1c) eso ya los crea en Gitea automáticamente. Tras eso,/full-git-pullaquí (paso 6) los traerá. NO reconstruir unproject.mdmínimo a mano. - DoD vida útil: validar el reclonado en un PC nuevo real (clon limpio del paraguas →
/full-git-pull→ árbol reconstruido) antes de declarar el issue cerrado.