Files
fn_registry/dev/issues/0007a-dag-core.md
T
egutierrez d9b448a07b feat: add DAG engine issues (0007a-e) and feature flag
Desglose del sistema de orquestacion propio para reemplazar Dagu:
- 0007a: core puro (parse, validate, topo sort)
- 0007b: process manager (spawn, wait, kill)
- 0007c: execution store (SQLite)
- 0007d: scheduler (cron parser, ticker)
- 0007e: app CLI que compone todo

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 01:18:19 +02:00

4.6 KiB

0007a — Funciones core del DAG engine

Metadata

Campo Valor
ID 0007a
Estado pendiente
Prioridad alta
Tipo feature

Dependencias

ID Título Estado Requerido
Ninguna

Bloqueada por: ninguna

Desbloquea: #0007b, #0007c, #0007d, #0007e


Objetivo

Crear las funciones puras que parsean, validan y ordenan DAGs definidos en YAML. Estas funciones son el nucleo del sistema de orquestacion — todo lo demas depende de ellas.

Contexto

  • Dagu usa YAML con steps, depends, env, schedule — queremos compatibilidad con ese formato
  • Las funciones deben ser puras: reciben datos, retornan datos, sin I/O
  • Deben vivir en functions/core/ (Go) para maxima composabilidad
  • El formato YAML de Dagu existente en ~/dagu/dags/ debe poder parsearse sin cambios

Arquitectura

functions/core/
├── dag_parse.go         — NEW: YAML → DagDefinition
├── dag_parse.md         — NEW: metadata
├── dag_validate.go      — NEW: valida ciclos, refs rotas, campos requeridos
├── dag_validate.md      — NEW: metadata
├── dag_topo_sort.go     — NEW: ordena steps por dependencias (Kahn's algorithm)
├── dag_topo_sort.md     — NEW: metadata
├── dag_resolve_env.go   — NEW: sustituye variables ${VAR} en steps
├── dag_resolve_env.md   — NEW: metadata

types/core/
├── dag_definition.md    — NEW: tipo DagDefinition (product)
├── dag_step.md          — NEW: tipo DagStep (product)
├── dag_schedule.md      — NEW: tipo DagSchedule (product)
├── dag_result.md        — NEW: tipo DagValidationResult (product)

Patron pure core / impure shell

  • core/ — Todas las funciones de este issue son puras
  • No hay shell/impure en este issue
  • Los tipos usan nativos de Go en firmas, tipos del registry en uses_types

Tareas

Fase 1: Tipos

  • 1.1 Definir DagStep — name, command, args, depends, env, timeout, retry, tags
  • 1.2 Definir DagSchedule — cron expressions, timezone
  • 1.3 Definir DagDefinition — name, description, steps, env, schedule, tags
  • 1.4 Definir DagValidationResult — errors, warnings, step_order

Fase 2: Parser

  • 2.1 dag_parse — YAML bytes → DagDefinition. Soportar formato Dagu: steps con command/depends/env
  • 2.2 Tests: parsear DAGs existentes de ~/dagu/dags/, edge cases (YAML invalido, campos faltantes)

Fase 3: Validacion

  • 3.1 dag_validate — detectar ciclos (DFS), referencias rotas en depends, steps sin nombre, nombres duplicados
  • 3.2 Tests: grafos ciclicos, DAGs validos, depends a steps inexistentes

Fase 4: Topological sort

  • 4.1 dag_topo_sort — Kahn's algorithm, retorna steps en orden de ejecucion con niveles de paralelismo
  • 4.2 Tests: DAGs lineales, DAGs con ramas paralelas, diamond dependencies

Fase 5: Resolucion de env

  • 5.1 dag_resolve_env — sustituye ${VAR} y $VAR en command/args de cada step usando env del DAG + env del step
  • 5.2 Tests: variables anidadas, variables no definidas, escaping

Fase 6: Cleanup

  • fn index y verificar todos los IDs
  • Verificar que todos los tipos son referenciados correctamente en uses_types

Ejemplo de uso

// Parsear un DAG
data, _ := os.ReadFile("dags/my_pipeline.yaml")
dag, err := dag_parse(data)

// Validar
result := dag_validate(dag)
if len(result.Errors) > 0 {
    // ciclos, refs rotas...
}

// Ordenar
ordered := dag_topo_sort(dag.Steps)
// ordered = [[step_a], [step_b, step_c], [step_d]]
//            nivel 0    nivel 1 (paralelo) nivel 2

// Resolver env
resolved := dag_resolve_env(dag, os.Environ())

Decisiones de diseno

  • Kahn's algorithm sobre DFS topo sort: Kahn's da niveles de paralelismo gratis — steps en el mismo nivel pueden ejecutarse en paralelo
  • Formato Dagu compatible: no inventar formato nuevo, reutilizar el YAML que ya existe
  • Tipos nativos en firma: []byte entrada, structs con campos basicos, sin dependencias externas para parsear

Criterios de aceptacion

  • dag_parse parsea correctamente los DAGs existentes en ~/dagu/dags/
  • dag_validate detecta ciclos y referencias rotas
  • dag_topo_sort retorna orden correcto con niveles de paralelismo
  • Todas las funciones son puras (sin I/O, sin estado)
  • Tests pasan con go test -tags fts5 ./...
  • Indexado en registry.db

Referencias

  • Dagu YAML spec: ~/dagu/dags/example.yaml
  • Kahn's algorithm: topological sort con BFS que da niveles