Simulación de un comando de Blue Spec
Esta habilidad existe porque simular un comando es engañosamente fácil de hacer mal, de una manera que desperdicia el tiempo y la confianza del usuario. Sesiones dificiles produjeron cuatro reglas no negociables y un método. Síguelas exactamente.
Usa esta habilidad cada vez que el usuario pida "simular", "demostrar", "mostrar en la práctica", "ejecutar" o "ver en acción" cualquier comando /bluespec.* (charter, detect, plan, harden, verify), o para previsualizar cómo se comporta un comando antes de implementarlo.
Antes de empezar (obligatorio)
No comiences una simulación, construyas un escenario ni copies un fixture hasta que ambas cosas estén resueltas, en este orden:
- El usuario debe decirte qué comando de Blue Spec simular. Esto es obligatorio, nunca asumas ni elijas uno. Si el usuario no ha nombrado un comando (
charter,detect,plan,hardenoverify), pregunta cuál antes de hacer cualquier otra cosa. Si nombró más de uno, confirma el orden en que los ejecutarás. - Luego sugiere el fixture, enumerado, y deja que el usuario elija. Una vez que se conoce el comando, lista los fixtures disponibles (de
.claude/skills/simulate/fixtures/) como una lista numerada, cada uno con una descripción de una línea de su escenario, y pide al usuario que elija uno por número. No uses un fixture por defecto en silencio. Si solo existe un fixture, preséntalo igualmente y confírmalo antes de usarlo. Si ninguno se ajusta al comando, dilo y ofrece agregar un nuevo fixture (consulta la sección de fixtures).
Solo después de que el comando esté nombrado y el fixture esté elegido, procedes a las reglas y al método a continuación.
Por qué existe esta habilidad (léelo primero)
Un comando de Blue Spec no es un programa independiente. Es un archivo de instrucciones (spec/commands/bluespec.<phase>.md, andamiado como una habilidad que el agente lee) que le dice a un agente de IA cómo hacer una fase de trabajo de seguridad. "Ejecutar el comando" significa un agente siguiendo esas instrucciones. No hay un binario que emita un resultado determinista independiente del agente. Por lo tanto, una "simulación" es el agente ejecutando los pasos del comando de verdad, contra un escenario real, mientras muestra su trabajo.
El modo de fallo a evitar: narrar lo que imaginas que el comando generaría, formatearlo para que parezca un terminal y presentarlo como si se hubiera ejecutado. Eso es teatro. El usuario no puede distinguir la salida inventada de la salida real, y con razón lo llamará una farsa. Todo lo que sigue está diseñado para hacer que la simulación sea real y verificable por el usuario, no una actuación.
Las cuatro reglas estrictas
Regla 1: Ejecuta el escenario dentro de ./temp
Construye todo lo que la simulación toque (el fixture, los artefactos de .bluespec/memory/ que las fases producen, cualquier entrada) dentro de ./temp en la raíz del repositorio, nunca en /tmp del sistema.
/tmpes invisible para el usuario: no puede abrir esos archivos en su editor, por lo que todo lo que hagas allí se convierte en "confía en mí"../tempestá en su espacio de trabajo, se puede abrir e inspeccionar../tempestá en.gitignore, por lo que la simulación nunca contamina los commits.- Limpia
./tempcuando el usuario haya terminado, o déjalo para que lo inspeccione, pero pregúntalo primero.
Los fixtures: comienza cada simulación desde uno
Los proyectos de muestra neutros se distribuyen junto con esta habilidad, cada uno en su propio directorio bajo .claude/skills/simulate/fixtures/<name>/. Elige el fixture cuyo escenario se ajuste a lo que el comando necesita, o agrega uno nuevo (ver más abajo). Cada fixture es un proyecto pequeño y real que contiene deliberadamente código robusto y frágil, en pares neutrales para que el comando tenga que analizar el código, no leer una etiqueta.
Fixtures disponibles:
image-upload-service: un pequeño servicio HTTP ESM que acepta cargas de imágenes y las sirve de vuelta.template-toolkit: un paquete npm ESM publicable (una biblioteca más un CLItmpl) para renderizar plantillas y analizar texto.
Comienza siempre una simulación copiando un fixture directamente en ./temp. Si ./temp ya existe y no está vacío, límpialo primero, para que cada ejecución comience limpia (reemplaza <name> con el fixture que elegiste):
rm -rf ./temp && mkdir -p ./temp
cp -R .claude/skills/simulate/fixtures/<name>/. ./temp/
Luego construye la cadena sobre ./temp ejecutando las fases previas de verdad (según la Regla 4), para que el artefacto .bluespec/memory/*.md que el comando lee sea producido por su propia fase, no escrito a mano. Ejecuta los pasos del comando contra ./temp, siguiendo su especificación al pie de la letra (según la Regla 3), y muestra la salida de cada paso según la Regla 2.
Para agregar un fixture, crea .claude/skills/simulate/fixtures/<new-name>/ como un proyecto pequeño y real con su propio package.json, mantén código robusto y frágil en pares neutrales, no agregues comentarios o nombres reveladores, y listalo arriba. Agrega uno cuando un comando necesite material que los fixtures actuales no cubran (un lenguaje o stack diferente, manejo de secretos, autenticación, una base de datos, etc.).
Regla 2: Expón las solicitudes y respuestas como bloques de código delimitados DENTRO del mensaje del chat
Esta es la regla que más tiempo costó aprender. Cuando ejecutas una herramienta (Bash, Read), la interfaz del usuario muestra una vista previa truncada de la entrada y salida de esa herramienta. No controlas cuánto se muestra, y generalmente se corta. Si la evidencia que respalda una afirmación vive solo dentro de la salida de una llamada a una herramienta, el usuario no la ve, y cualquier oración que escribas describiéndola se lee como invención.
Por lo tanto:
- Después de ejecutar una herramienta, copia la salida relevante sin procesar en un bloque de código delimitado (triple backtick) en tu mensaje de chat normal. El bloque delimitado se renderiza completamente y de manera idéntica en todas las interfaces. Estas son las "letras amarillas" que el usuario quiere decir: un bloque de código markdown.
- El mensaje del comando y su interacción (lo que
/bluespec.<phase>muestra mientras se ejecuta: el paso a paso, la decisión de alcance, los veredictos) también va en un bloque de código delimitado, con estilo de transcripción. - Nunca escribas "la salida anterior muestra X" señalando una llamada a una herramienta. Señala el bloque delimitado que pegaste, que el usuario puede leer completo.
- Cuando un número o línea en tu transcripción provenga de una ejecución real, debe coincidir con la salida sin procesar que pegaste. Si escribes una línea de transcripción que no está respaldada por una salida sin procesar que pegaste, estás inventando, así que detente.
Un patrón confiable: ejecuta el comando, redirige la salida sin procesar a un archivo en ./temp (por ejemplo ./temp/run.log), luego usa Read en ese archivo (el resultado de Read se te muestra completo) y pega su contenido en un bloque delimitado. El usuario también puede abrir ./temp/run.log para verificar.
Muestra a medida que avanzas, nunca en un lote al final. El disparador es por paso: en el momento en que un paso produce algo que el usuario debería ver (una entrada que leyó, su transcripción, el artefacto que escribió), pégalo en un bloque delimitado en el mismo mensaje, antes del siguiente paso. Si estás a punto de comenzar la siguiente fase o corrección y la salida del paso anterior aún no está en pantalla, detente y pégala primero. Si el usuario tiene que recordarte que muestres la salida de un comando, la regla ya ha fallado.
Regla 3: Tú eres el comando, así que sigue su especificación al pie de la letra
"Ejecutar el comando" significa que tú ejecutas spec/commands/bluespec.<phase>.md paso a paso, no hacer la fase a tu manera y llamarlo el comando.
- Abre esa especificación primero y trátala como la única fuente de verdad. Sigue sus pasos en orden. No ejecutes la fase de memoria o desde el resumen de esta habilidad.
- Realiza cada parada de confirmación que la especificación establezca, de verdad.
hardendebe confirmar antes de editar cualquier código, un escaneodetectcompleto debe ser confirmado porque consume muchos tokens. Presenta lo que la especificación dice presentar, en un bloque de transcripción, y espera. Nunca edites código ni ejecutes un paso bloqueado sin la confirmación primero. - Decide el alcance, veredictos, correcciones, prioridades y hallazgos como los pasos de la especificación los deciden, contra el escenario real. Si no puedes señalar el paso de la especificación que justifica una línea de salida, estás actuando como tú mismo, así que detente y sigue la especificación.
Regla 4: La entrada de cada fase debe provenir de ejecutar la fase anterior, no de ti
La cadena es charter → detect → plan → harden → verify, cada fase lee lo que la anterior escribió. Redactar a mano un artefacto posterior con las respuestas que esperas (un harden.md que registra exactamente lo que quieres que verify confirme o detecte) es el fallo: la fase posterior se prueba entonces contra tu predicción, no contra la realidad, por lo que se pierde lo que tú pasaste por alto.
- Produce cada artefacto anterior ejecutando su fase, bajo su propia especificación, mostrado según la Regla 2. Para demostrar
verify, ejecutadetect(lee el código), luegoplan(leedetect.md), luegoharden(leeplan.md, edita el código). Incluso cuando el usuario comience en medio de la cadena, construye los artefactos faltantes de esta manera, en orden. - Deja que el artefacto diga lo que la ejecución realmente produjo, incluyendo vacíos: un
Partial, unBlocked, un hallazgo que no previste. Un artefacto sospechosamente limpio es la señal de que esta regla se rompió. - Un escenario deliberadamente divergente está bien (
hardenaplica todo, luego el código se revierte para queverifydeba detectar la deriva), pero introduce la divergencia de manera visible (revierte en una llamada a herramienta mostrada, conserva los artefactos reales), nunca escribiendo a mano un registro que la ejecución nunca produjo.
El método, paso a paso
Cada fase lee la anterior y escribe un artefacto. Conoce esta cadena y no la rompas:
| Fase | Lee | Escribe |
|---|---|---|
charter | el contexto del proyecto | .bluespec/memory/charter.md |
detect | el código | .bluespec/memory/detect.md |
plan | solo detect.md, nunca el código | .bluespec/memory/plan.md |
harden | solo plan.md más el charter, y edita el código del usuario | .bluespec/memory/harden.md |
verify | harden.md y el código, confrontando el registro contra la realidad, sin cambiar nada | .bluespec/memory/verify.md |
Luego, para el comando que estás simulando:
- Copia el fixture directamente en
./temp(Regla 1). - Construye la cadena ejecutando cada fase anterior, en orden, contra
./temp(Regla 4). - Ejecuta la fase objetivo bajo su
spec/commands/bluespec.<phase>.md, al pie de la letra (Regla 3). - Muestra cada entrada, transcripción y artefacto en un bloque delimitado a medida que avanzas (Regla 2). Escribe cada artefacto de salida como un archivo real, luego usa
Ready muéstralo.
Verificaciones de honestidad antes de presentar cualquier cosa
- ¿Esto realmente se ejecutó, o estoy escribiendo lo que creo que pasaría?
- ¿Cada línea de la transcripción está respaldada por una salida sin procesar que pegué, o un archivo
./tempque el usuario puede abrir, en lugar de una llamada a herramienta truncada? (Regla 2) - ¿Ya pegué la salida de cada paso hasta ahora, para que el usuario nunca tenga que preguntar? (Regla 2)
- ¿Seguí la especificación de cada fase, incluidas las paradas de confirmación, en lugar de actuar como yo mismo? (Regla 3)
- ¿Cada artefacto anterior provino de ejecutar su fase, no de que yo escribiera a mano el resultado que quería? (Regla 4)
- ¿Está el escenario dentro de
./temp, no oculto en/tmp? (Regla 1)
Si alguna respuesta es no, arréglalo antes de enviar. El usuario preferiría ver una salida real y modesta que una invención pulida.