e3c8979e8d
- cmd/fn/doctor.go - cmd/fn/main.go - cpp/apps/primitives_gallery/playground/tables/CMakeLists.txt - cpp/apps/primitives_gallery/playground/tables/data_table.cpp - cpp/apps/primitives_gallery/playground/tables/data_table_logic.cpp - cpp/apps/primitives_gallery/playground/tables/data_table_logic.h - cpp/apps/primitives_gallery/playground/tables/self_test.cpp - cpp/apps/primitives_gallery/playground/tables/tql.cpp - cpp/apps/primitives_gallery/playground/tables/viz.cpp - cpp/apps/primitives_gallery/playground/tables/viz.h - ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
67 lines
2.4 KiB
Markdown
67 lines
2.4 KiB
Markdown
---
|
|
name: vault_doctor
|
|
kind: function
|
|
lang: go
|
|
domain: infra
|
|
version: "1.0.0"
|
|
purity: impure
|
|
signature: "func VaultDoctor(repoRoot string) ([]VaultDoctorEntry, error)"
|
|
description: "Audita la salud de todos los vaults declarados en projects/*/vaults/vault.yaml. Comprueba existencia del directorio, layout estándar, presencia del índice, staleness y drift entre disco e índice. Read-only."
|
|
tags: [vault, doctor, health, audit]
|
|
uses_functions:
|
|
- "vault_manifest_read_go_infra"
|
|
- "vault_index_open_go_infra"
|
|
uses_types: []
|
|
returns: []
|
|
returns_optional: false
|
|
error_type: "error_go_core"
|
|
imports:
|
|
- "fmt"
|
|
- "os"
|
|
- "path/filepath"
|
|
- "strings"
|
|
- "time"
|
|
tested: true
|
|
tests:
|
|
- "TestVaultDoctor_OK"
|
|
- "TestVaultDoctor_MissingDir"
|
|
- "TestVaultDoctor_NoIndex"
|
|
- "TestVaultDoctor_LayoutDrift"
|
|
- "TestVaultDoctor_EmptyVault"
|
|
test_file_path: "functions/infra/vault_doctor_test.go"
|
|
file_path: "functions/infra/vault_doctor.go"
|
|
params:
|
|
- name: repoRoot
|
|
desc: "Ruta absoluta a la raiz del fn_registry (donde están projects/ y registry.db)."
|
|
output: "Slice de VaultDoctorEntry con Status (ok/warning/error), Issues, DiskFiles, IndexedFiles y LastIndexedAt por vault. Error fatal solo si los manifests no se pueden leer."
|
|
---
|
|
|
|
## Checks aplicados
|
|
|
|
| Check | Condición | Severidad |
|
|
|---|---|---|
|
|
| `directory_missing` | `e.Path` no existe en disco | error |
|
|
| `layout_missing` | no hay `data/` ni `knowledge/` en la raíz del vault | warning |
|
|
| `non_standard_layout` | no hay `data/`/`knowledge/` pero sí otros subdirectorios (ej. imagegen_models) | warning |
|
|
| `index_missing` | no existe `vault_index.db` | warning |
|
|
| `index_stale` | algún archivo en disco tiene mtime > MAX(indexed_at) | warning |
|
|
| `index_drift` | count disco != count en tabla `files` | warning |
|
|
| `empty_vault` | DiskFiles == 0 | warning |
|
|
|
|
## Ejemplo
|
|
|
|
```go
|
|
entries, err := infra.VaultDoctor("/home/lucas/fn_registry")
|
|
for _, e := range entries {
|
|
fmt.Printf("%-30s %-8s files=%d issues=%v\n",
|
|
e.VaultName, e.Status, e.DiskFiles, e.Issues)
|
|
}
|
|
```
|
|
|
|
## Notas
|
|
|
|
- Función read-only: nunca escribe en disco ni en ninguna base de datos.
|
|
- `countDiskFiles` usa `filepath.WalkDir` sin hash (cheap) — excluye `vault_index.db*`, `.git/` y ficheros ocultos.
|
|
- `isIndexStale` también usa WalkDir; compara mtime de archivos con MAX(indexed_at) de la BD.
|
|
- El VaultIndexOpen de sólo lectura no crea el DB (si no existe, retorna error y se reporta `index_missing`).
|