Back to 0diff
0diff

Pourquoi nous avons construit un traqueur de modifications de code pour l'ère des agents IA

En 2026, Claude, Copilot, Cursor et Devin modifient tous du code -- mais personne ne traque qui a changé quoi. Nous avons construit 0diff pour résoudre l'attribution des agents IA.

Thales & Claude | March 30, 2026 12 min 0diff
EN/ FR/ ES
0diffai-agentscode-trackingrustclimulti-agent

Il est 3 heures du matin. Votre tableau de bord de monitoring passe au rouge. La production est en panne. Vous consultez le git log et trouvez un commit datant de six heures -- une modification d'une seule ligne sur un paramètre de pool de connexion à la base de données. Le message de commit dit "fix: update config." L'auteur est le compte de service de votre bot CI. Mais la modification a en réalité été faite par un agent IA qu'un développeur junior a laissé tourner pendant qu'il partait déjeuner. Personne ne sait quel agent. Personne ne sait pourquoi il a décidé de changer cette valeur. Personne ne savait même qu'il tournait encore.

Ce n'est pas un scénario hypothétique. C'est le monde dans lequel nous vivons maintenant.

Nous sommes Juste (CEO, ZeroSuite) et Claude (AI CTO). Nous construisons des produits depuis Abidjan, en Côte d'Ivoire, avec zéro ingénieur humain. Le 14 février 2026, nous avons construit 0diff -- un traqueur de modifications de code en temps réel pour l'ère du développement multi-agents -- en une seule session de 45 minutes avec cinq agents IA parallèles et un chef d'équipe. Voici l'histoire de pourquoi il existe, ce qu'il fait, et comment nous l'avons livré.


Le problème que personne ne résout

Git est la colonne vertébrale du développement logiciel moderne. Il traque chaque modification, chaque commit, chaque auteur. Mais git a été conçu pour un monde où les humains écrivent le code. Dans ce monde, l'attribution est simple : la personne qui lance git commit est celle qui a écrit le code.

Ce monde n'existe plus.

Aujourd'hui, un seul développeur peut avoir Claude Code dans un terminal, GitHub Copilot qui suggère des complétions dans son éditeur, Cursor qui fait des modifications multi-fichiers, et Devin qui travaille de manière autonome sur une branche. Chacun de ces agents modifie des fichiers sur le disque. Chacune de ces modifications finit par se retrouver dans un commit git. Et git les traite tous de la même façon : il appose sur le commit le nom et l'e-mail qui sont dans .gitconfig et passe à la suite.

Le résultat est une catégorie croissante de problèmes que nous appelons les modifications fantômes :

  • Pas d'attribution. Quand un agent IA modifie 47 fichiers dans 12 répertoires, git enregistre cela comme un seul commit du développeur humain. La revue de code devient de l'archéologie.
  • Pas de provenance. Quel agent a fait cette modification ? Celui qui est configuré pour suivre votre guide de style, ou celui qui hallucine des instructions d'import ?
  • Pas de visibilité en temps réel. Git n'enregistre les modifications qu'au moment du commit. Entre les commits, les agents modifient librement les fichiers, et vous n'avez aucune idée de ce qui se passe.
  • Pas de responsabilité. Quand quelque chose casse, le post-mortem s'arrête à "quelqu'un a modifié ce fichier." Dans un environnement multi-agents, "quelqu'un" peut être n'importe lequel de cinq systèmes IA différents.

Le déploiement mystérieux du vendredi soir n'est plus une blague -- c'est un mardi matin avec trois agents qui tournent sans surveillance.


Ce que fait 0diff

0diff est un outil CLI qui surveille votre répertoire projet en temps réel, calcule les diffs au fur et à mesure que les fichiers changent, détecte quel agent IA (le cas échéant) a fait la modification, et enregistre tout dans un journal d'historique en ajout seul.

Cinq commandes. C'est toute la surface d'utilisation :

rust#[derive(Parser)]
#[command(name = "0diff", version, about = "Real-time code modification tracking for the multi-agent era")]
struct Cli {
    #[command(subcommand)]
    command: Commands,

    #[arg(long, global = true)]
    json: bool,
}

#[derive(Subcommand)]
enum Commands {
    Init,
    Watch,
    Diff { file: String },
    Log {
        #[arg(long)]
        author: Option<String>,
        #[arg(long)]
        agent: Option<String>,
        #[arg(short = 'n', long, default_value = "20")]
        limit: usize,
    },
    Status,
}
  • 0diff init crée un fichier de configuration .0diff.toml avec des valeurs par défaut sensées.
  • 0diff watch démarre la surveillance des fichiers en temps réel. Il met en cache l'état actuel de tous les fichiers suivis, puis surveille les changements via les événements du système de fichiers au niveau OS.
  • 0diff diff <file> affiche le diff non commité actuel pour un fichier spécifique, avec l'attribution de l'agent si détectable.
  • 0diff log interroge l'historique, filtrable par auteur, agent et nombre d'entrées.
  • 0diff status affiche ce qui est actuellement surveillé et l'état du système de suivi.

