Command Palette

Search for a command to run...

Revue de code automatique avec CodeRift

🇬🇧EN

CodeRift analyse chaque merge request GitLab en 7 étapes : parsing de diff, AST tree-sitter, règles TOML, agents IA et commentaires inline automatiques.

15 min de lecture
code-reviewironflowrustiagitlabautomatisationtree-sitter
Schéma du pipeline CodeRift : GitLab webhook, API Rust, agents IronFlow, commentaires inline GitLab

La revue de code est le goulot d’étranglement de la plupart des équipes. La merge request est ouverte, l’auteur attend, le reviewer est sur autre chose. Quand la review arrive enfin, elle est souvent superficielle : un coup d’oeil sur le diff, un “LGTM”, merge. Les bugs de logique, les failles de sécurité et les violations d’architecture passent à travers.

J’ai construit CodeRift pour résoudre ce problème. C’est une plateforme de revue de code automatique qui analyse chaque merge request GitLab avec un pipeline en 7 étapes : parsing de diff, analyse AST via tree-sitter, moteur de règles TOML, agents IA spécialisés parallèles, corrélation cross-fichiers, validation des faux positifs, et publication des commentaires inline directement dans la MR. Le tout orchestré par IronFlow, mon moteur de workflows Rust.

L’architecture

CodeRift suit un modèle API + Workers. L’API (Rust/Axum/SQLx) gère la persistance, l’authentification GitLab OAuth et les webhooks. Les workers IronFlow interrogent l’API pour les reviews en attente, les exécutent, et postent les résultats.

GitLabwebhook MRCodeRift APIAxum + SQLx + Postgrespersistance + auth OAuthIronFlow Workerexécution du workflowreview-merge-requestGitLabinline commentsPipeline de review (dans le worker) :règles -> regex -> symboles -> chunking -> agents -> corrélation -> validationsécuritébugsperformancecorrélationvalidation

La séparation API/Worker est la même que celle d’IronFlow : l’API possède la persistance et ne fait jamais d’exécution. Scaler, c’est lancer plus de workers.

Le pipeline de review en 7 étapes

Le workflow review-merge-request implémente le trait WorkflowHandler d’IronFlow. Chaque étape est une opération IronFlow avec retry automatique et logs structurés.

Étape 1-3 : Préparation

Le worker met à jour le statut de la review en base, poste une note “review en cours” sur la MR GitLab, et met le commit status à running. Le développeur voit immédiatement que la review IA est lancée.

ctx.operation("update-review-status", &update_status_op).await?;

ctx.http(
    "post-review-started",
    HttpConfig::post(&notes_url)
        .header("PRIVATE-TOKEN", &CONFIG.gitlab.bot_token)
        .json(serde_json::json!({ "body": review_started_message(language) })),
).await?;

commit_status::set(ctx, "set-commit-status-running", &proj,
    &payload.head_sha, payload.review_id, "running",
    "AI review in progress...").await?;

Étape 4 : Le pipeline de review (le coeur)

C’est ici que le travail se fait. Le pipeline suit cette séquence :

Règles TOML : CodeRift charge un ensemble de règles embarquées à la compilation (include_dir!). Chaque règle cible un langage, des patterns de fichiers, et définit un pattern regex avec des exceptions. Par exemple, la règle rust-unwrap détecte les .unwrap() dans le code de production en excluant les fichiers de test :

[[rules]]
id = "rust-unwrap"
severity = "error_handling"
score = 7
title = ".unwrap() in production code"
languages = ["rust"]
file_patterns = ["*.rs"]
exclude_patterns = ["*_test.rs", "tests/*"]
type = "regex"
pattern = '\.unwrap\(\)'
negative_pattern = '#\[test\]|#\[cfg\(test\)\]|mod tests'

Les règles couvrent Rust, TypeScript, Python, Go, SQL, et des patterns communs (OWASP, prompt injection). Chaque projet peut ajouter ses propres règles ou désactiver celles du serveur via un fichier .coderift/context.md.

Analyse AST : tree-sitter parse les fichiers modifiés et extrait un index de symboles (définitions, références, edges cross-fichiers). Cet index sert à deux choses : construire un graphe de dépendances pour grouper les fichiers liés dans les mêmes chunks, et détecter des patterns structurels que les regex ne voient pas.

Chunking : les fichiers sont regroupés en chunks de 5 (configurable) pour la review parallèle. Quand le graphe de dépendances est disponible, les fichiers liés restent dans le même chunk pour donner à l’agent le contexte des deux côtés d’une interface.

