Volver a Hermes
En esta página La idea en 60 segundos 0%

Un proyecto full-stack nuevo cada día con Hermes Agent

Cómo organizo, coordino y mejoro un pipeline de 3 crons que construye, valida y despliega un proyecto Angular + NestJS + Neon Database completo cada día — y cómo un 4º cron “de reunión diaria” mantiene sincronizado a todo mi equipo de agentes.

Este documento explica el sistema que uso en mi portafolio: la infraestructura de agentes que hay detrás de los proyectos que ves publicados en cristiancode.dev/hermes.


La idea en 60 segundos

Tengo un equipo de agentes Hermes trabajando en un VPS. Cada madrugada, sin intervención humana, ejecutan una cadena de producción de software completa:

02:30  design-specs-builder   → diseña el proyecto del día (specs de 8 documentos)
03:30  hermes-daily-builder   → construye el proyecto Angular 22 + NestJS
07:00  qa-tester-deployer     → QA, tests, y despliegue a subdominio público
19:00  daily-cross-profile    → "reunión diaria": resume y sincroniza a todo el equipo

Cada día sale un proyecto full-stack nuevo, único, testeado y desplegado en https://<proyecto>.proyectos.cristiancode.dev, documentado y añadido a mi portafolio en 3 idiomas (es/en/pt).

Y la parte más importante: el sistema aprende. Cada proyecto registra qué aprendió, qué patrones reutilizó y qué errores nuevos descubrió. El proyecto siguiente se construye con ese conocimiento ya incorporado. Por eso “cada vez funciona mejor”: la cadena lleva 50+ proyectos y cada uno es ligeramente más sólido que el anterior.


Los 3 crons de la cadena de producción

#CronHoraSkill principalEntregable
1design-specs-builder02:30design-specs-builder, impeccable, claude-design, popular-web-designs, design-md8 archivos de especificación + DONE.marker
2hermes-daily-builder03:30impeccable, claude-design, design-md, excalidraw, ux-ui-reviewRepositorio full-stack completo + build OK
3qa-tester-deployer07:00qa-testing, software-quality, debugging, impeccableQA_REPORT.md + TEST_DONE.marker + despliegue en subdominio

Cada cron recibe como contexto el resultado del cron anterior (encadenamiento con context_from): el builder sabe qué specs se generaron a las 02:30, y el QA sabe qué proyecto construyó el builder a las 03:30. Esto crea una línea de montaje donde cada eslabón trabaja con datos reales, nunca con suposiciones.


Cron 1 — Design Specs Builder (02:30)

“Antes de escribir código, hay que saber exactamente qué construir.”

Este cron decide qué proyecto toca hoy y genera un paquete de especificaciones de 8 documentos. Toma todas las decisiones de forma autónoma, siguiendo reglas estrictas:

1.1 Cómo elige el concepto del día

  • Temática por día de la semana (tabla fija del skill):
DíaTemaEjemplos
LunesGestión / ManagementCRM, planificador
MartesUtilidad / Utilityconversores, calculadoras
MiércolesDashboard / WidgetKPIs, analítica, sprints
JuevesSocial / Communityforos, intercambio de skills
ViernesCreativo / Herramientabuilders, editores
SábadoJuego / Gamificaciónjuegos, puzzles, retos
DomingoPersonal / Wellnesshábitos, journal, salud
  • Rotación de dominios: el proyecto debe ser de un dominio distinto a los últimos 10. CardClash (sábado 01-08) fue el 21º dominio distinto — “card battles” no se parecía a nada de los 10 anteriores (quill, huddle, subwatch, sprintflow, teampolls, readstack, tinytag, goal-compass, daymark, riddlecraft).
  • Ejercitar las 2 skills más débiles: la matriz de skills (SKILL_MATRIX.md) mantiene niveles auto-evaluados 1–5. El proyecto del día debe ejercitar al menos una de las dos más bajas. Eso fuerza la mejora continua en lugar de repetir lo que ya se domina.
  • Contador AI (CYCLE): un contador de ciclo 1–3 produce builds “full-stack puro”, y en 4 toca un proyecto con integración de IA (AI Ladder). El nivel de dificultad va subiendo de forma controlada.