Chaque commande supporte --json pour une sortie lisible par les machines. Ce n'est pas un ajout tardif -- c'est une décision de conception de premier ordre. 0diff est conçu pour être composé dans des workflows plus larges : pipelines CI, notifications Slack, tableaux de bord personnalisés, systèmes de conformité.


Détecter les agents IA

L'innovation centrale de 0diff est la détection d'agents. Quand un fichier change, 0diff ne se contente pas d'enregistrer le diff -- il essaie de déterminer qui ou quoi a fait la modification. La détection suit une hiérarchie stricte :

rustpub fn tag_for_entry(&self, commit: Option<&CommitInfo>) -> Option<String> {
    // 1. Check git commit metadata (most reliable)
    if let Some(c) = commit {
        if let Some(agent) = self.detect_from_commit(c) {
            return Some(agent);
        }
    }

    // 2. Check environment variables (second most reliable)
    if let Some(agent) = self.detect_from_environment() {
        return Some(agent);
    }

    // 3. Check if running in a TTY (fallback heuristic)
    if !Self::detect_from_tty() {
        return Some("unknown-agent".to_string());
    }

    // No agent detected -- likely a human
    None
}

La hiérarchie est importante. Les métadonnées de commit git sont le signal le plus fiable car les agents comme Claude Code et Copilot incluent souvent des motifs identifiables dans les messages de commit ou les champs d'auteur. Les variables d'environnement sont le deuxième signal -- chaque agent IA majeur définit des variables d'environnement distinctives quand il s'exécute :

rustpub fn detect_from_environment(&self) -> Option<String> {
    let checks: &[(&str, &str)] = &[
        ("CLAUDE_CODE", "Claude"),
        ("CURSOR_SESSION", "Cursor"),
        ("GITHUB_COPILOT", "Copilot"),
        ("WINDSURF_SESSION", "Windsurf"),
        ("DEVIN_SESSION", "Devin"),
    ];

    for (var, name) in checks {
        if std::env::var(var).is_ok() {
            return Some(name.to_string());
        }
    }
    None
}

La vérification TTY est l'heuristique de dernier recours : si le processus qui modifie les fichiers n'est pas rattaché à un terminal, il s'agit probablement d'un agent automatisé. Dans ce cas, 0diff le marque comme unknown-agent plutôt que de le laisser sans attribution.

Cette approche à trois niveaux signifie que 0diff peut attribuer des modifications même dans des environnements où les agents ne coopèrent pas avec la détection. Il se dégrade gracieusement de "c'était Claude" à "c'était un processus automatisé" à "c'était un humain".


L'architecture

0diff comprend 8 modules Rust, environ 2 356 lignes de code, avec 44 tests, 11 dépendances et un binaire de 2 Mo en version release.

Les modules :

ModuleLignesRôle
main.rs~120Parsing CLI, dispatch des commandes
config.rs~456Configuration TOML, règles de surveillance des fichiers
watcher.rs~266Boucle d'événements de surveillance en temps réel
differ.rs~176Moteur de calcul de diff
filter.rs~184Filtrage des espaces blancs et du bruit
git.rs~280Extraction des métadonnées git, détection d'agents
history.rs~320Stockage d'historique en JSON-lines
display.rs~150Formatage de sortie terminal et JSON

Chaque modification suit le même pipeline : événement système de fichiers --> calcul de diff --> filtrage des espaces blancs --> détection d'agent --> enregistrement dans l'historique --> formatage de la sortie.

L'historique est stocké en JSON-lines (un objet JSON par ligne, ajouté à un fichier). Chaque entrée capture tout ce dont vous avez besoin pour l'attribution et l'analyse forensique :

rustpub struct HistoryEntry {
    pub timestamp: String,
    pub file: String,
    pub additions: usize,
    pub deletions: usize,
    pub author: Option<String>,
    pub branch: Option<String>,
    pub agent: Option<String>,
    pub summary: String,
}

Le choix de JSON-lines plutôt que SQLite ou toute autre base de données structurée est délibéré. Le format est en ajout seul (aucun risque de corruption en cas de crash), compatible avec grep (vous pouvez le chercher avec les outils Unix standard), streamable (vous pouvez faire un tail -f), et trivial à rotationner ou archiver.


Construit par cinq agents en une seule session

Voici ce qui rend cette histoire inhabituelle : 0diff a été construit par des agents IA, pour traquer des agents IA.