Agents IA spécialisés : chaque chunk est reviewé par 3 agents en parallèle, chacun avec un angle différent :

AgentModèleFocus
SécuritéOpus 4.6Injections, XSS, SSRF, contrôle d’accès, secrets
BugsOpus 4.6Logique incorrecte, edge cases, erreurs de type
PerformanceSonnet 4.6N+1, allocations inutiles, complexité algorithmique

Chaque agent a un budget en USD configurable et un maximum de 4 turns. Le provider IronFlow gère l’exécution et le tracking des coûts. Si un agent échoue (erreur de schéma, timeout), le pipeline continue avec les résultats des autres.

let mut agent = Agent::new()
    .system_prompt(system)
    .prompt(prompt)
    .model(Model::OPUS_46)
    .max_turns(4)
    .max_budget_usd(budget)
    .output::<FindingsOutput>();

Corrélation cross-fichiers : un agent Sonnet 4.6 reçoit tous les findings de tous les chunks et identifie les vulnérabilités qui traversent plusieurs fichiers. Par exemple, un input non validé dans un handler qui arrive dans une requête SQL dans un autre fichier.

Validation des faux positifs : un dernier agent filtre les findings non pertinents. Les faux positifs courants : un .unwrap() dans du code de test, un pattern flaggé dans un commentaire, un finding qui cible du code non modifié, ou un score gonflé par rapport au risque réel.

Étape 5-6 : Publication

Le worker poste les résultats dans la MR GitLab :

  • Un résumé avec un walkthrough de la MR, les fichiers groupés par zone fonctionnelle, des diagrammes de séquence Mermaid pour les flux non triviaux, et des checks pre-merge (sécurité, gestion d’erreur, tests).
  • Des commentaires inline sur les lignes concernées, avec la sévérité (Bug, Security, Performance, Error Handling, Suggestion), un score de criticité (Critical/Major/Moderate/Minor), et une suggestion de fix.

Étape 7 : Commit status

Le commit status GitLab passe à success ou failed. Si la review a des findings Critical, le pipeline peut bloquer le merge.

Les findings

Chaque finding a une structure précise :

pub struct Finding {
    pub file: String,
    pub line: u32,
    pub end_line: Option<u32>,
    pub severity: Severity,    // Bug | Security | Performance | ErrorHandling | Suggestion
    pub score: u8,             // 0-10, convertible en Critical/Major/Moderate/Minor
    pub title: String,
    pub comment: String,
    pub suggestion: Option<String>,
    pub analysis_chain: Vec<String>,
    pub ai_fix_prompt: Option<String>,
}

Le champ analysis_chain contient le raisonnement étape par étape de l’agent. Le champ ai_fix_prompt est un prompt prêt à l’emploi pour corriger le finding automatiquement.

Pourquoi pas un simple appel à Claude Code ?

La première version de ce système utilisait un node n8n qui invoquait Claude Code CLI. Ça fonctionnait pour les petites MR, mais les limites sont vite apparues :

  • Pas de contexte structuré : Claude voyait un diff brut sans comprendre les relations entre fichiers
  • Pas de règles : impossible d’encoder les conventions du projet de manière fiable
  • Pas de déduplication : les mêmes findings revenaient en double ou triple
  • Pas de contrôle de coût : un diff de 2000 lignes pouvait coûter 15 USD
  • Pas de validation : aucun filtre sur les faux positifs

CodeRift résout chacun de ces problèmes. Le pipeline structuré (règles + AST + agents spécialisés + validation) produit des findings plus précis que l’approche “envoie tout le diff à un LLM et espère”.

Configuration par projet

Chaque projet peut personnaliser la review via .coderift/context.md :

# Architecture

4 couches strictes : rest, services, repositories, entities.
Violations à signaler :
- rest qui importe directement repositories
- services qui fait du SQL brut
- repositories qui contient de la logique métier

# Frontend

Les types API dans app/types/generated.ts sont auto-générés.
Ne jamais redéfinir manuellement un type qui existe dans ce fichier.

Ce fichier est injecté dans les prompts des agents comme contexte non fiable (sandboxé, sans possibilité d’altérer les instructions de review). Les agents l’utilisent pour comprendre les conventions du projet et flagger les violations spécifiques.

La stack

CodeRift est construit avec l’écosystème que j’ai développé : IronFlow pour l’orchestration des workflows, la même architecture en couches (entities/repositories/services/rest) que Netir, et MCP RTK en option pour réduire les tokens sur les serveurs MCP connectés. Le setup Claude Code et les skills que j’utilise au quotidien m’ont servi de base pour structurer les prompts de review de CodeRift.