1.2 Validación de unicidad exhaustiva (5 fuentes)

Antes de comprometer un nombre de proyecto, comprueba 5 fuentes independientes:

  1. repositorios/ — proyectos full-stack ya construidos
  2. kimi3/ — otros proyectos desplegados
  3. Subdominios activos en proyectos.cristiancode.dev (curl real)
  4. Registro de slugs del portafolio (locales/es.ts)
  5. Paquetes de specs anteriores

Si el nombre, slug o dominio ya existe (o es demasiado parecido), descarta la idea y elige otra. Cada proyecto debe ser 100% nuevo.

1.3 El paquete de 8 documentos

Genera en /opt/data/hermes-design-specs/YYYY-MM-DD-<proyecto>/:

ArchivoContenido
PROJECT.mdPitch, stack, audiencia, features Must/Should/Could, entidades, criterios de éxito + Decision Record (contador, día, dominio, por qué este proyecto, evidencia de unicidad)
DESIGN_SYSTEM.mdPaleta única por proyecto (5+ colores, light + dark, formato Tailwind v4 @theme) — prohibido reutilizar o copiar paletas
WIREFRAMES.mdWireframes ASCII de cada pantalla con estados loading/empty/error documentados (desktop 1440×900 y mobile 390×844)
USER_STORIES.mdHistorias COMO/QUIERO/PARA con criterios de aceptación numerados y escenarios de validación concretos
COMPONENT_TREE.mdArquitectura de componentes, servicios, jerarquía
ROUTES.mdRutas frontend + endpoints API (método, path, auth, body, respuesta)
DATABASE_SCHEMA.mdEntidades con columnas/tipos/restricciones, decoradores TypeORM, SQL DDL completo, índices, consultas de agregación
FLOW_DIAGRAM.mdDiagramas Mermaid de flujos críticos + mapa de journey

DONE.marker: se crea al final, solo cuando los 8 archivos existen y pasan una auditoría de consistencia (9 checks automáticos: entidades ↔ esquema, rutas ↔ componentes, ≥15 user stories, ≥20 endpoints, bloques Mermaid balanceados, ≥15 tokens de color, light + dark mode…). Sin ese marker, el builder de las 03:30 no recoge las specs.

Pitfall resuelto en el camino: el journal de memoria (MEMORY.md) puede quedarse desfasado; cuando pasa, el sistema aprende a usar los Decision Records de los paquetes recientes como fuente autoritativa del contador en lugar de confiar en un archivo viejo.


Cron 2 — Hermes Daily Builder (03:30)

“De las specs a un proyecto que compila.”

Este es el corazón de la cadena. Lee las specs generadas a las 02:30 y construye el proyecto completo. Sus reglas:

2.1 Regla de oro: 100% nuevo

  • ABSOLUTAMENTE PROHIBIDO rediseñar, mejorar o reconstruir un proyecto existente.
  • Re-verifica la unicidad contra repositorios/, kimi3/, landing y slugs del portafolio antes de empezar.
  • Si las specs describen algo que ya existe, las ignora y crea un concepto diferente. (Esto ya ha salvado la cadena más de una vez.)
  • Sistema isFinalDesign.true: si un proyecto tiene el diseño “cerrado” y aprobado, nadie lo vuelve a tocar visualmente — solo bugfixes.

2.2 Qué construye

  • Frontend: Angular 22 (standalone, signals, zoneless, Tailwind CSS v4 con tokens @theme, dark mode con CSS variables, lazy loading por ruta).
  • Backend: NestJS 11 (módulos feature, TypeORM, Swagger, JWT auth con Passport + bcrypt, DTOs con class-validator).
  • Base de datos: SQLite (better-sqlite3) para dev, esquema diseñado para PostgreSQL/Neon.
  • Seed data: usuarios demo, entidades reales con datos coherentes (p.ej. 6 hábitos con 14 días de datos).
  • Documentación: 7-8 archivos por proyecto (README, ARCHITECTURE, DATABASE, API, DECISIONS, FRONTEND, AI_INTEGRATION, LEARNINGS).
  • Tests: suite de unit tests del backend (10–21+ casos según el proyecto).
  • Git: 3 commits convencionales (docs → backend → frontend) y push a GitHub (github.com/cristiancode-hermes).

