whyso — ce que git blame ne montre pas

git blame montre qui, quand et quoi a changé. whyso montre pourquoi.


Le problème

Quand on veut savoir pourquoi une ligne de code est écrite ainsi, on peut consulter git blame et les messages de commit.

$ git blame internal/handler/page.go
a3f1b2c (parkjunwoo 2026-03-08) func CreatePage(c *gin.Context) {

Qui, quand, quoi — on l’a. Pourquoi — on ne l’a pas.

On pourrait écrire la raison dans le message de commit, non ? La réalité, c’est plutôt ça :

fix: update handler
refactor: clean up
wip

Écrire de bons messages de commit est une question de discipline. Peu importe les conventions d’équipe, à 3h du matin en train de corriger un bug, personne ne pense : « je devrais soigneusement documenter le contexte et les motivations de ce changement dans le message de commit ».

Mais à l’ère du coding avec l’IA, la situation est différente. La raison du changement est déjà consignée.


Les données de session de Claude Code

Claude Code enregistre toutes les conversations dans des fichiers JSONL sous ~/.claude/projects/. Chaque entrée contient les messages utilisateur, les réponses de l’IA, les appels tool_use (Write, Edit, Bash), et une chaîne parentUuid qui les relie.

Utilisateur : "commence l'implémentation de la commande whyso validate"
  → IA : Write internal/crosscheck/crosscheck.go
    → IA : Edit internal/crosscheck/crosscheck.go
      → IA : "création du package crosscheck initial — validation de correspondance SSaC↔OpenAPI operationId"

La raison pour laquelle un fichier a été créé ou modifié est inscrite dans la conversation elle-même. C’est plus riche qu’un message de commit, et ça n’exige aucune intention particulière. Dès lors qu’on a eu la conversation, tout est automatiquement enregistré.

whyso parse ces données pour extraire l’historique des modifications par fichier.


La vie d’un fichier devient visible

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: "commence l'implémentation de la commande whyso validate"
    answer: "création du package crosscheck initial — validation de correspondance SSaC↔OpenAPI operationId"
    tool: Write

  - timestamp: 2026-03-09T10:15:33Z
    session: 4e9b4e5e-3a50-43f2-be6e-e5db228ecc3b
    user_request: "ajoute la validation de la présence de la colonne x-sort dans le DDL"
    answer: "ajout de la validation croisée colonnes x-sort/x-filter → DDL"
    tool: Edit

  - timestamp: 2026-03-10T09:41:22Z
    session: b2e43b4f-cb21-4286-975d-1eb9de8a16c0
    user_request: "ajoute aussi la validation croisée de la spec Func"
    answer: "ajout de la validation croisée @call ↔ spec Func nombre/type d'arguments"
    tool: Edit

Pourquoi il a été créé, et comment il a évolué selon quelles demandes. Toute la vie d’un fichier devient visible.


Pourquoi c’est nécessaire

Les angles morts de la code review

Lors d’une review de PR, il arrive qu’on se demande : « pourquoi ce changement ? » Si la raison n’est pas dans le message de commit, il faut interroger l’auteur. Si l’auteur ne s’en souvient plus, il faut relire le code pour en déduire l’intention.

Dans un environnement de coding avec IA, la réponse à cette question se trouve dans les données de session. whyso va la chercher.

L’onboarding

La façon la plus rapide pour un nouveau membre d’équipe de comprendre une base de code, c’est de savoir « pourquoi ce code est ainsi ». git log est une liste chronologique de changements ; la documentation est un instantané de l’état actuel. L’historique par fichier de whyso montre ce qui se trouve entre les deux — la chaîne des intentions.

L’auto-documentation

Même en développant seul, il arrive qu’on ne se rappelle plus pourquoi on a écrit quelque chose trois mois plus tôt. whyso restaure la conversation entre soi et l’IA dans le passé. Le contexte qu’on n’a pas écrit dans le message de commit est là.


La relation avec git blame

whyso ne remplace pas git blame. Il le complète.

git blamewhyso
QuiO
QuandOO
QuoiO (par ligne)O (par tool_use)
Pourquoi△ (message de commit)O (requête utilisateur + explication IA)
Source de donnéeshistorique gitsessions Claude Code

Si git blame est l’« enregistrement officiel » fondé sur les commits, whyso est le « journal de travail » fondé sur les conversations. Le contexte qu’on n’a pas pu écrire dans l’enregistrement officiel subsiste dans le journal de travail.


Une structure où l’IA lit ses propres traces

Le cas d’usage le plus fascinant de whyso, c’est que ce n’est pas un humain qui lit — c’est l’IA elle-même.

Claude Code oublie tout à la fin d’une session. Quand on ouvre le même projet lors d’une nouvelle session, il n’y a plus rien : pourquoi on avait structuré ainsi hier, quelles options on avait envisagées puis rejetées, dans quel contexte l’utilisateur avait formulé sa demande. L’IA ne peut que relire le code pour en déduire l’intention.

Imaginons qu’on ajoute une ligne à CLAUDE.md :

Avant toute modification de fichier, exécuter obligatoirement `whyso history <file>`. S'il existe un historique, le lire avant de modifier.

Ce que cette ligne change :

Savoir quels changements ne pas annuler

On lit un fichier avant de le modifier, et un bout de code semble bizarre. Vu uniquement l’état actuel, on voudrait le corriger en pensant que c’est une erreur. Mais si l’historique whyso indique que « l’utilisateur a explicitement demandé cette structure, non pour des raisons de performance mais de lisibilité », on n’y touche pas.

Ne pas reproposer des options déjà rejetées

Dans une session précédente, il y avait eu l’échange : « on essaie l’approche A ? » → « non, allons-y avec B ». L’IA d’une nouvelle session l’ignore et propose à nouveau A. Frustrant pour l’utilisateur. Avec whyso, elle connaît les directions déjà étudiées et écartées.

Assurer la continuité du contexte d’un travail en cours

Quand on dit « continue le refactoring d’hier », l’IA doit actuellement inférer à partir du diff. Avec l’historique whyso, elle peut lire directement les requêtes utilisateur de la session précédente et les raisonnements de l’IA. Le travail en continu repose sur des faits, pas sur des déductions.

L’historique s’accumule au fil des sessions

Avec cette structure, l’historique whyso s’enrichit de session en session. La raison d’une modification effectuée lors de cette session est transmise à l’IA de la prochaine. Le problème de l’absence de mémoire entre sessions est résolu fichier par fichier, sans système de mémoire séparé.

Ce qui est enregistré dans whyso, c’est le travail de l’IA. Mais l’IA ne s’en souvient pas. Les traces qu’elle a créées sont précisément ce dont elle a le plus besoin. C’est le point singulier de whyso combiné aux outils de coding IA.

Pour un humain, whyso est « un outil qui laisse automatiquement de bons messages de commit ». Pour une IA, whyso est une mémoire qui traverse les sessions.


Utilisation

Installation

go install github.com/park-jun-woo/whyso/cmd/whyso@latest

Consulter l’historique d’un fichier

# Un seul fichier
whyso history README.md

# Tout un répertoire
whyso history internal/ --all

# Sortie en miroir de la structure de fichiers
whyso history . --all --output .file-histories/

# Format JSON
whyso history README.md --format json

Liste des sessions

whyso sessions

Comment ça fonctionne

Remonter la chaîne parentUuid

Chaque entrée du JSONL est reliée par uuid et parentUuid. En remontant la chaîne parentUuid depuis le tool_use où l’IA a modifié un fichier, on atteint la requête originale de l’utilisateur qui a déclenché cette modification.

message utilisateur (uuid: A)          ← "ajoute la validation de la présence de la colonne x-sort dans le DDL"
  → tool_use assistant (parentUuid: A)
    → tool_result (parentUuid: B)
      → Edit assistant (parentUuid: C)  ← raison de cette modification = A

Comme des messages de type tool_result s’intercalent, on extrait les vrais messages utilisateur en ne retenant que ceux dont type == "user" et dont content est une chaîne de caractères.

Décisions de conception

Seuls Write/Edit sont suivis. Les tool_use Write et Edit de Claude Code contiennent explicitement le chemin du fichier et le contenu des modifications. Les manipulations de fichiers par commandes Bash (rm, mv, cp) sont détectées par heuristique, mais Write/Edit sont les cibles principales du suivi. Claude Code étant conçu pour utiliser Write/Edit lors des modifications de fichiers, ces deux outils suffisent à capturer l’essentiel des changements.

Les sous-agents sont inclus. Quand Claude Code traite des tâches complexes, il peut créer des sous-agents. Les sessions de ces sous-agents sont stockées dans les sous-répertoires de la session parente. whyso parse également ces sessions de sous-agents pour construire un historique complet.

Mises à jour incrémentales. Lors d’une sortie vers un répertoire avec l’option --output, les sessions déjà parsées sont ignorées. Même si les sessions se comptent par centaines, tout n’est pas retraité à chaque fois.

Chiffres

Résultat du suivi par whyso du développement du projet whyso lui-même :

ÉlémentValeur
Nombre de sessions17
Appels Write660
Appels Edit1 415
Manipulations de fichiers Bash206
Nombre de fichiers uniques modifiés480

Sur 17 sessions, l’historique des modifications de 480 fichiers a été extrait. Pour chaque fichier, « pourquoi il a été créé et pourquoi il a changé » est enregistré.


Limites

  • Exclusivement pour Claude Code. Les données de session d’autres outils de coding IA ont des formats différents. Seul le format JSONL de Claude Code est actuellement pris en charge.
  • Seuls les fichiers texte sont suivis. Les tool_use Write/Edit ciblent les fichiers texte. Les modifications d’images et de fichiers binaires ne sont pas tracées.
  • Les données de session doivent être en local. Les fichiers de session doivent être présents dans ~/.claude/projects/. Si vous les avez supprimés ou avez travaillé sur une autre machine, ces traces n’existent pas.

En résumé

À l’ère où l’on écrit du code avec l’IA, la raison d’un changement n’a plus besoin de reposer uniquement sur les messages de commit. La conversation elle-même est une trace, et depuis cette trace il est possible d’extraire automatiquement l’historique des modifications par fichier.

Là où git blame montre « qui a changé quoi et quand », whyso montre pourquoi.

Code : github.com/park-jun-woo/whyso