chore: auto-commit (8 archivos)
- .claude/rules/registry_calls.md - apps/dag_engine/README.md - apps/dag_engine/app.md - docs/capabilities/INDEX.md - docs/capabilities/systemd.md - docs/execution_standard.md - dev/proposals_e2e_checks_0121/ - docs/capabilities/backends.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+29
-26
@@ -1,6 +1,6 @@
|
||||
# Estandar de Ejecucion: YAML + Exit Codes + Hooks
|
||||
|
||||
Contrato comun para apps, pipelines y automatizaciones del fn-registry. Define como declarar flujos en YAML, que exit codes devolver, como reportar resultados y como integrarse con Dagu y operations.db.
|
||||
Contrato comun para apps, pipelines y automatizaciones del fn-registry. Define como declarar flujos en YAML, que exit codes devolver, como reportar resultados y como integrarse con dag_engine y operations.db.
|
||||
|
||||
---
|
||||
|
||||
@@ -8,7 +8,7 @@ Contrato comun para apps, pipelines y automatizaciones del fn-registry. Define c
|
||||
|
||||
Tenemos dos patrones que ya funcionan:
|
||||
|
||||
- **Dagu**: orquesta DAGs con `command`/`script`, usa exit codes para decidir flujo, tiene handlers globales y scheduling cron.
|
||||
- **dag_engine** (`apps/dag_engine/`): orquesta DAGs con `command`/`function`, usa exit codes para decidir flujo, soporta `handlers` (init/success/failure/exit) y scheduling cron via `schedule:`.
|
||||
- **script_navegador**: ejecuta pasos tipados (CDP actions) desde YAML, registra todo en operations.db, sale con 0/1.
|
||||
|
||||
Ambos comparten la misma idea: **YAML declara el flujo, exit code señala el resultado, logs estructurados permiten analisis posterior**. Este documento formaliza ese contrato para que cualquier app nueva lo siga desde el inicio.
|
||||
@@ -73,7 +73,8 @@ Cada app registra sus actions validos. Ejemplos:
|
||||
| Dominio | Actions | App de referencia |
|
||||
|---------|---------|-------------------|
|
||||
| navegacion | `navigate`, `click`, `type`, `wait`, `screenshot`, `evaluate`, `get_html`, `wait_load`, `sleep` | script_navegador |
|
||||
| shell | `command`, `script` | Dagu / apps genericas |
|
||||
| shell | `command`, `script` | dag_engine / apps genericas |
|
||||
| registry | `function`, `args` | dag_engine (invoca `fn run <id>` y captura `function_id` en `dag_step_results`) |
|
||||
| database | `query`, `migrate`, `backup` | futuras apps |
|
||||
| http | `request`, `assert_status`, `extract` | futuras apps |
|
||||
|
||||
@@ -96,16 +97,16 @@ Toda app/script que siga este estandar DEBE salir con uno de estos tres codigos:
|
||||
- Si algun paso falla pero todos los fallos tenian `continue_on_error: true` → `2`
|
||||
- Un timeout agotado cuenta como fallo del paso
|
||||
|
||||
### Compatibilidad con Dagu
|
||||
### Compatibilidad con dag_engine
|
||||
|
||||
Dagu interpreta exit code != 0 como fallo. Para que `2` (partial) no dispare el handler de failure en Dagu, el DAG que llama a la app puede usar:
|
||||
dag_engine interpreta exit code != 0 como fallo. Para que `2` (partial) no dispare el handler de failure, el DAG que llama a la app puede usar `continue_on.exit_code`:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- name: run_app
|
||||
command: ./mi_app --script flujo.yaml
|
||||
continue_on:
|
||||
failure: true # no abortar el DAG por parcial
|
||||
exit_code: [2] # exit 2 no aborta el DAG (partial es tolerado)
|
||||
- name: check_result
|
||||
command: test $? -le 1 # falla solo si fue error fatal
|
||||
depends: [run_app]
|
||||
@@ -152,10 +153,10 @@ Toda app DEBE escribir un **resumen JSON en stdout** al finalizar (despues de su
|
||||
### Separacion humano / maquina
|
||||
|
||||
- **stderr**: logs legibles para humanos (progreso, warnings)
|
||||
- **stdout**: output JSON estructurado al final (para Dagu, hooks, pipes)
|
||||
- **stdout**: output JSON estructurado al final (para dag_engine, hooks, pipes)
|
||||
- Flag `--json` o `--quiet`: suprime output humano, solo JSON en stdout
|
||||
|
||||
Esto permite que Dagu capture el JSON:
|
||||
Esto permite que dag_engine capture el JSON:
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
@@ -197,23 +198,24 @@ hooks:
|
||||
| `{{.StepName}}` | string | Nombre del paso (solo en on_step_error) |
|
||||
| `{{.Error}}` | string | Mensaje de error (solo en on_step_error/on_failure) |
|
||||
|
||||
### En Dagu (handlers globales)
|
||||
### En dag_engine (handlers globales)
|
||||
|
||||
Los hooks del YAML son locales al flujo. Para orquestacion, Dagu maneja sus propios handlers:
|
||||
Los hooks del YAML son locales al flujo. Para orquestacion, dag_engine maneja sus propios handlers (`init/success/failure/exit`, alias `handler_on`):
|
||||
|
||||
```yaml
|
||||
# dags/mi_automatizacion.yaml
|
||||
# apps/dag_engine/dags_migrated/mi_automatizacion.yaml
|
||||
name: mi_automatizacion
|
||||
handlers:
|
||||
failure:
|
||||
- name: alerta
|
||||
command: echo "Fallo en mi_automatizacion" >> ~/dagu/logs/failures.log
|
||||
command: echo "Fallo en mi_automatizacion" >> /var/log/fn_registry/failures.log
|
||||
success:
|
||||
- name: registrar
|
||||
command: echo "OK $(date)" >> ~/dagu/logs/success.log
|
||||
command: echo "OK $(date)" >> /var/log/fn_registry/success.log
|
||||
steps:
|
||||
- name: ejecutar
|
||||
command: ./fn run mi_pipeline --script flujo.yaml
|
||||
function: mi_pipeline_bash_pipelines
|
||||
args: ["flujo.yaml"]
|
||||
```
|
||||
|
||||
---
|
||||
@@ -249,15 +251,15 @@ Este patron ya esta implementado en `script_navegador/ops.go` y sirve como refer
|
||||
|
||||
---
|
||||
|
||||
## 6. Flujo completo: App → Dagu → Hooks
|
||||
## 6. Flujo completo: App → dag_engine → Hooks
|
||||
|
||||
```
|
||||
Dagu (scheduler)
|
||||
dag_engine (scheduler)
|
||||
│
|
||||
cron / manual
|
||||
cron / manual / API
|
||||
│
|
||||
┌────▼────┐
|
||||
│ DAG │ dags/mi_dag.yaml
|
||||
│ DAG │ apps/dag_engine/dags_migrated/mi_dag.yaml
|
||||
│ step │ command: ./mi_app --script flujo.yaml --json
|
||||
└────┬────┘
|
||||
│
|
||||
@@ -280,11 +282,11 @@ Este patron ya esta implementado en `script_navegador/ops.go` y sirve como refer
|
||||
success failure partial
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
Dagu OK Dagu FAIL Dagu FAIL*
|
||||
handler handler (configurable)
|
||||
engine OK engine FAIL engine FAIL*
|
||||
handler handler (configurable)
|
||||
```
|
||||
|
||||
*Con `continue_on: failure: true` en el step de Dagu, exit 2 no aborta el DAG.
|
||||
*Con `continue_on: { exit_code: [2] }` en el step, exit 2 no aborta el DAG.
|
||||
|
||||
---
|
||||
|
||||
@@ -330,19 +332,20 @@ hooks:
|
||||
on_failure: "echo 'Backup fallo' >> /tmp/backup_errors.log"
|
||||
```
|
||||
|
||||
### Invocacion desde Dagu
|
||||
### Invocacion desde dag_engine
|
||||
|
||||
```yaml
|
||||
name: backup_diario
|
||||
schedule: "0 2 * * *"
|
||||
working_dir: /home/lucas/fn_registry/apps/mi_app
|
||||
steps:
|
||||
- name: backup
|
||||
command: ./fn run backup_db --script flujo.yaml --json
|
||||
working_dir: /home/lucas/fn_registry/apps/mi_app
|
||||
function: backup_db_bash_pipelines
|
||||
args: ["flujo.yaml", "--json"]
|
||||
handlers:
|
||||
failure:
|
||||
- name: alerta
|
||||
command: echo "Backup fallo $(date)" >> ~/dagu/logs/failures.log
|
||||
command: echo "Backup fallo $(date)" >> /var/log/fn_registry/failures.log
|
||||
```
|
||||
|
||||
### Output esperado (stdout)
|
||||
@@ -380,5 +383,5 @@ Exit code: `2` (partial — push fallo pero tenia continue_on_error).
|
||||
| Output humano | stderr (progreso, warnings) |
|
||||
| Error handling | `continue_on_error` por paso, hooks por resultado |
|
||||
| Trazabilidad | operations.db (executions + logs) |
|
||||
| Orquestacion | Dagu como scheduler, apps como ejecutores |
|
||||
| Orquestacion | dag_engine como scheduler (`apps/dag_engine/`), apps/funciones del registry como ejecutores |
|
||||
| Funciones | Reutilizar del registry, actions por dominio |
|
||||
|
||||
Reference in New Issue
Block a user