2.3 Cómo trabaja (técnica de subagentes paralelos)

Para cumplir el presupuesto de ~150 minutos, delega backend y frontend en paralelo a dos subagentes con contexto que especifica los nombres de campo EXACTOS (para evitar mismatches de interfaces). Cada subagente produce ~90-95% del código correcto; el agente principal dedica ~15-20 min a arreglar los desajustes típicos: imports, rutas vacías, app.config.ts, páginas faltantes, alineación de tipos.

2.4 Verificación antes de entregar

  • ng build (0 errores) y nest build (0 errores).
  • Tests pasando.
  • LEARNINGS.md documentando las lecciones del proyecto.

Al terminar, su informe final (que se entrega a Slack) es el contexto de entrada del cron siguiente: el QA sabe exactamente qué proyecto acaba de nacer.


Cron 3 — QA Tester + Deployer (07:00)

“Si no está testeado y desplegado, no está terminado.”

Este cron hace el control de calidad completo y despliega. Es el eslabón que garantiza que lo que ves publicado funciona de verdad — nada de “debería funcionar”.

3.1 Fases del QA

  1. Detección de tipo de proyecto — Angular+NestJS, C++/CLI, o standalone (usa un único flujo multi-stack).
  2. Pre-checks de diagnóstico — AppModule con imports reales, reflect-metadata, páginas existentes, versión de TypeScript compatible con Angular 22 (≥6.0.0), test runner correcto (Jest vs Vitest — usar el equivocado produce falsos fallos).
  3. Build verificationng build + nest build, borrando .tsbuildinfo obsoletos (un build incremental corrupto puede emitir “éxito” con dist/ vacío).
  4. Tests — suite completa con el runner real del proyecto.
  5. QA funcional por API — register/login con DTOs reales (varían por proyecto: email+password, username+email+password, name+organizationName+email+password…), endpoints autenticados, versionado URI (/api/v1/).
  6. Prueba de flujo en navegador — register → login → dashboard → logout → login, en el subdominio desplegado.
  7. Auditoría de calidad — criterios con veredicto por sección.
  8. Security scan — checks de seguridad estáticos.
  9. QA_REPORT.md — informe estructurado con tablas: build, tests, runtime, calidad, seguridad, despliegue.

3.2 Corrección de bugs (el QA también arregla)

No se limita a reportar: arregla. El skill qa-testing (v2.15.0) acumula un catálogo de ~30 pitfalls documentados con su diagnóstico y fix exacto, que se aplican de forma sistemática:

  • Token key mismatch backend ↔ frontend (token vs access_token)
  • Interceptor con template literal malformado (*** ${token} en vez de `Bearer ${token}`) — bug silencioso que compila OK
  • APP_GUARD global bloqueando rutas públicas de auth (401 en register/login)
  • Prefijo de ruta duplicado (/api/api/auth)
  • Columnas TypeORM con tipo unión sin type: explícito (crash de better-sqlite3)
  • SQL raw con snake_case cuando las columnas son camelCase (“userId” no user_id)
  • Palabras reservadas de SQLite como alias de columna sin comillas
  • Seed gateado detrás de SEED_DB=true
  • Zombie processes de Node que ocupan puertos

Cada bug nuevo descubierto en un proyecto se documenta como pitfall en el skill, con la causa raíz y el fix — así el siguiente proyecto ya no lo sufre. Esa es la mecánica de “cada vez funciona mejor”.

3.3 Despliegue

  • Puerto libre (convención 3040+), API arrancada y verificada con Swagger.
  • Entrada en el Caddyfile → subdominio https://<slug>.proyectos.cristiancode.dev (SPA routing + reverse proxy /api*).
  • Registro en manage-apis.sh (3 arrays: PORTS, NAMES, DIRS) para que sobreviva a reinicios del VPS.
  • Entrada en la landing page proyectos.cristiancode.dev (repo auto-desplegado en Netlify).
  • Entrada en el portafolio en 3 idiomas (es.ts, en.ts, pt.ts).
  • Registro en el config de capturas del portafolio (para los screenshots).
  • Verificación de enlaces obligatoria: href (web), link2 (README) y link3 (GitHub) con curl → todos HTTP 200. Si uno devuelve 404, es INCIDENCIA CRÍTICA y no se cierra el despliegue hasta arreglarlo.
  • Actualización de markers: TEST_DONE.marker con Published: ✅.

