
Director–Implementer Loop R4.4-AG: una CI por HEAD y Playwright sin fricción
La Revisión 4 fijó quién decide. La Revisión 4.1 dio hogar al handoff y gate al humano. R4.3-AG afinó la operación agent-first: contexto fresco, CI despachada sin espera, validación visual canónica y cierre verificable hasta producción.
R4.4-AG no reescribe ese loop. Elimina dos formas de orquestación accidental que el dogfooding real dejó a la vista:
- volver a lanzar feature CI sobre el mismo HEAD sólo porque una PR pasa de Draft a Ready;
- obligar a cada Implementer a redescubrir el networking Docker ↔ WSL para validar una página.
La forma corta sigue siendo la misma:
Implementer:
builds → validates → launches → shows → stops
Human:
reviews → accepts
Director:
audits → interprets → merges → verifies → closes
La evolución está en cómo se ejecuta, no en quién decide. Menos orquestación accidental; los mismos gates.
De dónde venimos
La genealogía deliberada es esta:
R4
ownership
↓
R4.1
GitHub handoff + localhost + human gate
↓
R4.2
rejected automatic wake-up experiment
↓
R4.3-AG
fresh context + CI dispatched + rendered validation + full closure
↓
R4.4-AG
one feature CI per HEAD + canonical Playwright facade
R4.2 permanece como experimento rechazado. Automatizar el gesto de «despertar al Director» añadió opacidad y agentes esperando. R4.4 avanza por el otro camino: quitar fricción que no aporta gate nuevo.
Primer hallazgo: CI redundante al pasar a Ready
R4.3 había resuelto correctamente una ambigüedad importante:
expected CI
≠ CI DISPATCHED
≠ observed CI
≠ interpreted CI
El Implementer confirma el dispatch una vez y se detiene. El Director observa e interpreta. Eso funcionaba.
Pero el workflow del adapter todavía reaccionaba al evento ready_for_review.
Durante dogfooding real la secuencia fue esta:
- el HEAD de feature ya había sido validado;
- el humano aceptaba localhost;
- el Director pasaba la PR de Draft a Ready;
- la plataforma lanzaba otra feature CI sobre exactamente el mismo SHA.
La evidencia histórica fue una ejecución redundante —en aquel momento, la #363— sobre un commit que no había cambiado. Cambiar el estado administrativo de una PR no cambia el código que estamos validando.
El principio quedó claro:
same HEAD
+ already green CI
+ no new commit
= reuse evidence
No ejecutar otra feature CI sólo porque Draft cambie a Ready. Ready debe significar aceptación humana y continuidad del Director, no «vuelve a comprobar el mismo código».
Contrato R4.4: una feature CI por HEAD
La corrección que consolidó la versión estable redujo los triggers de feature a eventos que pueden justificar una validación nueva del HEAD:
opened
synchronize
reopened
ready_for_review deja de ser trigger de CI.
El flujo conceptual queda así:
feature HEAD A
│
└── CI A ── green
│
human accepts
│
Draft → Ready
│
└── NO CI
│
expected-head merge
│
main HEAD M
│
└── CI M
La CI de main no es duplicada. Valida otro commit y otro estado del sistema: el árbol ya mergeado, con su post-merge y su camino a despliegue. Reutilizar la feature CI verde del HEAD exacto no elimina la CI de main; elimina la repetición inútil sobre el mismo SHA.
Prueba final real
El último dogfood antes de promover R4.4 cerró el contrato con un caso concreto:
PR de promoción del facade / covers
feature HEAD b2828ec…
feature CI #370
Secuencia verificada:
HEAD b2828ec…
→ #370
→ green
→ Draft → Ready
→ no nueva CI feature
→ expected-head merge
→ nuevo commit en main
→ #371
→ green
→ deployments verdes
Ready dejó de significar «vuelve a comprobar el mismo código». Volvió a significar únicamente:
el gate humano ha sido aceptado y el Director puede continuar.
Esa es la semántica que R4.4 quiere conservar.
Segundo hallazgo: Playwright funcionaba, pero filtraba infraestructura
playwright-docker ya era un runtime válido. El problema no era Playwright.
El problema era que cada implementación acababa conociendo detalles como:
WSL IP
Docker bridge
host.docker.internal
--add-host
bind address
container → host networking
effective base URL
cleanup
Ese conocimiento reaparecía en handoffs y sesiones del Implementer. No aportaba un gate nuevo. Era fricción operacional accidental: el agente aprendía topología de red en lugar de validar la superficie del producto.
El facade canónico
R4.4 separa tres capas con responsabilidades distintas:
playwright-ui-validation
↓
validation contract
devx playwright
↓
operational facade
playwright-docker
↓
browser runtime
playwright-ui-validation
Define qué debe validar el agente: páginas, interacciones, responsive, consola, requests, screenshots o evidencia razonable, y ausencia de errores relevantes.
devx playwright
Define cómo alcanzar el runtime desde el entorno real. Absorbe bridge efímero cuando hace falta, host aliasing, traducción de URL, PLAYWRIGHT_BASE_URL, preparación de Docker y cleanup.
playwright-docker
Sigue siendo la pieza de bajo nivel que ejecuta el navegador de forma reproducible.
No se sustituyen entre sí. Un HO de producto no debería reinventar ninguna de las tres.
Qué desaparece del HO normal
Un handoff R4.4 ya no debería enseñar al Implementer procedimientos manuales como:
descubre la IP de WSL
cambia el bind
crea un --add-host
prueba host.docker.internal
recalcula la URL visible desde Docker
El contrato normal pasa a ser:
localhost está disponible
↓
devx playwright
↓
effective runtime URL
↓
browser validation
La señal fuerte de aceptación del facade es:
FACADE_ACCEPTANCE: PASS
Significa que la validación se realizó sin workaround manual de networking. Si el agente tuvo que inventar IPs o flags ad-hoc, el facade no ha cumplido su promesa aunque la página acabe validándose.
Dogfood real del facade
El caso Books Explorer / validación de carátulas lo demostró en vivo.
El humano seguía viendo la URL estable:
http://127.0.0.1:8000
Mientras el facade podía proporcionar automáticamente otra URL efectiva al navegador dentro de Docker. El harness debe consumir PLAYWRIGHT_BASE_URL y no asumir que la URL observada desde el contenedor coincide literalmente con la URL local.
Se validaron superficies reales: listado, filtros, búsqueda, paginación, detalle, carátulas, Private Notes, responsive, consola, page errors y network errors.
El propio dogfood detectó dos supuestos del harness —ignoraba PLAYWRIGHT_BASE_URL y asumía un trailing slash concreto— y permitió corregirlos. Eso es exactamente por qué dogfoodear infraestructura es más útil que diseñarla sólo en abstracto: el contrato se prueba contra el harness que realmente ejecuta el agente.
Al publicar este mismo artículo con R4.4 apareció otro detalle del adapter Astro/Vite: el servidor de desarrollo rechazaba el host hostmachine que el facade usa para alcanzar localhost desde Docker. La corrección no fue inventar networking ad-hoc en el HO; fue permitir ese host en la configuración del servidor para que el facade siga siendo la entrada canónica.
Golden flow R4.4-AG
Director
↓
HO
↓
Implementer pre-flight
↓
implementation
↓
local validation
↓
self-review
↓
commit + push
↓
Draft PR
↓
exact-head Evidence Pack
↓
feature CI dispatched once
↓
rendered validation
playwright-ui-validation
+ devx playwright
↓
localhost human gate
↓
STOP
Human
↓
accepts
Director
↓
audit exact HEAD
↓
reuse existing green feature CI
↓
Ready
└─ no redispatch
↓
expected-head merge
↓
main CI
↓
deployment
↓
production verification
↓
issue close
↓
cleanup
El Implementer sigue deteniéndose después de evidencia, dispatch y localhost. El humano conserva el gate visual. El Director conserva interpretación de CI, Ready, merge, producción y cierre.
Qué R4.4 deliberadamente NO automatiza
R4.4 no introduce:
- Tasks despertando al Director;
- webhooks de wake-up;
- CI watchers;
- Implementer haciendo polling;
- merge autónomo;
- eliminación del gate humano;
- eliminación de localhost;
- generic workflow engine;
- state-machine framework;
- agentes observadores permanentes.
El aprendizaje de R4.2 sigue vigente:
automatizar un gesto no es una mejora si para hacerlo añadimos una nueva capa de orquestación, opacidad o agentes esperando.
R4.4 reduce fricción dentro del recorrido existente. No convierte el loop en una orquestación genérica.
DIL Core frente al adapter de jesuserro.com
DIL Core
Conceptos portables:
- Director;
- Implementer;
- Human;
- exact-head evidence;
- CI ownership;
- human acceptance;
- expected-head merge;
- post-merge verification;
- failure routing;
- STOP boundaries.
Adapter actual
Tecnologías concretas de este proyecto:
- GitHub;
- GitHub Actions;
- Vercel;
- WSL;
- Docker;
- Playwright;
devx;- GitNexus.
Otro proyecto puede conservar el Core y sustituir por completo este adapter. GitHub, Vercel o WSL no son requisitos universales del patrón; son la expresión actual en jesuserro.com.
Cómo se promovió R4.4
No se declaró estable de inmediato.
R4.4 rc1
↓
dogfood
↓
duplicate Ready CI discovered
↓
rc2
↓
trigger corrected
↓
Books Explorer dogfood
↓
Playwright facade dogfood
↓
final Draft → Ready self-test
↓
feature #370 once
↓
main #371
↓
promotion PR
↓
R4.4-AG stable
La idea editorial importante:
una versión del proceso que gobierna las entregas debe demostrar su comportamiento entregando trabajo real.
Los nombres rc1 y rc2 pertenecen a la historia de promoción. La versión pública estable se llama R4.4-AG.
Epílogo: la propia promoción probó failure routing
Durante el post-merge de la promoción, la CI #373 empezó en rojo. canonical-postgres falló al descargar PostgreSQL desde Docker Hub: la conexión con auth.docker.io se reseteó. El fallo no había llegado a Liquibase ni al código del repositorio.
Se clasificó como infraestructura externa. El Director no inventó un cambio de código ni relanzó indiscriminadamente toda la entrega. Hubo un rerun dirigido del job afectado. El segundo intento arrancó PostgreSQL, ejecutó Liquibase y terminó verde. La CI #373 acabó verde.
Eso ilustra dos frases que R4 ya pedía y R4.4 sigue practicando:
red ≠ code defect
y:
observe
→ classify
→ route
→ rerun only when justified
R4.4 terminó dogfoodeándose incluso durante su propia promoción.
R4.4-AG en una frase
R4.3 enseñó a despachar CI sin quedarse esperando. R4.4 enseña a no despacharla otra vez sin motivo y a validar lo renderizado sin convertir cada HO en un tutorial de networking Docker/WSL.
Menos orquestación accidental. Los mismos gates. El mismo ownership.