---
id: 0033c
title: Comando `fn check vendored` — drift detection
status: pending
priority: medium
created: 2026-05-02
depends_on: [0033b]
---

## Objetivo

Subcomando del CLI `fn` para detectar drift entre los `_vendored/`
de los enrichers y la fuente del registry. Permite auditoria en CI y
diagnostico rapido cuando algo deja de funcionar tras editar una
funcion.

## CLI

```bash
fn check vendored                          # recorre todas las apps con vendoring
fn check vendored apps/graph_explorer      # solo esta app
fn check vendored --fix                    # re-vendoriza si detecta drift
```

Salida esperada:

```
[OK]    apps/graph_explorer/enrichers/fetch_webpage         3 funcs, lock OK
[DRIFT] apps/graph_explorer/enrichers/extract_links         1 func cambio
        - extract_urls_py_cybersecurity (lock=abc123, current=def456)
[MISS]  apps/graph_explorer/enrichers/web_search            sin .vendor.lock
```

Exit codes:
- 0: todo OK
- 1: drift detectado
- 2: error operativo (manifest invalido, registry.db inaccesible)

## Implementacion

`cmd/fn/check_vendored.go`:
1. Glob `apps/*/enrichers/*/manifest.yaml` y
   `projects/*/apps/*/enrichers/*/manifest.yaml`.
2. Filtrar los con `lang: python` y `uses_functions` no vacio.
3. Por cada uno:
   - Si no existe `.vendor.lock` → MISS.
   - Por cada linea del lock: leer `file_path` actual de registry.db,
     calcular sha256, comparar.
4. Con `--fix`: invocar `vendor_enricher_python.sh` cuando se detecta
   drift o miss.

## Tests

- Caso OK: manifest + lock + ficheros consistentes.
- Caso DRIFT: editamos un .py vendorizado, el comando lo detecta.
- Caso MISS: enricher con `lang: python` y `uses_functions` no vacio
  pero sin lock.
- Caso `--fix`: tras drift, ejecutar con `--fix` deja todo OK.

## Definicion de hecho

- `fn check vendored` reporta el estado correctamente en los 3
  casos.
- `--fix` re-vendoriza y deja exit code 0.
- Tests Go en `cmd/fn/check_vendored_test.go`.