Cómo se coordinan: markers, contexto encadenado y estado compartido

La cadena no depende de la memoria de un agente — depende de artefactos en disco que cualquiera puede verificar:

Markers de estado (protocolo de handoff)

DESIGN_SPEC_DONE  → DONE.marker          (specs completas, 02:30)
BUILD_DONE        → proyecto + build OK   (03:30)
QA_DONE           → TEST_DONE.marker      (QA + deploy OK, 07:00)
CAPTURE_DONE      → screenshots reales    (11:00)

Si un eslabón falla, deja el marker correspondiente (DESIGN_SPEC_FAILED, BUILD_FAILED, TEST_FAILED…) y los siguientes crons cascada-fallan visiblemente — el supervisor puede diagnosticar en segundos en qué punto se rompió la cadena. El skill qa-testing incluye un procedimiento completo de recuperación de orfanatos (proyectos a medio construir) con pasos exactos.

Contexto encadenado (context_from)

design-specs-builder ──output──▶ hermes-daily-builder ──output──▶ qa-tester-deployer
       02:30                        03:30                            07:00

Cada cron recibe el output del anterior inyectado en su prompt. No hay “reuniones de planificación” ni adivinanzas: el QA sabe exactamente qué proyecto construyó el builder porque se lo pasa el sistema.

Estado compartido (hermes-builder-memory/)

ArchivoRol
CYCLE.mdContador 1–3 non-AI / 4 AI build
SKILL_MATRIX.mdNiveles 1–5 por skill con evidencia + bottom-2 (las que toca ejercitar)
MEMORY.mdJournal de cada proyecto (511+ líneas, formato tabla de aprendizaje)
BACKLOG.mdFeatures a arrastrar entre proyectos
PLAYBOOK.mdPatrones reutilizables (Angular signals, Tailwind v4, auth JWT, FTS5, state machines…)
incidents/Informes de incidentes (p.ej. 23 fallos seguidos de GitHub push)
PROCESS_PROPOSALS.mdPropuestas de mejora de proceso con impacto estimado

El sistema de aprendizaje: qué aprendo en cada proyecto y cómo lo documento

Esta es la parte que hace que el pipeline mejore día a día. Cada proyecto no es solo código: es una unidad de aprendizaje con 4 salidas documentadas.

1. El journal de memoria (MEMORY.md)

Cada proyecto añade una entrada con formato fijo: Fecha | Proyecto | Outcome | Grade | Key Learning | Next Difficulty. Por ejemplo (resumido de proyectos reales):

### 2026-06-14 | hermes-rag-knowledge-base
- Outcome: RAG completo (ingest → chunk → embed → retrieve → answer) con TF-IDF local,
  10/10 tests, 8 docs
- Grade: B+ (Scope B+, Code Quality B+, Build A, Docs A, AI B, Time B)
- Key Learning: 500-word chunks con 50-word overlap; TypeORM leftJoinAndSelect;
  el pipeline RAG es limpiamente separable en módulos
- Next Difficulty: 5 (Neon PostgreSQL + LLM real)

Y además dos secciones comparativas por proyecto:

  • Improvements over last project — qué se hizo mejor que el anterior (más tests, más módulos, primer push a GitHub tras 24 fallos…).
  • Applied Lessons From <proyecto anterior> — qué lecciones del anterior se reutilizaron (✅ multi-tenant scoping, ✅ CSS variable dark mode, ✅ subagent pattern…).

Esto convierte cada build en un ciclo PDCA real: Plan → Do → Check → Act, con evidencia escrita.

2. La matriz de skills (SKILL_MATRIX.md)

Auto-evaluación con evidencia por skill:

| Angular Signals | 4 | 6 lazy routes con arquitectura signal-first, 3-panel builder, auto-save |
| Neon/Postgres   | 2 | **Raised 2→2.5:** primer uso de JSONB para opciones flexibles |
| CI/CD           | 2 | **Raised 2→2.5:** segundo push GitHub exitoso con token |
  • Las 2 más bajas son las que el Design Specs Builder debe ejercitar en el siguiente proyecto.
  • Esto garantiza que el equipo no se especialice solo en lo fácil: las debilidades se convierten en el plan de estudios.

