
Un arnés determinista y manual para agentes ofensivos autónomos basados en LLM, que impone autorización, alcance y compuertas de evidencia para garantizar pruebas de penetración reproducibles y honestas.
Un arnés determinista para agentes ofensivos autónomos. El modelo sigue siendo probabilístico. La aplicación anfitriona es dueña de la autorización, las acciones permitidas, los registros de evidencia y la aceptación. Reejecutar entradas congeladas y la política puede reproducir esas decisiones de control; no hace que un objetivo vivo o una respuesta del modelo sean repetibles.
python3 -m pip install -r requirements.txt
python3 -m harness.demo --out /tmp/harness-report.json
diff -u harness/report.json /tmp/harness-report.json
python3 -m pytest tests/test_harness.py
Esta versión está verificada en CPython 3.14. Las versiones anteriores de Python no forman parte de la evidencia de la versión; si usas una, ejecuta la secuencia completa de compuertas que aparece abajo antes de confiar en el resultado.
Construye por fases: Acota el límite de efectos secundarios y el orden de las etapas; Describe el objetivo mediante hechos medidos y catálogos; Prueba las afirmaciones mediante capturas y predicados de política independientes; Controla y rinde cuentas de la autorización, las compuertas, la finalización y el trabajo omitido. El orden de desarrollo no es el orden de ejecución: la autorización y la compuerta preceden al despacho.
El laboratorio público no hace ninguna solicitud de red y no llama a ningún modelo. Su predicado de prueba es sintético, su anfitrión y sus adaptadores son de confianza, y cada hallazgo está marcado como pendiente de revisión humana. El laboratorio no implementa el flujo de aceptación de una persona ni de firma de informes. Una cita textual establece integridad de citación, no explotabilidad. Menos llamadas al modelo y menos retrabajo son objetivos de diseño, no ahorros medidos por el corpus.
Los capítulos siguientes describen la implementación anterior de core/ y walkthrough/ y sus defectos publicados. Su verificador ausente que llama al modelo sigue ausente de esa ruta histórica. El nuevo paquete harness/ es una referencia de control separada sin conexión; no repara retroactivamente el corpus ni los módulos históricos. Lee el límite y las correcciones del capítulo 07 antes de copiar un componente histórico.
Apunta un modelo capaz a un anfitrión, entrégale una caja de herramientas y dile que ejecute una prueba de penetración, y hará algo sensato. Ejecútalo de nuevo mañana y hará algo sensato distinto, y ninguna de las dos ejecuciones puede decirte por qué omitió lo que la otra detectó. Este manual aboga por un trabajo más pequeño para el modelo: dale cada decisión a la capa más barata que pueda tomarla correctamente, y gasta capacidad del modelo solo donde la respuesta genuinamente no se puede derivar de lo que ya tienes. Ese ordenamiento, desde las decisiones que puede tomar una tabla hasta las pocas que necesitan un modelo, es el gradiente del título del capítulo 00. Los capítulos siguen a un agente ofensivo de seguridad en funcionamiento y a los controles que sus fallos exigieron.
El sistema histórico tiene dos rutas de orquestación. En la ruta impulsada por el servidor, un orquestador mantiene su propia lista de fases y ofrece al modelo solo las herramientas que esa fase permite. En la ruta impulsada por el agente, un modelo orquestador planifica la ejecución y llama a las herramientas él mismo, con las capas inferiores construidas pero no siempre consultadas. Una ruta de escritura compartida hace que las acciones registradas y los hallazgos sean revisables, pero un shell disponible puede omitirla. Un endpoint inventado merece una respuesta capturada, no un veredicto automático de vulnerabilidad. El gobernador de severidad no puede elevar; la compuerta de elevación histórica del verificador separado comprueba una cita pero no establece explotabilidad. La autorización se solicita en el límite de la herramienta en lugar de en cada solicitud saliente. Los capítulos de informes distinguen un escaneo que no encontró nada de un escaneo rechazado en la puerta. Esas diferencias entre intención y aplicación forman parte del estudio de caso, no propiedades para copiar en un nuevo arnés.
Cada capítulo después del primero termina admitiendo lo que su control todavía hace mal, y las secciones de honestidad llevan las mediciones que lo demuestran. Lee primero las secciones de honestidad si estás decidiendo si confiar en el resto: el corpus es el historial operativo de un sistema, la única ejecución de objetivo público seleccionada es un agregado registrado por el autor con dos ejecuciones excluidas publicadas a su lado, y el estudio de ablación que mostraría cuánto contribuyen realmente las capas deterministas no se ha ejecutado. El repositorio no incluye los hallazgos brutos de la ejecución seleccionada, la verdad fundamental ni el comparador, por lo que la precisión registrada no es reproducible de forma independiente aquí. El argumento de diseño se argumenta, no se mide, y el capítulo 05 lo dice con esas palabras.
Canónicas en el capítulo 00, copiadas aquí. Cada una es intención de diseño, y el capítulo nombrado al final de cada ley es donde se evalúa este sistema contra ella: qué partes se sostienen por construcción, cuáles se sostienen solo en una de las dos rutas de orquestación, cuáles se sostienen por el buen comportamiento del orquestador y cuáles aún no se sostienen.
El modelo propone; el código determinista dispone. Dale al modelo una interfaz de propuesta, no acceso directo al objetivo, almacenamiento bruto ni la última palabra sobre la severidad. El código determinista valida, ejecuta y registra el trabajo admitido. El sistema histórico no aplica ese límite en todas partes: ambos orquestadores pueden alcanzar un shell, y su ruta de escritura lleva un subcomando que almacena un hallazgo sin una ejecución. Un endpoint inventado podría devolver 404, una página de inicio de sesión o un shell de aplicación; registra la respuesta y juzga la afirmación por separado. Un escritor compartido no es una sandbox. Capítulos 01 y 02.
Las afirmaciones sobre el pasado deben citar. Las propuestas sobre el futuro deben ejecutarse. Son tipos distintos de declaración y necesitan compuertas distintas. Una afirmación sobre algo ya observado debe citar su propia captura; una cita coincidente establece integridad de citación, no que la conclusión sea verdadera. La compuerta histórica tiene fugas: conserva un elemento por lote incluso si ninguno pasa, y en una ruta de orquestación una confianza proporcionada por el llamador puede sustituir a la comprobación. Una prueba propuesta no puede validarse citando una observación que no ha hecho. Solo puede ejecutarse después de que la autorización, el alcance, la compuerta y las comprobaciones de presupuesto lo permitan, y su resultado aún necesita interpretación. La ley no es permiso para ejecutar cada propuesta. Capítulo 02.
La severidad cae por defecto y solo sube contra prueba. El gobernador determinista puede bajar una severidad o marcar un hallazgo como falso positivo, y no puede elevarla. Eso limita su autoridad; no hace que sus conclusiones sean correctas. El subinforme puede ocultar una vulnerabilidad real, por lo que cada regla de bajada necesita pruebas de coincidencia y de contraejemplo y una razón revisable. El endpoint de elevación histórico comprueba una cita textual pero no aplica la puntuación redactada que su contrato solicita. Una cita sola no es prueba de explotabilidad. Vincula la captura al hallazgo, aplica una política de prueba de dominio revisada y conserva un proceso separado de revisión y aprobación humana. Capítulo 03.
El alcance es una función, no una sentencia. La autorización escrita en un prompt compite con cada otra instrucción en la ventana de contexto. Codifica el permiso del operador como una política revisable y aplícala antes de cada acción saliente, con un registro de rechazos. El guardián histórico se queda corto: se solicita en el límite de la herramienta en lugar de en cada solicitud, amplía algunos límites del anfitrión y falla abierto bajo un interruptor de apagado o cuando se construye sin un objetivo. El laboratorio rechaza orígenes no listados antes de su callback de confianza, pero la contención del transporte aún pertenece al adaptador. Una decisión de política es tan correcta como la autorización y el destino que evalúa. Capítulo 04.
Informa lo que no hiciste. Un escaneo que no encontró nada y un escaneo que no pudo alcanzar nada son escaneos distintos, y un informe que los muestra de forma idéntica miente por omisión. La cobertura, el estado de la compuerta y un libro mayor de cada anfitrión omitido con su razón pertenecen al entregable, junto a los hallazgos. Ese es un requisito que el informe histórico no cumplió: solo llegó la cobertura, calculada contra su denominador más débil y bajo una etiqueta que nombraba uno distinto. El laboratorio rinde cuentas de las acciones planificadas de herramienta y URL, el trabajo ejecutado, los errores y las omisiones; ese denominador no mide la cobertura de vulnerabilidades. Capítulo 05.
| Capítulo | Tema |
|---|---|
| Capítulo 00: El gradiente de determinismo (fuente) | Por qué la varianza es un problema de diseño más que un problema de capacidad, las cuatro capas y las cinco leyes |
| Capítulo 01: El procedimiento fijo (fuente) | La máquina de etapas, la puntuación determinista de herramientas, los priors como contadores en un archivo y la proporción de turnos que no dice lo que querrías |
| Capítulo 02: La cintura estrecha (fuente) | Un escritor por efecto secundario, la validación de esquemas y el bucle de reparación, y por qué las afirmaciones y las propuestas necesitan compuertas distintas |
| Capítulo 03: Confianza asimétrica (fuente) | Un gobernador que no puede escalar, un verificador que solo puede elevar contra prueba y las cadenas de ataque que no pueden probarse |
| Capítulo 04: El alcance como código (fuente) | La autorización como función, el libro mayor de omisiones, el suelo que ninguna función debería decidir y la brecha de alcance registrada en la ejecución seleccionada |
| Capítulo 05: Lo que el escaneo no pudo alcanzar (fuente) |
El código histórico bajo core/ está aquí para leerse, ejecutarse y discutirse. Es de sala limpia y deliberadamente no funcional como probador en vivo: la elaboración de perfiles, la puntuación de relevancia, la programación y la validación de llamadas de herramienta son reales y ejecutables, y todo lo que pondría un paquete en el cable está retenido. Ejecuta ls core/*.py para ver qué se incluye en lugar de confiar en una cifra escrita aquí, que es el tipo de afirmación que se vuelve obsoleta en el momento en que se añade un módulo. Los controles en los que se apoyan los capítulos posteriores están entre ellos: la ruta de escritura es core/store_protocol.py, el gobernador de severidad core/severity_governor.py, el guardián de alcance core/scope_guard.py, la comprobación de compuerta core/gate_check.py y la máquina de etapas walkthrough/run.py. El verificador histórico que llama al modelo está retenido. El capítulo 06 lo especifica; el capítulo 07 incluye un guardián de evidencia determinista separado, no ese verificador ni un flujo de aceptación humana. Mantén sus trabajos separados: el crítico de fundamentación comprueba la contención de citas, el gobernador limita la severidad, y una ruta de elevación debe satisfacer una política de prueba revisada de forma independiente. Ninguno de ellos reemplaza la revisión y aprobación humana.
walkthrough/ impulsa esa máquina de etapas sobre fixtures confirmados y escribe los artefactos que los capítulos citan en walkthrough/artifacts/. Regenera con python3 -m walkthrough.run, que acepta un directorio --out si prefieres no tocar las copias confirmadas, y tests/test_walkthrough_is_in_sync.py compara una ejecución fresca en memoria contra esas copias byte por byte, de modo que un fixture editado sin una reejecución se enrojece en lugar de publicarse. Lo que esa compuerta no detecta es un artefacto que está mal en ambos lugares, y su propio docstring lo dice.
Cada cifra en cada capítulo se resuelve a una clave en data/stats.json, o lleva una anotación que nombra qué es la cifra y por qué no es una medición tomada de un objetivo. En los capítulos 00 a 05 y este README, trece anotaciones nombran una constante o una propiedad del código, treinta y cinco cubren una cantidad escrita que la comprobación de dígitos no puede leer, cinco nombran un código de estado HTTP y una nombra una comparación entre dos instantáneas publicadas propias de este repositorio. El archivo de estadísticas es una instantánea congelada con una ventana publicada, no una consulta en vivo, y el capítulo 05 explica por qué reejecutar el pipeline no la reproduciría.
El capítulo 05 informa el F1 del sistema contra una aplicación pública deliberadamente vulnerable y lo coloca junto a una puntuación de escaneo pasivo de OWASP ZAP. Este repositorio prueba la aritmética y mantiene los cuatro archivos de puntuaciones agregadas sincronizados con data/stats.json; no contiene los hallazgos brutos, las entradas de verdad fundamental, el comparador, los identificadores de objetivo ni los identificadores de ejecución necesarios para probar que las dos herramientas se evaluaron en un cara a cara controlado. Trata el par como puntos de datos históricos registrados por el autor, no como un benchmark justo. El tamaño de la muestra, la dispersión que por tanto no informa y las ejecuciones excluidas con la razón de cada exclusión están todos en ese capítulo.
Una copia generada de los capítulos, con cada cifra resuelta a su valor en su lugar y cada cita de código convertida en un enlace a core/, vive en el árbol renderizado para lectura en GitHub; la produce scripts/render.py y se mantiene en sincronía con la fuente mediante tests/test_rendered_is_in_sync.py.
Si vas a publicar el repositorio, sigue PUBLICATION.md. Publica una instantánea sin historial en un repositorio público nuevo; no cambies la visibilidad del repositorio de desarrollo ni asumas que un árbol de trabajo limpio ha limpiado su historial de Git alcanzable. El pre-commit obligatorio scripts/publication_gate.sh rechaza la publicación a menos que la denylist privada se haya fusionado realmente, la identidad pública del autor de Git coincida con el valor aprobado y el repositorio de preparación no tenga refs, objetos ni reflogs previos.
scripts/audit.sh barre el repositorio en busca de identificadores, scripts/prose_check.sh y scripts/verify_claims.sh barren la prosa, tests/test_gates.sh planta violaciones contra ellos para probar que siguen disparándose, y la suite de pruebas mantiene la implementación de referencia contra lo que los capítulos dicen de ella. Un capítulo no está terminado hasta que cada una de estas pasa:
python3 -m pip install -r requirements.txt
# pytest, y nada más: cada módulo bajo
# core/ es solo biblioteca estándar
export HANDBOOK_ROOT=.
bash scripts/audit.sh . # siempre los patrones publicados; la denylist de
# empleador, cliente y anfitrión solo donde existe,
# y ese archivo es privado, así que ningún clon lo
# lleva. Qué mitad se ejecutó está en la línea
# "sanitization scope:" que esto imprime y no en el
# estado de salida, así que lee la línea
./scripts/prose_check.sh handbook # indicios mecánicos de IA
./scripts/verify_claims.sh handbook # citas, números sin citar, referencias cruzadas,
# anclas de afirmaciones, atribución de fuentes
./scripts/prose_check.sh README.md # ambas compuertas toman un objetivo y usan handbook/
./scripts/verify_claims.sh README.md # por defecto, así que este archivo debe nombrarse
# para ser comprobado
./tests/test_gates.sh # las compuertas contra violaciones plantadas, el
# árbol, el README y las afirmaciones de los
# capítulos; la prosa de los capítulos está cubierta
# por las compuertas de prosa y afirmaciones
# dirigidas a handbook arriba, y no por este barrido
python3 -m pytest tests/ # toda la suite, e imprime su propio recuento
# en lugar de tener uno escrito aquí. Cada línea
# de arriba ejecuta los scripts de compuerta y los
# archivos pytest que esos conectan, que son los
# que tratan sobre este documento; las pruebas de
# los controles sobre los que tratan las cinco leyes
# -- el gobernador de severidad, el guardián de
# alcance, la comprobación de compuerta, la ruta de
# escritura compartida, el crítico de fundamentación
# -- se alcanzan con esta línea y con ninguna de las
# anteriores. Una ruptura en uno de ellos enrojece
# las líneas anteriores solo donde también mueve
# los artefactos confirmados de walkthrough
tests/test_chapter_claims.py, dentro de esa suite, es el que vale la pena robar. Contiene aserciones contra la implementación de referencia y las estadísticas publicadas, y cada una está anclada a la oración textual que respalda, de modo que una edición que cambie un hecho falle una prueba en lugar de publicarse silenciosamente.
Theodoros Moutesidis.
| La alcanzabilidad como valor registrado, los denominadores de cobertura, la consolidación, los parciales honestos y cómo evaluar tu propio sistema |
| Capítulo 06: Construye el tuyo (fuente) | El manual ordenado: cada paso declara el invariante que protege y nombra el archivo que lo aplica, una prueba y el artefacto confirmado dondequiera que el árbol público los lleve |
| Capítulo 07: El laboratorio del arnés (fuente) | La referencia sin conexión recomendada: aplica el límite, inspecciona un informe completo y prueba lo que debe rechazarse |
| Apéndice A: El contrato del orquestador (fuente) | El instrumento que se entrega al modelo, generalizado a partir del original privado |
| Apéndice B: Los esquemas (fuente) | Las formas de llamada de herramienta, hallazgo y registro de gobernanza, con lo que cada una garantiza y lo que no |
| Apéndice C: El museo de fallos (fuente) | Falsos positivos reales con su causa raíz y la regla que elimina cada uno, y cuáles de ellos puede fijar este repositorio |