chore: snapshot WIP previo + flow 0008 + 7 sub-issues (0112-0119)
Snapshot de WIP acumulado de sesiones previas antes de merge wave 1 del flow 0008 (kanban_cpp + agent_runner_api + DoD schema). Incluye: - dev/flows/0008-kanban-cpp-and-agent-workflows.md - dev/issues/0112-0119*.md (7 sub-issues) - WIP previo en cmd/fn/doctor.go, registry/*, modules/, cpp/, etc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
---
|
||||
name: audit_services_spec
|
||||
kind: function
|
||||
lang: go
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "func AuditServicesSpec(registryRoot string) ([]ServiceSpecAudit, error)"
|
||||
description: "Audita apps con tag 'service': reporta drift entre el bloque service: del app.md y los datos requeridos por el monitor (port, health_endpoint, systemd_unit, pc_targets). Lee registry.db read-only via sql.Open. Issue 0105."
|
||||
tags: [audit, services, doctor, registry, sqlite, issue-0105]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: error_go_core
|
||||
imports:
|
||||
- database/sql
|
||||
- github.com/mattn/go-sqlite3
|
||||
tested: false
|
||||
file_path: functions/infra/audit_services_spec.go
|
||||
params:
|
||||
- name: registryRoot
|
||||
desc: "Ruta absoluta a la raiz del fn_registry (donde vive registry.db)."
|
||||
output: "Slice de ServiceSpecAudit (uno por app con tag service). OK=false si Issues no esta vacio."
|
||||
---
|
||||
|
||||
# audit_services_spec
|
||||
|
||||
Reporta apps con tag `service` cuya `service:` block esta incompleta.
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
- Subcomando `fn doctor services-spec` (este es su unico consumer hoy).
|
||||
- Antes de desplegar `services_monitor` (issue 0106) — si esta funcion devuelve `OK=false` para alguna app, el monitor no puede reconciliar estado.
|
||||
- En CI/cron para detectar regresiones cuando alguien crea app `tag: service` sin bloque.
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```go
|
||||
audits, err := infra.AuditServicesSpec("/home/lucas/fn_registry")
|
||||
for _, a := range audits {
|
||||
if !a.OK {
|
||||
fmt.Println(a.AppID, "issues:", a.Issues)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Reglas que valida
|
||||
|
||||
- bloque presente (alguno de runtime/systemd_unit/port/health_endpoint != default).
|
||||
- `runtime` declarado y en allowlist (`systemd-user`, `systemd-system`, `docker-compose`, `stdio`, `manual`).
|
||||
- `pc_targets` con al menos 1 pc_id (cruzado contra tabla `service_targets`).
|
||||
- `runtime` empieza con `systemd-` ⇒ `systemd_unit` obligatorio.
|
||||
- `restart_policy` (si declarada) en `always`, `on-failure`, `none`.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Lee `registry.db` en modo `?mode=ro`; si la base no existe o esta locked retorna error.
|
||||
- `service:` bloque parcial pasa el check `HasBlock=true` pero falla validaciones especificas — ver `Issues[]` para detalles.
|
||||
- No valida que el `port` este libre o el `systemd_unit` exista en disco; eso lo hace `services_status_go_infra` (runtime check).
|
||||
Reference in New Issue
Block a user