3. El playbook (PLAYBOOK.md)

Los patrones que funcionan se promocionan a recetas reutilizables: componente signal-first, zoneless, wizard multi-paso, status machine, patrón strategy para IA, FTS5, multi-tenant queries, mock repos para tests. Cada patrón incluye código listo para copiar. Un patrón que funciona 3 veces se convierte en estándar; uno que falla, se documenta como anti-patrón.

4. Incidentes y propuestas de proceso

  • incidents/YYYY-MM-DD.md — cuando algo falla de forma sistémica (p.ej. GitHub push fallando 23 días seguidos por token vacío), se escribe un informe: resumen, entorno, métodos intentados, scope, fix sugerido y workaround.
  • PROCESS_PROPOSALS.md — mejoras de proceso con impacto cuantificado (p.ej. “añadir pre-flight check de CI/CD ahorraría 5-10 min por run; en 19 runs son 95-190 min acumulados — un proyecto entero”).

Ejemplo real de aprendizaje en acción

El 2026-06-07 el push a GitHub falló por 23ª vez consecutiva (token vacío en el entorno cron). Se documentó como incidente, se propuso el fix, y el 2026-07-08 —después de arreglar el entorno con export-cron-env.shel push funcionó por primera vez en 24 intentos. Desde entonces, cada proyecto full-stack tiene repo público en GitHub, y el QA verifica los 3 enlaces del portafolio con curl antes de cerrar el despliegue. El fallo crónico se convirtió en estándar de calidad.

Otro ejemplo: el bug del interceptor *** ${token} se descubrió un día (compila sin error pero rompe auth en runtime). Ahora cada QA pasa un grep obligatorio de *** en todo el proyecto (TS, MJS, JS), no solo en el interceptor — porque se demostró que aparece también en scripts de smoke-test. Un descubrimiento de un proyecto protege a todos los siguientes.


El cron de la reunión diaria (19:00)

daily-cross-profile-summary — “la reunión diaria del equipo”.

Además del pipeline full-stack, tengo otros perfiles trabajando en paralelo (cada uno con su gateway, sus skills y sus crons):

PerfilEspecialidad
defaultFull-stack (Angular, NestJS, DevOps, Caddy, VPS)
cpp-developerC++ moderno (C++23, header-only)
ml-learnerMachine Learning (scikit-learn, Keras, CNNs)
scriptable-devWidgets iOS Scriptable
tester-stackQA/testing (Playwright, Vitest)
unreal-mentorUnreal Engine (C++, Blueprints)
ux-ui-designerUX/UI (glassmorphism, animaciones)

Sin la reunión diaria, los perfiles que no forman parte del proyecto diario full stack serían agentes aislados que no saben nada los unos de los otros. El cron de las 19:00 los convierte en un equipo coordinado.

Cómo funciona

  1. Un script recolector (daily-profile-summary.py) escanea la base de datos de sesiones de cada perfil + los repos git de cada uno, y produce un JSON estructurado: sesiones por perfil, commits del día (con hash corto de 7 dígitos como prueba), actividad sí/no, y resumen por perfil.
  2. El agente coordinador procesa ese JSON y genera el RESUMEN CRUZADO: cada perfil activo le cuenta a cada otro perfil activo lo más útil que hizo hoy para él. El perfil default habla con todos (activos e inactivos); los inactivos solo reciben, no emiten. Típicamente ~25 pares de mensajes de 1–3 líneas, concretos y dirigidos.
  3. Persistencia: el informe se guarda en /opt/data/daily-reports/YYYY-MM-DD.md y se actualiza la MEMORY.md de cada perfil activo con la entrada 📅 YYYY-MM-DD daily cross-profile: — así el conocimiento del día sobrevive en la memoria a largo plazo de cada agente.
  4. Entrega: el resumen se publica en Slack con el archivo adjunto (línea MEDIA:).

Ejemplo real (viernes 31 de julio de 2026)

