
git blamemuestra quién, cuándo y qué cambió. whyso muestra por qué.
El problema
Cuando quieres saber por qué una línea de código tiene la forma que tiene, las únicas herramientas a tu disposición son git blame y los mensajes de commit.
$ git blame internal/handler/page.go
a3f1b2c (parkjunwoo 2026-03-08) func CreatePage(c *gin.Context) {
Quién, cuándo y qué se cambió: todo está ahí. Por qué se cambió: eso no aparece.
¿Acaso no basta con escribir el motivo en el mensaje de commit? La realidad es esta:
fix: update handler
refactor: clean up
wip
Escribir buenos mensajes de commit es una cuestión de disciplina. Por mucho que el equipo establezca convenciones, son pocas las personas que, arreglando un bug a las 3 de la madrugada, piensan: “Debería registrar con cuidado el contexto y los motivos de este cambio en el mensaje de commit.”
Sin embargo, en la era del AI coding la situación es distinta. El motivo del cambio ya está registrado.
Los datos de sesión de Claude Code
Claude Code guarda todas las conversaciones como archivos JSONL en ~/.claude/projects/. Cada registro contiene el mensaje del usuario, la respuesta de la IA, las llamadas a tool_use (Write, Edit, Bash) y la cadena de parentUuid que los conecta.
Usuario: "Empieza a implementar el comando whyso validate"
→ IA: Write internal/crosscheck/crosscheck.go
→ IA: Edit internal/crosscheck/crosscheck.go
→ IA: "Paquete crosscheck inicial — validación de coincidencia de operationId SSaC↔OpenAPI"
El motivo por el que se creó un archivo, por qué se modificó, queda en la conversación misma. Es más rico que un mensaje de commit y no requiere esfuerzo consciente para redactarlo. Si hubo conversación, el registro es automático.
whyso analiza estos datos y extrae el historial de cambios por archivo.
La vida entera de un archivo queda a la vista
file: internal/crosscheck/crosscheck.go
created: 2026-03-08T14:23:01Z
history:
- timestamp: 2026-03-08T14:23:01Z
session: 09351222-d7be-41fe-994f-87c2d7067e5d
user_request: "Empieza a implementar el comando whyso validate"
answer: "Paquete crosscheck inicial — validación de coincidencia de operationId SSaC↔OpenAPI"
tool: Write
- timestamp: 2026-03-09T10:15:33Z
session: 4e9b4e5e-3a50-43f2-be6e-e5db228ecc3b
user_request: "Añade validación de si la columna x-sort está en el DDL"
answer: "Añadida validación cruzada de columnas x-sort/x-filter → DDL"
tool: Edit
- timestamp: 2026-03-10T09:41:22Z
session: b2e43b4f-cb21-4286-975d-1eb9de8a16c0
user_request: "Añade también la validación cruzada de la especificación Func"
answer: "Añadida validación cruzada de número/tipo de argumentos @call ↔ Func spec"
tool: Edit
Por qué se creó, con qué petición y cómo fue evolucionando. La vida completa de un archivo queda a la vista.
Por qué es necesario
El hueco en el code review
Al revisar un PR hay momentos en que surge la pregunta: “¿Por qué se hizo este cambio?” Si el mensaje de commit no explica el motivo, hay que preguntarle al autor. Si el autor no lo recuerda, hay que releer el código e inferirlo.
En un entorno de AI coding, la respuesta a esa pregunta está en los datos de sesión. whyso la extrae.
Onboarding
La forma más rápida que tiene un nuevo miembro del equipo de comprender una base de código es entender “por qué el código llegó a ser así”. git log es una lista cronológica de cambios; la documentación es una instantánea del estado actual. El historial por archivo de whyso muestra lo que hay en medio: la cadena de intenciones.
Registro personal
Incluso cuando se trabaja en solitario, llega el momento en que no recuerdas por qué escribiste algo hace tres meses. whyso restaura la conversación que mantuviste con la IA en el pasado. El contexto que no pusiste en el mensaje de commit sigue ahí.
Relación con git blame
whyso no sustituye a git blame. Lo complementa.
| git blame | whyso | |
|---|---|---|
| Quién | O | — |
| Cuándo | O | O |
| Qué se cambió | O (por línea) | O (por tool_use) |
| Por qué se cambió | △ (mensaje de commit) | O (petición del usuario + explicación de la IA) |
| Fuente de datos | historial de git | sesiones de Claude Code |
Si git blame es el “registro oficial” basado en commits, whyso es el “diario de trabajo” basado en conversaciones. El contexto que no cabe en el registro oficial queda en el diario de trabajo.
La estructura en que la IA lee sus propios registros
El caso de uso más interesante de whyso no es que lo lea una persona, sino que lo lea la propia IA.
Claude Code lo olvida todo cuando termina una sesión. Al abrir el mismo proyecto en la siguiente sesión, ya no sabe por qué lo construyó así ayer, qué opciones consideró y descartó, ni en qué contexto hizo el usuario cada petición. Solo puede leer el código e inferir.
Imagina añadir una línea a CLAUDE.md:
Antes de modificar cualquier archivo, ejecuta `whyso history <file>`. Si hay historial, léelo antes de editar.
Lo que cambia con esa sola línea:
Sabe qué cambios no debe revertir
Al leer un archivo que va a modificar, encuentra un código que parece extraño. Viéndolo en su estado actual, la tentación es corregirlo como si fuera un error. Pero si el historial de whyso dice “el usuario pidió explícitamente esta estructura, y el motivo no era rendimiento sino legibilidad”, no lo toca.
No vuelve a proponer opciones ya descartadas
En una sesión anterior hubo la conversación “¿probamos el enfoque A?” → “No, vamos con B”. La IA de la nueva sesión no sabe nada de eso y vuelve a proponer A. Para el usuario es exasperante. Con whyso, la IA ya sabe qué direcciones se evaluaron y se rechazaron.
Mantiene el contexto de un trabajo continuo
Si el usuario dice “continúa con el refactor de ayer”, ahora la IA tiene que mirar el diff e inferir. Con el historial de whyso puede leer directamente las peticiones del usuario de la sesión anterior y el razonamiento de la IA. El trabajo continuo pasa de ser una inferencia a basarse en hechos.
El registro se acumula de sesión en sesión
Con esta estructura, el historial de whyso crece sesión a sesión. El motivo de los cambios de esta sesión se transmite a la IA de la siguiente. El problema de la falta de memoria entre sesiones se resuelve a nivel de archivo, sin necesidad de un sistema de memoria independiente.
Lo que hay en whyso es lo que hizo la IA. Pero la IA no lo recuerda. El registro que ella misma creó es precisamente lo que más necesita. Ahí está el punto singular de whyso cuando se combina con herramientas de AI coding.
Para una persona, whyso es “una herramienta que deja automáticamente buenos mensajes de commit”. Para la IA, whyso es la memoria que trasciende las sesiones.
Uso
Instalación
go install github.com/park-jun-woo/whyso/cmd/whyso@latest
Consultar el historial de un archivo
# Un solo archivo
whyso history README.md
# Todo un directorio
whyso history internal/ --all
# Salida en espejo de la estructura de archivos
whyso history . --all --output .file-histories/
# Formato JSON
whyso history README.md --format json
Lista de sesiones
whyso sessions
Cómo funciona
Rastreo inverso de la cadena parentUuid
Todos los registros del JSONL están enlazados por uuid y parentUuid. Partiendo del tool_use que modificó un archivo, se remonta la cadena de parentUuid hasta llegar a la petición original del usuario que desencadenó esa modificación.
user message (uuid: A) ← "Añade validación de si la columna x-sort está en el DDL"
→ assistant tool_use (parentUuid: A)
→ tool_result (parentUuid: B)
→ assistant Edit (parentUuid: C) ← motivo de esta modificación = A
Como en medio puede haber mensajes de tipo tool_result, basta con extraer los que tienen type == "user" y content de tipo cadena para encontrar la petición real del usuario.
Decisiones de diseño
Solo se rastrean Write/Edit. Las llamadas a Write y Edit de Claude Code incluyen explícitamente la ruta del archivo y el contenido del cambio. Las operaciones de archivo en comandos Bash (rm, mv, cp) se detectan heurísticamente, pero Write/Edit son el objetivo principal de rastreo. Como Claude Code está diseñado para usar Write/Edit al modificar archivos, estos dos tools capturan la gran mayoría de los cambios.
También se incluyen los subagentes. Cuando Claude Code procesa tareas complejas, puede crear subagentes. Las sesiones de los subagentes se guardan dentro del directorio de la sesión padre. whyso también analiza estas sesiones de subagentes para construir un historial completo.
Actualizaciones incrementales. Al usar la opción --output para escribir en un directorio, las sesiones ya analizadas se omiten. Aunque el número de sesiones crezca hasta cientos, no hay que reanalizar todo desde cero cada vez.
Cifras
Resultado de rastrear con whyso el propio proceso de desarrollo de whyso:
| Elemento | Valor |
|---|---|
| Número de sesiones | 17 |
| Llamadas a Write | 660 |
| Llamadas a Edit | 1.415 |
| Operaciones de archivo en Bash | 206 |
| Archivos únicos modificados | 480 |
De 17 sesiones se extrajeron los historiales de cambio de 480 archivos. En cada archivo queda registrado “por qué se creó y por qué cambió”.
Limitaciones
- Solo funciona con Claude Code. Los datos de sesión de otras herramientas de AI coding tienen formatos distintos. Por ahora solo se admite el formato JSONL de Claude Code.
- Solo rastrea archivos de texto. Las llamadas a Write/Edit tool_use se dirigen a archivos de texto. Los cambios en imágenes y archivos binarios no se rastrean.
- Los datos de sesión deben estar en local. Es necesario que los archivos de sesión estén en
~/.claude/projects/. Si se eliminaron o el trabajo se realizó en otra máquina, ese registro no existe.
Resumen
En la era de escribir código junto con la IA, el motivo de un cambio ya no necesita depender únicamente del mensaje de commit. La conversación en sí es el registro, y de ese registro se puede extraer automáticamente el historial de cambios por archivo.
Si git blame muestra “quién, cuándo y qué cambió”, whyso muestra “por qué”.
Código: github.com/park-jun-woo/whyso