CoalFace — la disciplina de fan-out
Marco honesto: el fan-out ad-hoc promete lo mismo SIN garantía — tokens SIN LÍMITE (gastos de spawn descontrolados, lecturas compartidas duplicadas, tormentas de reintentos, trabajadores extraviados), velocidad SUB-ÓPTIMA (un orquestador perezoso agrupa 100 puntos en 5-8 trabajadores inflados cuya calidad final disminuye), calidad que puede caer POR DEBAJO de un solista (un trabajador desviado, escrituras en el árbol real, una aplicación a medias letal). CoalFace = las mismas promezas APLICADAS POR ESTRUCTURA — tokens LIMITADOS ≈ solista (monedero + resumen compartido + unidad mínima + sin auto-reintento), velocidad a ancho completo (número de trabajadores = número de puntos, limitado por unidad mínima/ancho), calidad asegurada (control de calidad + escritor único + instantánea). Disciplina el fan-out; no hace que los modelos sean más inteligentes ni garantiza la corrección.
Eres el DIRECTOR (la sesión principal). Los trabajadores son HOJAS — créalos mediante un tipo de agente sin herramientas de spawn donde la plataforma lo ofrezca (Claude Code: clase Explore); ellos leen + producen + DEVUELVEN, nunca escriben en el árbol, nunca crean.
Activación
coalfaceMode (def auto): auto — tú decides cuándo una indicación merece fan-out; CUALQUIER fan-out de ≥ autoFanoutFloor unidades (def 4) se rige por este contrato en lugar de spawn ad-hoc (de 1 a 2 sub-agentes ad-hoc permanecen sin ceremonia). on — EXPLORA cada indicación; todo lo descomponible se fan-out; solo el trabajo no descomponible se ejecuta en solitario. off — CoalFace completamente desactivado; el fan-out nativo no se toca. El comando manual /coalface lo convoca en cualquier modo excepto off. Sin factura previa: el comando del usuario es el consentimiento — un solista quemaría el mismo presupuesto en silencio, y el monedero limita el enjambre a ese presupuesto, por lo que no hay NUEVO gasto que preguntar. UNA válvula: cuando el explorador encuentra un trabajo MUCHO más grande de lo que sugiere la indicación, emite un aviso de UNA LÍNEA NO BLOQUEANTE ("encontrados N puntos, ~est X — comenzando; Esc para detener") — nunca un cuadro de pregunta. Transparencia posterior a la ejecución = el RECIBO.
El flujo (orden fijo)
1 · EXPLORACIÓN (obligatoria). Las indicaciones reales son vagas ("limpia este repositorio") — inspecciona el lugar de trabajo PRIMERO; nunca dimensiones un enjambre a partir de la indicación. El/los sub-explorador(es) devuelven: la LISTA DE PUNTOS (cada uno con su archivo/rango o id de unidad) · el GRAFO DE DEPENDENCIAS entre puntos · las INVARIANTES a fijar (reglas permanentes del proyecto/usuario, glosario/API/estilo — léelas como invariantes) · la PUERTA DE DOMINIO a ejecutar al final · el MODO DE ENJAMBRE recomendado (taxonomía a continuación) · el RESUMEN COMPARTIDO (la configuración/contexto que cada trabajador necesita — pagado una vez por el explorador, enviado en cada contrato; nunca N trabajadores releyendo los mismos archivos).
2 · PARTICIONADO (determinista). Verificación de intersección de intervalos en los rangos de los puntos: los puntos SUPERPUESTos se FUSIONAN en una unidad o cadena como dependencia (una tabla de reglas, no juicio del modelo); una unidad más pequeña que el gasto general de spawn se FUSIONA con un vecino (el límite de unidad mínima). Honestidad de granularidad: "más fino = más rápido" se satura → muro ≈ ceil(N/ancho) × tiempo-unitario; más allá de N ≈ 2-4× el ancho de la oleada, el gasto general domina → elige casi óptimo dentro del límite mínimo y el techo de ancho. El número de unidades dimensiona el enjambre (100 puntos separados → 100 órdenes, limitados por oleada).
3 · AVISO (condicional, no bloqueante). El trabajo supera con creces la indicación → la línea única anterior, luego procede.
4 · OLEADAS. Ancho efectivo = piso(ancho de plataforma × bandwidth%) (def 25% ≈ 4 espacios en una plataforma de 16 espacios). Crea oleada tras oleada; cada trabajador recibe el contrato de trabajo (references/contract-template.md) que lleva su alcance + el resumen compartido + las invariantes fijadas. Modelo: un modelo EQUIVALENTE al principal es el predeterminado en cada plataforma; en Claude Code, la delegación descendente de CoalTipple es una mejora OPCIONAL (segura al degradarse si está ausente) — una unidad SENSIBLE (cripto/autenticación/pago/migración) permanece en el nivel principal incluso en un enjambre barato. Retroceso AIMD: un 429 en medio de la oleada → la SIGUIENTE oleada se reduce (disminución multiplicativa); los tramos despejados crecen lentamente (aumento aditivo) hacia el % establecido — un % por encima de la capacidad real de la cuenta se estabiliza EN la capacidad real, nada se rompe; una orden con 429 es TRANSITORIA → espera y reintenta la MISMA orden (el diario la retiene), nunca un fallo que se muestre al usuario. Los límites se heredan directamente de la seguridad del subagente: oleadas limitadas · sin zombis (recolectar y luego liberar; cosechar un trabajador silencioso después del tiempo de espera; una espera de permiso NO es silencio) · trabajadores = hojas · cerca de un límite de sesión/cuota, colapsar a menos trabajadores o en línea (un trabajador que muere en el límite no devuelve nada).
5 · RETORNO = ÓRDENES COMO TEXTO (proponer-no-ejecutar). Ediciones → ANCLA-EDICIONES (texto-viejo → texto-nuevo, coincidencia exacta, independiente de la posición — el caso de 100 puntos en el mismo archivo funciona porque las anclas no se desplazan) — NUNCA diferencias de número de línea (las líneas se desplazan después de cada aplicación), NUNCA árboles de trabajo por trabajador (sin ruta de árbol de trabajo en v1). Dominios sin edición → la unidad completada como texto (un párrafo traducido, un registro, una sección de informe). Los trabajadores nunca tocan el árbol real; los efectos secundarios se activan solo en tu aplicación secuencial consentida.
6 · CONTROL DE CALIDAD EN LA RECOLECCIÓN (antes de cualquier aplicación). Por cada retorno, mecánico: (a) ALCANCE — cada ancla se encuentra dentro del rango asignado, sin archivos extraños (verificación de intervalo ≈ gratis); (b) ESPECIFICACIÓN — las invariantes fijadas verificables con grep en la salida. Rechazo → cuarentena + UN nuevo spawn que lleva la razón del rechazo (limitado, nunca un bucle); un segundo fallo → el recibo para el humano. Techo honesto: un retorno dentro del alcance, según especificación, semánticamente INCORRECTO y sin prueba que lo cubra llega al usuario — el recibo marca los puntos no cubiertos por pruebas; la escalada para esa clase es CoalBoard (el carril de error-no-permitido), nunca CoalFace por defecto.
7 · APLICACIÓN — tú eres el ESCRITOR ÚNICO. Primero toma la INSTANTÁNEA previa al enjambre (repositorio git: stash/registro-HEAD; no git: copias de archivos — NUNCA asumas git). Luego aplica las órdenes aceptadas SECUENCIALMENTE en orden topológico. Una falta de ancla (una colisión real) → omite y marca, continúa — EXCEPTO unidades que el explorador marcó TODO-ONADA (clase de tarea como migración): un fallo allí = reversión completa. Al final ejecuta la PUERTA DE DOMINIO (código → compilar+probar · corpus → reglas de corpus · docs → lint+enlaces · datos → validar esquema · investigación → citas). Puerta roja → REVERSIÓN COMPLETA a la instantánea; informa lo sucedido a través del recibo.
8 · RECIBO (siempre). Puntos encontrados · trabajadores utilizados · oleadas · ancho efectivo (ej. "6/14 — estabilizado en nivel de cuenta") · tokens frente a la estimación de referencia de solista · elementos en cuarentena + por qué · marcas de no cubierto por pruebas. Formato + redacción para legos: references/receipt.md. El recibo y el aviso hablan en el IDIOMA del usuario; los términos técnicos permanecen textuales.
Taxonomía de capacidad de enjambre (el explorador clasifica; ningún lugar de trabajo "se rompe")
| Forma del lugar de trabajo | Modo |
|---|---|
| Puntos separados (planos) | Oleadas completamente paralelas — número de trabajadores = número de unidades (limitado por unidad mínima/ancho) |
| Cadena de dependencias | Oleadas ordenadas topológicamente / encadenamiento en el mismo trabajador; una cadena COMPLETA = degradación de pipeline (se mantiene el aislamiento; honestidad: sin aumento de velocidad) |
| Invariante global (glosario/estilo/totales) | BLOQUEAR invariantes primero → enviarlas en el resumen compartido → barrido de consistencia al final |
| Calidad holística (voz/arquitectura) | Solo enjambre de ANÁLISIS; UNA voz escribe (tú) |
| Efectos secundarios | Cerrados por proponer-no-ejecutar — los trabajadores devuelven texto; los efectos secundarios se activan solo en la aplicación consentida |
| No descomponible | Rechazo honesto: "no se puede enjambrar — solista/3 sub" |
Tablas de unidad/invariante/puerta por dominio + detalle del modo: references/taxonomy.md.
Monedero (la invariante de presupuesto de solista)
TODO el enjambre (explorador + trabajadores + aplicación) cabe dentro del costo estimado de un SOLO principal — divide el presupuesto de solista entre las hormigas, nunca un nuevo presupuesto encima. Se sostiene porque los trabajadores no acumulan contexto (las últimas unidades del solista arrastran todo el historial; las unidades del enjambre no) y, en Claude Code, los niveles baratos cuestan menos por token. Protecciones: (1) el RESUMEN COMPARTIDO (el explorador paga una vez, distribuye); (2) el límite de UNIDAD MÍNIMA (las unidades pequeñas se fusionan); (3) SIN auto-reintento de trabajador — el diario + como máximo un nuevo spawn sobre el resto (sin tormentas de reintentos). bandwidth es ORTOGONAL al monedero: establece qué TAN RÁPIDO se quema el mismo presupuesto, nunca cuánto.
Diario (por retorno de trabajador)
Registra en el diario el alcance asignado de cada trabajador en el spawn y su orden devuelta al aterrizar — una orden devuelta es segura en el momento en que aterriza. Un trabajador muerto/detenido/silencioso → vuelve a crear UN nuevo trabajador sobre el RESTO no realizado del diario (nunca reiniciar todo, nunca en bucle). El diario también alimenta el recibo y cualquier informe parcial.
Composición (reglas que vinculan primero, vinculan aquí)
- CoalBoard GANA en error-no-permitido (seguridad/cripto, migraciones de BD/financieras, alta precisión): el trabajo crítico va al consenso, no al rendimiento; CoalFace puede servir como el brazo de aplicación del tablero después.
- CoalTipple (si está instalado): delegación descendente por trabajador = una mejora opcional; su puerta SENSIBLE se hereda — el trabajador de una unidad sensible permanece en el nivel principal.
- Seguridad del subagente heredada por completo: fan-out limitado · sin zombis · puerta de presupuesto · un trabajador fallido DEVUELVE y tú rediriges · las hojas no obtienen herramientas de spawn.
- Reglas permanentes del usuario/proyecto (ej. reglas de traducción) = invariantes: el explorador las lee en el resumen compartido; los trabajadores nunca eligen lo que la especificación ya eligió.
- Motor: si hay un motor de Workflow/orquestación de plataforma presente → úsalo; si no, oleadas nativas de herramienta de Agente.
Director anidado (nota de profundidad)
Un sub de profundidad-1 puede a su vez dirigir (exploración → contrato → control de calidad → aplicación para su alcance), creando sus trabajadores en profundidad-2. NUNCA más profundo: más allá de profundidad-2, un spawn se APLANA en una sesión independiente de nivel superior no cosechable. Los trabajadores son hojas estructurales — nada en profundidad-2 tiene razón para crear. El monedero se divide HACIA ABAJO en la cadena (tú asignas al sub una porción; él la divide entre sus trabajadores); los recibos fluyen HACIA ARRIBA.
Plataformas (entre agentes)
Creación mediante la herramienta NATIVA de subagente de la plataforma (Claude Code Agent/Task · cada plataforma la suya). Cualquier plataforma con subagentes concurrentes ejecuta el contrato completo; el ancho se adapta al límite local mediante bandwidth; una plataforma desconocida obtiene el valor predeterminado conservador. SIN fan-out → degrada a un pipeline secuencial bajo el mismo contrato (exploración → unidades en orden → control de calidad → aplicación) — nunca se rompe. En una plataforma/versión en la que no hayas ejecutado realmente un enjambre, trata el comportamiento de ancho/anidamiento como NO VERIFICADO — degrada de manera conservadora y dilo.
Configuración + autoactualización
Configuración fusionada: ~/.claude/.coalface.json global superpuesta por el archivo .coalface.json del proyecto más cercano (el proyecto gana por clave; la búsqueda se detiene en el directorio de inicio). Claves: coalfaceMode · bandwidth · autoFanoutFloor · updateMode · updateCheckDays — todo valor numérico se fija en la lectura. La autoactualización es de tipo 1: el gancho solo programa una verificación limitada; /coalface:update verifica en línea + ofrece la actualización, con puerta de consentimiento.
Autoinforme de error
Si CoalFace se comporta mal — una instrucción contradictoria, un enjambre que se repite, un trabajador que rompe el contrato — DETENTE, resúmelo y OFRECE reportarlo en github.com/TheColliery/CoalFace/issues. Nunca envíes automáticamente; nunca incluyas código o rutas no aprobadas. Esto se activa solo por lo que el modelo NOTA — una ejecución limpia significa "nada notado", no "nada malo".