¿Qué hace belay?
Alcanzas un objetivo en muchos pasos pequeños. Una verificación puntúa cada paso sin intervención humana.
scripts/belay.py mantiene la puntuación: tú editas, él ejecuta la verificación, confirma una victoria o deshace una pérdida, y escribe el registro. Nunca anotas una puntuación tú mismo, y nunca decides que un paso "básicamente" pasó.
Cada objetivo se convierte en lo mismo: un comando que imprime un número. Más rápido es un tiempo o un conteo. Una auditoría es el número de pruebas fallidas, una por hallazgo. Un port es el número de salidas que coinciden. Una interfaz de usuario es una puntuación de un juez.
Cómo trabajar:
- El usuario inicia una escalada y se va. No te detengas para dar actualizaciones. Ellos leen tres cosas: la ficha, una pregunta que solo ellos pueden responder, y el informe. Pregunta con la herramienta de preguntas del arnés si tiene una.
- El estado vive en disco, no en el chat. La ficha, el registro, tus notas y la última salida de la verificación están bajo
.belay/<name>/. Después de una compactación o un fallo,statuslo devuelve todo en una sola llamada. - Nunca esperes con un bucle de sueño. Ejecuta comandos largos en segundo plano y planifica el siguiente paso mientras se ejecutan.
BELAYabajo es la ruta absoluta descripts/belay.pyjunto a este archivo. Escribe la ruta completa en cada comando. Ejecútalo desde dentro del repositorio objetivo. Las rutas y los comandos que pases son relativas a la raíz del repositorio.- La escalada obtiene su propia rama,
climb/<name>. Un paso deshecho restablece el árbol y elimina los archivos no rastreados que git no ignora. Si alguien más está trabajando en este checkout, escala en un worktree separado. Pasa--herecuando ya estés en una rama hecha para este trabajo.
1. Reanuda antes de empezar
Ejecuta python3 "$BELAY" list. Si existe una escalada para este objetivo, cambia a su rama, ejecuta status <name> y continúa en el paso 4. "Continuar" después de un fallo o una nueva sesión significa esto. No empieces de nuevo.
2. Construye la verificación
La escalada solo es tan buena como su verificación. Una verificación que mide lo incorrecto gasta toda la ejecución mejorando lo incorrecto. Primero consigue una verificación aproximada funcionando y ajústala más tarde con relock.
Pregunta: ¿qué ejecutaría para ver que se cumple el objetivo? Haz que ese comando imprima un número. Usa la forma más sólida que encaje: una coincidencia exacta o conteo de pruebas, luego un conteo del trabajo (consultas, viajes de ida y vuelta, bytes), luego un reloj, y un juez modelo solo cuando nada más que el gusto pueda decidir.
| Objetivo | Puntuación |
|---|---|
| Error o funcionalidad | Pruebas fallidas escritas a partir de la especificación, no de tu arreglo |
| Auditoría, estabilizar, "hacer que X funcione" | Pruebas fallidas, una por hallazgo |
| Velocidad o tamaño | Un conteo del trabajo detrás del tiempo, o el tiempo |
| Port o clon | Salidas que coinciden con la herramienta real |
| Varios objetivos a la vez | Progreso hacia la peor barra |
| Apariencia, sensación, escritura | judge.py con una rúbrica y buenos ejemplos |
Las recetas para cada uno están en references/checks.md. Lee la parte que coincide con tu objetivo antes de escribir la verificación.
Usa lo que tenga el repositorio. --score '<regex>' lee la puntuación de la salida de cualquier ejecutor de pruebas, como --score '(\d+) failed'. Toma la última línea coincidente y suma los números que captura. Una ejecución exitosa sin coincidencia puntúa 0. Sin --score, la última línea de la salida estándar de la verificación debe ser el número desnudo. Repite --check para ejecutar varios comandos a la vez; sus puntuaciones se suman. Añade --repo <path> por cada otro checkout que la escalada edite. Un paso se mantiene o se deshace en todos ellos juntos.
Demuestra la verificación antes de confiar en ella:
- Puede fallar. Rompe el código a propósito y ve cómo la puntuación empeora. Restaura con
git checkout -- <file>. - Puede ver una victoria. Una pequeña mejora real debe mover la puntuación.
- Es estable. Ejecútala 3 veces. Si la puntuación varía sin cambios de código, reemplaza el reloj por un conteo, o usa
--runs 3, un--min-gainpor encima de la deriva (un porcentaje como3%cuando la puntuación se reducirá mucho), y--paired. - No se puede engañar. Varía la entrada en cada ejecución y compara con una referencia. Intenta un truco a mano, como codificar la respuesta, y confirma que la verificación o una guardia lo detecta.
- Es rápida. Pagas el tiempo de verificación en cada paso. Mantén un paso por debajo de 2 minutos: puntúa una muestra o un conteo por paso, y guarda la suite completa o la ejecución cronometrada como guardia o conjunto de validación.
- La barra es alcanzable. Calcula lo mejor que puede hacer el diseño actual. Si la barra está más allá, dilo en la ficha y propón una barra que puedas alcanzar.
Protege todo lo que la puntuación no mide:
- Guardias (
--guard, pasan saliendo con 0). Enumera lo que toca el código que cambiarás: llamadores, otras plataformas, datos guardados, APIs públicas. Cada uno necesita una guardia: las pruebas que pasan hoy, typecheck, lint, la compilación. Cuando la puntuación es un conteo de fallos, mantén esas pruebas que pasan en sus propios archivos como guardia, para que un fallo no pueda pasar como "menos fallos". - Bloqueo (
--lock) la verificación, las pruebas, los fixtures y el conjunto de validación.tryse niega a puntuar mientras un archivo bloqueado difiera. Los archivos nuevos bajo una ruta--lockse convierten en el primer commit en la rama de escalada. Cualquier otro cambio no confirmado detieneinit. - Conjunto de validación (
--holdout), cuando la verificación usa muestras, un benchmark o un juez: casos en los que la escalada nunca entrena, guardados bajo.belay/<name>/holdout/. No los abras de nuevo. Si la puntuación sube y el conjunto de validación no, la escalada está sobreajustando. Detente y dilo.
Auditorías y objetivos abiertos. Enumera lo que cubre el objetivo como una lista de verificación en .belay/<name>/notes.md. Busca errores área por área. Escribe una prueba fallida por hallazgo real, a partir de la especificación o del informe de error. Cuando un paso posterior encuentre un nuevo error, añade su prueba y ejecuta relock --why "encontrado <error>". La puntuación sube por una razón honesta y el registro muestra por qué. Un hallazgo que necesita la decisión del usuario va en las notas y en el informe, no en la puntuación.
3. La ficha, luego init
Envía un mensaje con la ficha y nada más para decidir:
Ficha de escalada:
build-speedObjetivo: compilación en frío 2x más rápida, misma salida
Puntuación Segundos de compilación mediana, menor es mejor: 47.0 ahora, barra 23.5 Verificación ./scripts/bench-build.sh, 3 ejecuciones, emparejadas, ganancia mín. 3%Guardias npm test,npm run typecheckConjunto de validación 3 de las 12 aplicaciones de muestra Bloqueado scripts/bench-build.sh,test/,samples/Límite ninguno (unos 2 min por paso) Necesita tu respuesta: ninguna
Responde go, o cambia una línea.
Llena cada línea con tu mejor elección. Si el usuario dio un objetivo sin barra, propón una que sea ambiciosa y comprobable, como "2x más rápido" o "cada muestra coincide". Espera a "go", que aprueba la ficha, la rama y sus commits. Omite la espera y pon la ficha al principio del informe cuando el usuario ya haya dicho que ejecute sin preguntar, o cuando el objetivo sea pequeño y la barra no esté en duda. Después de eso, no preguntes nada que puedas averiguar o decidir tú mismo.
python3 "$BELAY" init build-speed --goal "compilación en frío 2x más rápida" \
--check ./scripts/bench-build.sh --direction min --target 2x \
--runs 3 --paired --min-gain 3% --guard "npm test" --guard "npm run typecheck" \
--holdout ./scripts/bench-holdout.sh --lock scripts --lock test \
--lock .belay/build-speed/holdout
Una auditoría sobre un backend y un frontend:
python3 "$BELAY" init billing-audit --goal "cada hallazgo de facturación corregido" \
--check "pytest tests/billing -q" --check "cd ../web && npx vitest run billing" \
--score '(\d+) failed' --direction min --target 0 --repo ../web \
--guard "pytest tests/legacy -q" --guard "cd ../web && npx tsc --noEmit" \
--lock tests/billing --lock ../web/src/billing/__tests__
init crea la rama, mide la línea base y se niega a empezar si una guardia ya falla. Arregla lo que advierte antes del primer paso. Establece --max-hours o --max-steps solo cuando el usuario nombre un límite. Sin uno, la escalada se ejecuta hasta que se cumpla la barra o se atasque.
4. Escalar
Cada paso es una idea, un cambio, un try:
- Elige la idea. No reintentes una que el registro ya haya deshecho a menos que puedas decir qué es diferente ahora. Si se usan jueces, lee
.belay/judge-notes.md. - Haz un cambio por una razón y adivina su efecto. Pon la suposición en la idea:
"caché del analizador (espero -10%)". Cuando una suposición está muy lejos, tu modelo del código está equivocado. Perfila antes del siguiente paso. python3 "$BELAY" try "<idea>". Confirma una victoria o restablece el árbol. De cualquier manera, sigue adelante. La salida completa de la verificación del paso está en.belay/<name>/last.txt, y la del mejor paso enbest.txt. Lee esos en lugar de ejecutar la verificación de nuevo.- Mientras se ejecuta una verificación, no edites el árbol. Solo un comando
belay.pyque cambie la escalada se ejecuta a la vez. Si dice que otro sigue ejecutándose, espera. - Cada 5 pasos, actualiza
.belay/<name>/notes.mden unas pocas líneas: qué funciona, qué no, qué probar a continuación. La próxima sesión reanuda a partir de ahí.
Si crees en una idea que la verificación deshizo dos veces, la verificación no puede verla. Haz la verificación más fina y relock. Nunca edites un archivo bloqueado para que un paso pase.
Nunca engañes a la verificación
Cada una de estas aumenta la puntuación y empeora el trabajo. Cada una es una escalada fallida incluso si try la mantiene:
- Hacer casos especiales de las entradas que usa la verificación, o codificar o almacenar en caché las salidas esperadas.
- Saltar, debilitar o eliminar pruebas, o capturar y ocultar errores.
- Hacer que el benchmark haga menos trabajo en lugar de hacer el código más rápido.
- Usar
relockpara eliminar o suavizar un caso difícil para que se cumpla la barra. Relock solo hace la verificación más correcta. Si no se puede alcanzar la barra, informa el mínimo que mediste. - Leer el conjunto de validación.
Una victoria real mejora el mismo código en entradas que la verificación nunca ha visto. Si la única forma de avanzar es una de estas, la verificación está mal. Dilo.
Sigue reevaluando
La puntuación solo representa lo que el usuario quiere. Comprueba que todavía lo hace:
- Cada 10 pasos mantenidos, y en la barra: mira la cosa real tú mismo. Abre la aplicación, lee la salida, ve la captura de pantalla. Ejecuta la suite de pruebas completa y
holdout. Si la puntuación y la cosa real se separaron, arregla la verificación yrelock --why "...". - Algo se rompió que ninguna guardia atrapó: encuentra el paso con
git bisect run <comando fallido>, luego repáralo contry --fix "<qué se rompió>", que mantiene un cambio que sostiene la puntuación. Si la única reparación renuncia a esa ganancia del paso,git revertel paso yrelock --why "paso N revertido: rompió X". Añade la guardia que faltaba. - Antes del informe: revisa
git diff <inicio>..HEADcomo un solo cambio, con ojos nuevos. Busca pruebas eliminadas, errores tragados, una característica desactivada, un valor predeterminado cambiado y cambios de datos o API. Repara contry --fix, luego ejecuta la verificación yholdout --why finaluna vez más para que el informe cite números medidos.
5. Cuando se estanca
try y status imprimen PLATEAU después de 5 pasos sin ganancia. Deja de probar ideas y encuentra el bloqueo. Mide antes de adivinar:
- ¿De dónde viene realmente el tiempo o el conteo de errores? Perfílalo.
- ¿Es la verificación inestable, demasiado gruesa para ver pequeñas ganancias, o ciega al problema?
- ¿Hay una idea más grande que los pequeños pasos no pueden alcanzar?
- ¿Qué herramienta, acceso, datos o computación cambiarían los próximos diez pasos?
Regístralo con python3 "$BELAY" review "<lo que encontraste>", que silencia PLATEAU durante 5 pasos. Arregla lo que puedas: una verificación más rápida, una métrica más fina, un enfoque diferente. Pregunta al usuario solo por lo que solo ellos pueden dar, como acceso o dinero, y solo después de haber agotado todas las demás ideas.
6. Detente e informa
Detente cuando se cumpla alguna de estas condiciones:
tryimprime BARRA ALCANZADA. Ejecuta el conjunto de validación por ti. Una victoria visible con un conjunto de validación plano no es una victoria.statusimplica STUCK: dos revisiones de bloqueo sin ganancia entre ellas.tryse niega con "Presupuesto usado".- El conjunto de validación no coincide con la puntuación.
- El siguiente paso necesita algo que solo el usuario puede dar.
Luego haz la revisión final anterior, elimina .belay/<name>/data/ y envía el informe. Hazlo legible en diez segundos:
Escalada
build-speed: barra alcanzada47.1s → 18.7s, 2.5x más rápido (barra 23.5s, alcanzada en el paso 41)
Conjunto de validación 51.0s → 20.2s, se movió con la puntuación Pasos 19 mantenidos de 52 Seguridad Guardias pasadas en cada paso mantenido. Suite completa y revisión final limpias Rama climb/build-speed, 19 commitsQué funcionó
- Caché de tipos incremental: −12s
Probado y deshecho
- Cambio a swc: rompió 3 guardias
Tu siguiente paso
- Revisar:
git log --oneline 1a2b3c4..climb/build-speed
El titular es uno de: barra alcanzada, atascado, presupuesto agotado, conjunto de validación en desacuerdo, te necesita. Cita números que midió el script, nunca estimaciones. Si cambiaste la verificación o la barra en el camino, dilo en el titular. Mayores victorias primero. Como máximo 3 viñetas por sección. Salta las secciones vacías.
Si el usuario luego quiere más, establece una barra más dura para la misma afirmación con raise 2x --why "..." y sigue escalando. Nunca cambies a un nuevo objetivo.
Subagentes
Si el arnés puede iniciar subagentes, úsalos para lectura paralela durante la configuración y para ojos nuevos en la revisión del bloqueo y la revisión final. Pide conclusiones, no volcados de archivos. Solo tú escribes en el árbol de escalada, porque try lo restablece. Un ayudante lee, o redacta un parche en su propio worktree para que lo apliques y lo pruebes. Sin subagentes, hazlo en línea.
Comandos
| Comando | Hace |
|---|---|
init <name> --goal "..." --check "..." --direction min|max | Línea base, rama, bloqueo. Opciones: --check (repetir), --score '<regex>', --target (número o 2x), --guard (repetir), --lock (repetir), --holdout, --repo (repetir), --runs, --paired, --min-gain, --timeout, --max-hours, --max-steps, --here |
try "<idea>" [--fix] | Puntúa la edición, luego la mantiene o la deshace. --fix mantiene una reparación que sostiene la puntuación |
status [name] | Puntuación, últimos pasos, notas, PLATEAU o STUCK |
relock --why "..." | Acepta una verificación modificada y mide de nuevo |
holdout --why "..." | Ejecuta el conjunto de validación ahora |
review "<encontrado>" | Registra una revisión de bloqueo |
raise <barra> --why "..." | Establece una barra más dura después de alcanzar esta |
budget [--hours N] [--steps N] | Muestra o establece el presupuesto restante |
list | Enumera las escaladas existentes |
notes [name] | Muestra o crea .belay/<name>/notes.md |