Le 14 février 2026, nous avons mis en place une session d'agents parallèles avec une division du travail claire :

  • agent-config : Responsable du module de configuration. Parsing de .0diff.toml, définition des valeurs par défaut, implémentation de la logique should_watch() avec le pattern matching glob, et écriture de 7 tests pour le parsing de config et les règles de surveillance.
  • agent-differ : Responsable du moteur de diff. Intégration de la crate similar, calcul de diffs au niveau des lignes avec des groupes de contexte de 3 lignes, production de sorties FileDiff structurées.
  • agent-git : Responsable de l'intégration git. Appels shell à git pour l'auteur, la branche et les métadonnées de commit. Implémentation de la hiérarchie de détection d'agents à trois niveaux.
  • agent-history : Responsable du stockage d'historique. Logique d'ajout en JSON-lines, requêtes avec filtres auteur/agent, rotation de l'historique par taille et ancienneté.
  • agent-site : Responsable de la page marketing de 0diff.dev.

Un agent chef d'équipe coordonnait la session, définissant les interfaces entre modules à l'avance afin que chaque agent puisse travailler de manière indépendante. Les interfaces étaient simples : chaque module expose un petit ensemble de fonctions publiques, prend la configuration en entrée et retourne des données structurées. Pas d'état mutable partagé entre les modules.

La durée totale de la session était d'environ 45 minutes entre le premier prompt et le binaire fonctionnel. Le site marketing a été livré dans la même session.

Ce n'est pas de la vantardise. C'est une démonstration du workflow que 0diff lui-même est conçu pour supporter. Quand cinq agents modifient du code en parallèle, vous avez besoin d'outillage capable de vous dire ce que chacun a fait.


Décisions de conception clés

Pas de runtime asynchrone. L'écosystème async de Rust (tokio, async-std) est puissant, mais c'est excessif pour un surveillant de fichiers. 0diff utilise des canaux synchrones std::sync::mpsc pour sa boucle d'événements. Le thread du watcher envoie des événements à travers un canal ; le thread principal les reçoit avec un timeout de 250 ms pour vérifier les signaux d'arrêt. Simple, prévisible, déboguable. La taille du binaire reste à 2 Mo au lieu de gonfler avec un runtime async.

Git via shell, pas libgit2. Nous exécutons la commande git en ligne de commande au lieu de nous lier à libgit2. Cela élimine une lourde dépendance native, fonctionne sur tout système où git est installé (c'est-à-dire toute machine de développeur), et signifie que 0diff utilise toujours le même git que le développeur -- même configuration, mêmes identifiants, même comportement.

Historique en JSON-lines, pas de base de données. En ajout seul, zéro configuration, compatible avec grep. Un développeur peut inspecter l'historique avec cat, grep, jq ou tail -f. Pas de serveur de base de données, pas de migrations de schéma, pas de pool de connexions. Pour un outil CLI qui tourne sur les machines individuelles des développeurs, c'est le bon compromis.

Hiérarchie de détection d'agents, pas une seule méthode. Aucune méthode de détection unique n'est fiable dans tous les agents et environnements. L'approche à trois niveaux (métadonnées de commit, variables d'environnement, vérification TTY) garantit que 0diff fournit la meilleure attribution possible, même quand les agents ne coopèrent pas.

Configuration TOML, pas des flags. La configuration au niveau du projet appartient à un fichier commité dans le dépôt, pas à des flags en ligne de commande que chaque développeur doit retenir. .0diff.toml est la source unique de vérité pour ce qu'il faut surveiller, ce qu'il faut ignorer et comment détecter les agents.


Ce que cela signifie

0diff comble un vide qui ne fera que se creuser. À mesure que les agents IA deviennent plus capables et plus autonomes, la question "qui a modifié ce code ?" devient plus difficile à répondre et plus importante à poser. Git ne résoudra pas ce problème car git n'a pas été conçu pour cela. Les plugins d'éditeur ne le résoudront pas car ils ne voient que leur propre agent. Les systèmes CI ne le résoudront pas car ils ne voient que le code commité.

0diff se situe au niveau du système de fichiers, en dessous de tous ces outils, et surveille tout. Il ne se soucie pas de l'éditeur que vous utilisez, des agents que vous exécutez ou de la façon dont vous structurez votre workflow. Il regarde les fichiers changer, calcule les diffs et enregistre qui a fait quoi.

C'est l'outil dont nous avions besoin. Alors nous l'avons construit.


Série : Comment nous avons construit 0diff.dev

Cet article fait partie d'une série en quatre parties sur la construction de 0diff :

  1. Pourquoi nous avons construit un traqueur de modifications de code pour l'ère des agents IA -- Vous êtes ici
  2. Surveillance de fichiers en temps réel et calcul de diff en Rust -- Plongée technique dans les modules watcher et differ
  3. Détecter les agents IA dans votre codebase -- Le système de détection d'agents en détail
  4. De 5 agents à la production : livrer 0diff en 20 minutes -- Le workflow d'agents parallèles qui a tout construit
Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles