# ADR 0002 — Apps y analyses como repos `dataforge/<name>` en branch `master`

- **Fecha:** 2026-04-28
- **Estado:** accepted

## Contexto

Cada app (`apps/<name>`, `projects/*/apps/<name>`) y cada analysis (`analysis/<name>`, `projects/*/analysis/<name>`) en `fn_registry` vive como repo git independiente: el repo padre los `.gitignore`a y solo conserva su metadata indexada en `registry.db`. Esto permite clonar/desplegar/compartir cada artefacto sin arrastrar el monorepo entero.

Hasta 2026-04-28 el sistema tenia tres inconsistencias:

1. **Owners mezclados en Gitea**: la mayoria pusheaba a `dataforge/<name>`, pero `projects/element_agents/apps/{agents_and_robots,element_matrix_chat}` apuntaban a `egutierrez/<name>` (uno no existia, otro sin permisos de push).
2. **Apps/analyses sin `.git`**: `apps/{deploy_server,shaders_lab,voice_guide}` y `analysis/{agent_coding_eval,ontology_graph}` + `projects/app_turismo/analysis/turismo_spain` no estaban en Gitea — imposibles de recuperar en otro PC.
3. **Mezcla de ramas `main` vs `master`**: 10 repos en `main` (creados antes de unificar convencion), 14 en `master`. La causa raiz era `init.defaultBranch` sin configurar globalmente, asi que `git init` daba lo que la version de git decidiera, y las primeras pushes fijaban el default branch en Gitea.

## Decision

1. **Owner unico en Gitea: `dataforge`**. Toda app/analysis del registry vive en `https://gitea.../dataforge/<basename>`. `dataforge` es un *user* en Gitea (no org), asi que `gitea_create_repo` cae al endpoint `/api/v1/user/repos` automaticamente.
2. **Branch unico: `master`**. Coherente con `fn_registry` (raiz), con la mayoria de apps/analyses, y con `subrepos/fn-design-system`. Configuracion enforced con `git config --global init.defaultBranch master` en cada PC.
3. **Vaults NO siguen esta regla**. Los vaults son datos puros — su mecanismo de compartir queda pendiente (TBD: object storage, rsync programado, restic). Hasta entonces, no se versionan en Gitea.
4. **`subrepos/` NO entran**. Son mirrors upstream (Claude Design, etc.); se gestionan con su propio remote dual y no participan de `/full-git-push` / `/full-git-pull`.

### Helpers introducidos

- `ensure_repo_synced_bash_infra` — pipeline idempotente que crea repo Gitea + init local + commit + push.
- `/full-git-push` descubre apps/analyses sin `.git` y los inicializa.
- `/full-git-pull` tras `fn sync` clona los `dataforge/<name>` faltantes localmente.

## Alternativas descartadas

- **Owner por usuario** (`egutierrez/<name>`): obligaria a tener tokens distintos por PC y limitaria colaboracion. Descartado.
- **Submodules en `fn_registry`**: se probo (ver ADR 0001 — GitButler). Bugs con gitlinks, commits cruzados y duplicacion. Descartado.
- **Branch `main`**: estandar moderno (GitHub default), pero `fn_registry` raiz, deploy scripts y la mayoria de apps ya estaban en `master`. Migrar todo a `main` requeria mas cambios que migrar 10 repos a `master`. Decidido por minimizar churn.

## Consecuencias

- Recuperar todo el ecosistema en un PC nuevo: `git clone fn_registry` + `/full-git-pull` (clona los dataforge/* registrados via `fn sync`).
- Crear app/analysis nueva: el pipeline `init_jupyter_analysis` o el flujo manual debe invocar `ensure_repo_synced` con defaults `owner=dataforge branch=master`.
- Cualquier outlier en otro owner o branch se detecta facilmente con la query del audit (ver `.claude/rules/apps_own_repo.md`).
- Si se anaden mas branches (feature, issue/*), siguen las reglas de `apps_tbd.md`. La convencion solo fija el tronco principal.

## Cambios concretos aplicados (2026-04-28)

- 2 repos movidos a `dataforge/`: `agents_and_robots`, `element_matrix_chat`.
- 6 repos creados desde cero: `deploy_server`, `shaders_lab`, `voice_guide`, `agent_coding_eval`, `ontology_graph`, `turismo_spain`.
- 10 repos migrados `main` → `master`: `apps/{docker_tui,fuzzygraph,metabase_registry,pipeline_launcher,rapid_dashboards,script_navegador}`, `analysis/{estudio_embeddings,estudio_mercados,pruebas_jupyter,retrieving_graphs}`.
- `git config --global init.defaultBranch master`.
