---
id: "0059"
title: "Resolver doble tracking de `apps/*/app.md` (fn_registry + sub-repo)"
status: completado
type: infra
domain:
  - registry-quality
scope: app-scoped
priority: media
depends: []
blocks: []
related: []
created: 2026-05-17
updated: 2026-05-17
tags: []
---
# 0059 — Resolver doble tracking de `apps/*/app.md` (fn_registry + sub-repo)

## APP Metadata

| Campo | Valor |
|-------|-------|
| **ID** | 0059 |
| **Estado** | pendiente |
| **Prioridad** | media |
| **Tipo** | infra — git, .gitignore, indexer |

## Dependencias

- ADR 0002 (apps_analyses_as_dataforge_master): cada app es su propio repo.
- `.gitignore` raiz: `apps/*/`.

## Contexto

Detectado en sesion 2026-05-07:

- `.gitignore` de `fn_registry` excluye `apps/*/`.
- Pero `apps/dag_engine/app.md` aparece tracked tambien por `fn_registry` (legado pre-gitignore).
- Resultado: el mismo archivo fisico es tracked por DOS repos: `fn_registry` Y `dataforge/dag_engine` (sub-repo).
- Cualquier cambio crea conmits duplicados, status confuso, riesgo de divergencia.

```
$ git status  # en fn_registry
 M apps/dag_engine/app.md
$ git -C apps/dag_engine status
 M app.md
```

Mismo archivo. Dos `git add` distintos.

## Objetivo

Eliminar el doble tracking. Decidir source of truth y limpiar la otra.

## Decisiones a tomar

**Opcion A: source of truth = sub-repo.**
- `git rm --cached apps/*/app.md` en fn_registry (sin borrar archivo).
- `app.md` solo se commitea desde el sub-repo.
- `fn index` lee desde disco igual.
- PRO: consistente con ADR 0002 (sub-repo es la unidad).
- CONTRA: `app.md` no se versiona junto con cambios al registry que lo rompan (ej. funciones referenciadas que se borran).

**Opcion B: source of truth = fn_registry.**
- Sub-repo NO trackea `app.md` (anadir a su `.gitignore`).
- `fn_registry` lo versiona.
- PRO: el indexer y el registry tienen control directo.
- CONTRA: el sub-repo es incompleto (falta su propia ficha de identidad).

**Opcion C: ambos lo trackean conscientemente.**
- Documentar en regla nueva.
- Hook que bloquea desync (post-commit en uno avisa para commitear en el otro).
- PRO: cada repo es self-describing.
- CONTRA: complejidad operacional alta, riesgo de drift.

**Recomendada: Opcion A.** Alinea con ADR 0002. La cobertura "registry rompe app.md" se cubre con `fn doctor uses-functions` + pre-commit hook v2.

## Arquitectura

### Archivos afectados

- `.gitignore` raiz — verificar que `apps/*/` cubre todo.
- Posiblemente otros `apps/*/app.md` tracked legacy (auditar).
- `docs/adr/0004-app-md-source-of-truth.md` — NUEVO ADR.

## Tareas

### Fase 1 — auditar
1.1 `git ls-files apps/ | grep app.md` — listar todos los `app.md` tracked en fn_registry.
1.2 Cruzar con sub-repos para confirmar duplicacion.

### Fase 2 — decision (humano)
2.1 Confirmar Opcion A o cambiar a B/C con razon documentada.

### Fase 3 — implementacion (Opcion A)
3.1 Para cada `app.md` duplicado: confirmar que existe identico en el sub-repo.
3.2 `git rm --cached apps/<name>/app.md` en fn_registry.
3.3 Commit limpio en fn_registry.
3.4 No tocar el sub-repo (ya esta correcto).

### Fase 4 — ADR + docs
4.1 Crear `docs/adr/0004-app-md-source-of-truth.md` con la decision y razon.
4.2 Actualizar `.claude/rules/cpp_apps.md` y `apps_vs_functions.md` si mencionan tracking.

## Riesgos

- Si el indexer asume que `app.md` esta tracked en fn_registry (no es el caso, lee de disco), cero impacto.
- Si `fn sync` o `pc_locations` asumen tracking, validar que solo dependen del archivo fisico.

## Decisiones de diseno

- Opcion A es coherente con ADR 0002 — apps son sub-repos completos.