📋 RESUMEN CRUZADO — viernes, 31 de julio de 2026
📊 Resumen: 88 sesiones, 13 commits, 5 perfiles activos — Quill completado de
   punta a punta (build → QA → deploy → capturas reales → diseño aprobado)

🔹 default → cpp-developer:
  Pipeline completo de Quill (Angular 22 + NestJS 11) hoy... Su backend NestJS
  queda disponible como API REST para consumir desde CLIs C++...
🔹 scriptable-dev → default:
  Creé midnight-skyline-widget.js — 17º script en scriptable-widgets,
  viernes → widget creativo...
🔹 unreal-mentor → ux-ui-designer:
  ✅ Diseño definitivo de Quill APROBADO por Cristian (isFinalDesign.true)...
🔹 cpp-developer → default:
  Gateway vigilado todo el día... ⚠️ ventana de incidencias 05:14–07:19...

🎯 Recordatorios para mañana (sábado, 1 agosto):
- default (02:30): Design Specs Builder
- default (03:30): Daily Builder — Angular 22 + NestJS 11 + Neon PostgreSQL
- cpp-developer (05:00): Sábado → proyecto C++ libre; revisar logs del gateway
- tester-stack (07:00): QA del día
- ux-ui-designer (12:00): ⚠️ REVISAR daily-landing-impeccable — hoy corrió vacío

Fíjate en lo que hace esto: un día cualquiera, el perfil de C++ se entera de que el backend de Quill puede servirle de API REST; el de diseño sabe que el tema Inkwell es la referencia visual del día; el de testing sabe qué QA le toca mañana; y todos se enteran de la incidencia del gateway. Es literalmente una reunión de equipo asíncrona, con acta escrita y memoria a largo plazo.

El valor añadido: detección temprana de anomalías (el cron de diseño que corrió vacío ayer se señala “⚠️ REVISAR”), y conocimiento cruzado que ningún perfil podría obtener por sí solo.


El ecosistema completo alrededor del pipeline

El pipeline full-stack no está solo — comparte el día con otros crons de otros perfiles:

02:30  design-specs-builder    (default)     Specs del proyecto full-stack
03:30  hermes-daily-builder    (default)     Build Angular + NestJS
05:00  cpp-daily-project       (cpp)         Proyecto C++23 + portafolio
07:00  qa-tester-deployer      (default)     QA + deploy + portafolio (3 idiomas)
09:00  ml-daily-project        (ml)          Proyecto ML + portafolio
11:00  portfolio-daily-capture (default)     Screenshots reales de producción
12:00  daily-landing           (ux-ui)       Refinamientos de landing
19:00  daily-cross-profile     (default)     LA REUNIÓN DIARIA (resumen cruzado)
22/23  resumen-diario          (default)     Resumen diario + Excel de proyectos

Todos convergen en el mismo portafolio: los proyectos full-stack tienen su ficha en 3 idiomas con screenshots reales capturados de producción (no mockups), los C++ con captura de terminal, los ML con sus gráficas. Y todo queda registrado en el Excel proyectos_completo.xlsx como inventario histórico.


Resultados y números reales

  • 50+ proyectos full-stack construidos desde las specs (el builder lleva 54 runs completados).
  • 21 dominios distintos hasta CardClash — rotación real, sin repetirse.
  • 100% builds verificados: cada proyecto pasa ng build + nest build + tests antes de desplegarse.
  • Todos desplegados en subdominios públicos .proyectos.cristiancode.dev con verificación de enlaces HTTP 200.
  • Cada proyecto documentado con 7-8 archivos + entrada de portafolio en es/en/pt + fila en el Excel.
  • Un diario de aprendizaje de 511+ líneas que registra outcome, nota, lecciones y dificultad siguiente de cada proyecto.
  • ~30 pitfalls documentados en el skill de QA — cada uno descubierto en un proyecto real y convertido en protección para los siguientes.
  • Reunión diaria real: ~88 sesiones y ~13 commits cruzados por día entre 10 perfiles, con acta escrita en daily-reports/.

Este documento describe la infraestructura real que ejecuta los proyectos de cristiancode.dev/hermes. Los horarios, rutas, markers y ejemplos son datos verificados del sistema — no una descripción de intenciones.