30 minutos · el estándar completo, más un quiz en vivo al final.
guia-presentador.html — speech completo por slide, para tener en otra pantalla.
| Chat web | App escritorio | Extensión IDE | CLI | |
|---|---|---|---|---|
| Acceso al repo completo | ❌ | ⚠️ parcial | ⚠️ parcial | ✅ |
| CLAUDE.md / jerarquía | ❌ | ⚠️ | ⚠️ | ✅ |
| Hooks | ❌ | ❌ | ❌ | ✅ |
| Correr tests / comandos | ❌ | ⚠️ | ⚠️ | ✅ |
| Skills y plugins | ❌ | ⚠️ | ⚠️ | ✅ |
⚠️ = funciona a medias: ven parte del repo abierto, pero no corren hooks y no aplican toda la jerarquía de CLAUDE.md. No es "anda distinto", es "le faltan piezas del estándar".
El chat es solo para preguntas generales y borradores — nunca para tocar código del repo.
Y la razón de fondo: necesitamos que todos sigamos el mismo set de reglas, para que el desarrollo del equipo cumpla estándares de calidad y sea explicable — que cualquiera pueda entender por qué se hizo algo de una manera y no de otra.
/initGenera el CLAUDE.md del proyecto: convenciones, estructura, comandos de build/test.
$ claude > /init
Ejemplo real — el CLAUDE.md de este mismo proyecto:
# CAPACITACION-VIERNES Deck + quiz en vivo para la charla de estándar de Claude Code. Node nativo (sin dependencias), server HTTP a mano. ## Stack y comandos - Node 22+, gestor de paquetes pnpm (no npm). - pnpm start — levanta server.js (puerto 3000, fallback 3001). - pnpm test — corre node --test sobre test/*.test.js. ## Convenciones - Contenido de usuario en español; código y comandos en inglés. - TDD: tests antes que la implementación. - data/results.json y data/host-key.txt no se versionan.
Reglas para que Claude siga en todas tus sesiones, sin importar el repo: cómo querés que te conteste, tus hábitos de trabajo, qué confirmar antes de actuar.
Información sobre ese repo puntual: stack, comandos, estructura, convenciones. Se commitea — es para todo el equipo, no solo para vos.
(Existe también CLAUDE.local.md, gitignored, para overrides personales de un repo — el equipo no lo usa hoy, así que no es parte del estándar.)
Template base de usuario (sin credenciales):
Contestá siempre en español. Antes de editar un .html, guardá una copia en temp_old/. Registrá el trabajo en un .txt o .md con marcas de tiempo. Al interactuar con una base de datos, confirmá dos veces cualquier acción que no sea de solo lectura. Nunca pongas credenciales en este archivo.
CLAUDE.md es una petición. Un hook es una garantía: corre siempre, pase lo que pase. Click en cada fila para ver el código real.
log_conversation.py — UserPromptSubmit / Stop#!/usr/bin/env python3
"""Append the conversation to a per-project .log in ~/.claude/logs/.
Usage: log_conversation.py [user|stop] (reads hook JSON on stdin)"""
import sys, json, os, re, datetime
def main():
event = sys.argv[1] if len(sys.argv) > 1 else "user"
try:
data = json.load(sys.stdin)
except Exception:
return
cwd = data.get("cwd") or "unknown"
name = re.sub(r"[^A-Za-z0-9]", "_", cwd).strip("_") or "session"
logdir = os.path.join(os.path.expanduser("~"), ".claude", "logs")
os.makedirs(logdir, exist_ok=True)
path = os.path.join(logdir, name + ".log")
ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if event == "user":
text = data.get("prompt", "")
label = "USER"
else:
label = "ASSISTANT"
# ...lee el último mensaje del assistant desde transcript_path...
with open(path, "a", encoding="utf-8") as f:
f.write(f"[{ts}] {label}:\n{text}\n\n")
if __name__ == "__main__":
main()
snapshot_html.py — PreToolUse (Write/Edit)#!/usr/bin/env python3
"""Before an Edit/Write to an existing .html file, copy it into a sibling
temp_old/ folder with a timestamp. Reads PreToolUse hook JSON on stdin.
Never blocks the edit (always exits 0)."""
import sys, json, os, shutil, datetime
def main():
try:
data = json.load(sys.stdin)
except Exception:
return
f = (data.get("tool_input") or {}).get("file_path", "")
if not f or not f.lower().endswith(".html"):
return
if not os.path.isfile(f):
return # new file, nothing to snapshot
d = os.path.dirname(f)
backup_dir = os.path.join(d, "temp_old")
os.makedirs(backup_dir, exist_ok=True)
ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
dest = os.path.join(backup_dir, f"{os.path.basename(f)}.{ts}.bak")
try:
shutil.copy2(f, dest)
except Exception:
pass
if __name__ == "__main__":
main()
sys.exit(0)
/planExplorar → preguntas → plan → aprobar → ejecutar. No cambia ningún archivo hasta que lo aprobás.
Shift+Tab o /plan · obligatorio para cambios en varios archivos, features nuevas o riesgosas.
Ejemplo real — extracto del plan que armó esta misma charla (PLAN.md):
## Implementation steps 1. git init, TODO.md y WORKLOG.md. Copiar este spec a docs/. Commit. 2. Test first (TDD): escribir scoring.test.js y game.test.js, después lib/scoring.js y lib/game.js hasta que pasen. Commit. 3. store.js, sse.js, csv.js, server.js y api.test.js. Commit. 4. data/questions.json y data/roster.json (placeholder). Commit. ...
Un paquete instalable con skills, agentes y comandos adentro.
Ej: claude-mem, superpowers, impeccable
Una habilidad puntual que Claude activa cuando la tarea la necesita.
Ej: find-skills, task-observer, graphify
Conecta Claude con sistemas externos.
Ej: Jira, bases de datos, Google Drive
Memoria persistente entre sesiones.
Brainstorming, planificación y TDD guiados.
Diseño y auditoría de interfaces web.
Seguimiento de tareas en curso.
Buscar e instalar skills de la comunidad.
Cualquier input a un grafo de conocimiento.
Por rol (opcional): Ansible (infra) · docx/pdf/pptx/xlsx (documentos) · /code-review, /security-review, /simplify (todos).
Sirve para hacer QA manual después de un cambio hecho con Claude: un ítem por cada cosa que Claude tocó, para revalidarla vos mismo una por una y no dejar nada sin mirar. Guarda lo tildado en localStorage, así que sobrevive a un reload.
Ideal para frontend (un ítem por pantalla/componente que cambió), pero aplica igual a backend (un ítem por endpoint o caso de uso afectado).
Prompt estándar: "Generá un checklist de QA en HTML para [funcionalidad], que guarde el progreso en localStorage."
Demo en vivo: qa-checklist.html — tildar ítems → recargar → siguen tildados.
Baseline → cambio → correr de nuevo → comparar.
Prompt estándar: "Antes de tocar nada, corré los tests y guardá el resultado como baseline. Hacé el cambio. Corré los tests de nuevo y compará contra el baseline."
Ejemplo real 1 — test_documentacion.py (824-golang-api):
Chequeo funcional/regresión para los endpoints de Documentación. Se loguea como cada usuario real y compara qué ve antes y después del cambio.
python test_documentacion.py --out baseline_run # ...se edita el endpoint... python test_documentacion.py --baseline baseline_run/snapshot.json
El report.html resultante resalta, por usuario, qué se agregó o se sacó, y el delta en la cantidad de resultados — no hay que leer un diff de JSON a mano.
Ejemplo real 2 — comparación "threeway" (COMEX):
Cuando el cambio no es en una API sino en una vista de base de datos con lógica de negocio pesada, comparar a ojo es inviable — son cientos de miles de filas. El script trae, para cada fila, el valor de una misma columna en tres versiones de la vista (la de producción, la anterior, y la que se está por promover), las cruza por sus columnas clave, y arma un reporte HTML interactivo con filtros y presets que muestra solo las filas donde las tres versiones no coinciden — en vez de mirar 600.000 filas iguales para encontrar las 2.000 que cambiaron.
Mismo principio que el checklist de QA: no confiar en "me parece que anda", sino verificar cada diferencia una por una antes de promover el cambio.
Demo en vivo: threeway-demo.html — mismo mecanismo, con datos 100% inventados (el caso real tiene datos de cliente, no se muestra en pantalla).
/init genera el CLAUDE.md del proyecto, se commitea./plan para cambios grandes o riesgosos.test_documentacion.py.Servir software, no solo entregarlo.
Nada de IA en esta parte: qué hace que un cliente quede conforme con lo que le entregamos, y dónde se pierde la calidad en el camino.
La razón principal por la que entrás a la cafetería: el café en sí. Si está malo o no te despierta, falló el beneficio sustancial.
En software: el core del sistema, funcionalidades, pantallas, utilidad.
El empaque, las reglas y el proceso: taza limpia, que acepten tarjeta, que te den el ticket, pedir por app sin hacer fila. No cambia el sabor, cambia cómo lo recibís.
En software: presentación del producto, UI, UX, performance, manuales, videotutoriales, documentación.
El extra inesperado que no estabas pagando: el corazón de espuma, la galletita, el Wi-Fi rápido, los sillones cómodos.
En software: todas las extra features que no espera el usuario. Detalles extra que suman.
Cómo leerlo
Seis etapas entre lo que el cliente espera y lo que el cliente percibe. Entre cada etapa hay un gap: un lugar donde se pierde calidad.
El ciclo vuelve siempre al servicio esperado por el cliente.
Etapa 1
Lo que el usuario tiene en mente.
Etapa 2
Lo que el desarrollador entiende que quiere/piensa el cliente.
Etapa 3
Documentación formal, estandarización de patrones, diseño, etc.
Etapa 4
Ej. Producto / Programa / Web.
Etapa 5
Qué se le logra comunicar con claridad al usuario (qué sabe el cliente sobre el producto): funcionalidades, subfuncionalidades, limitantes, relaciones-ítems “escondidos”, de dónde sale cada dato, cada cuánto se actualiza, etc.
Etapa 6
Producto × Comunicación: del producto formal, el % que el cliente/usuario entiende con claridad.
Y de ahí, de nuevo al servicio esperado por el cliente.
Gap 1 · esperado → entendido
Se cierra iterando lo que quiere/tiene en mente el cliente contra lo que entendemos que quiere. Demos, canvas, maquetas, documentación y diagramas fáciles de entender para lograr “consenso”.
(La doc. de ZYSS de Isa, por ej., no cumple para cerrar este gap, porque es extensa y necesita cráneo.)
Gap 2 · entendido → normas
Lo que ya sabemos que se debe realizar vs. los estándares de desarrollo y diseño.
Gap 3 · normas → resultado
Básicamente QA y tests unitarios / de integración.
Gap 4 · resultado → comunicado
Documentación simplificada: funcionalidades, video tutoriales, limitaciones técnicas, ciclo end to end de cada entidad con sus limitantes e interbloqueos.
+ manual de usuario APB = apto para boludos.
Gap 5 · comunicado → percibido
(UX, UI, diseño) Performance × (Documentación + Producto).
Gap 6 · percibido → esperado
Debería ser inexistente si los gaps anteriores fueron cerrados. Puede haber diferencias que el usuario no anticipó, aunque estas deberían lograr evitarse cerrando el Gap 1.
Se cierra iterando lo que quiere/tiene en mente el cliente contra lo que entendemos que quiere: demos, canvas, maquetas, documentación y diagramas fáciles de entender, hasta lograr “consenso”.
La doc. de ZYSS de Isa, por ej., no cumple para cerrar este gap: es extensa y necesita cráneo.
| Gap | Entre | Cómo se cierra |
|---|---|---|
| 1 | Esperado → entendido | Iterar con demos, maquetas, canvas, diagramas simples → consenso |
| 2 | Entendido → normas | Contrastar contra los estándares de desarrollo y diseño |
| 3 | Normas → resultado | QA y tests unitarios / de integración |
| 4 | Resultado → comunicado | Documentación simplificada, video tutoriales, manual APB |
| 5 | Comunicado → percibido | UX, UI, diseño, performance |
| 6 | Percibido → esperado | No debería existir si se cerraron los anteriores |
GitLab CE no tiene secret push protection nativo (es Premium/Ultimate) — así que lo armamos con hooks propios, en dos capas.
Corre en la máquina de cada uno al hacer git commit. Revisa el diff staged y los archivos .env agregados.
Bloquea el commit si encuentra un patrón de secreto real (no un placeholder).
Corre en GitLab al recibir el push, sin importar si el commit local ya pasó el chequeo.
Es la red de seguridad real: nadie puede saltear el chequeo local editando su propio hook.
Ambos comparten los mismos patrones (secret-patterns.sh): claves privadas, tokens de GitLab (glpat-/glrt-), claves de AWS, tokens de Slack, connection strings de DB con credenciales, y .env con valores reales.
git push -o secret-override="bypass" origin <branch>
El override existe para falsos positivos puntuales, no para usarlo por costumbre. Dos razones:
Es literalmente lo que pasó el lunes-martes con zyss-web-backend: un secreto viejo reapareció por el merge de un clone desactualizado, y arreglarlo bien costó bastante más que haberlo evitado de entrada.
Entrá con tu nombre en /play.html
El presentador maneja el quiz desde /host.html?key=…