🎯 OBJECTIF
Comprendre comment :
--update sémantique), git hooks, merge driver, et ce qui se committe vs ce qui reste local🧠 MODÈLE MENTAL
Un assistant de code est excellent pour lire un fichier, et catastrophique pour comprendre comment 200 fichiers se connectent. Sans carte structurelle, il infère du générique : il ne sait pas que telle classe est le hub dont dépend tout le reste, ni que telle préoccupation transverse devrait se traiter au niveau de l'enregistrement plutôt qu'en créant un nouveau wrapper. À chaque question, il re-lit des fichiers en série, brûle du contexte et rate les liens inter-modules.
Graphify pré-calcule cette carte une seule fois : il parse le repo en graphe (nœuds = fichiers / fonctions / classes / concepts, arêtes = imports / appels / références) que l'agent interroge à la demande. L'agent cesse de grep à l'aveugle ; il navigue une structure. Résultat concret : des suggestions qui collent à l'architecture réelle, pour une fraction des tokens.
# WHY:, une docstring ou une décision de design extraite comme nœud, relié au code qu'il explique (rationale_for).EXTRACTED (vue dans le code), INFERRED (déduite par le LLM), AMBIGUOUS (incertaine)._origin — champ porté par chaque nœud de graph.json : ast s'il vient du parseur local, autre valeur s'il vient de la passe sémantique. C'est le seul juge fiable de ce que contient réellement le graphe (voir §9).graphify-mcp, installé avec le package).Graphify enchaîne deux passes (AST local, puis sémantique LLM) puis clusterise le résultat.
flowchart LR
SRC[Repo<br/>code, docs, PDF, images] --> P1[Pass 1<br/>tree-sitter AST<br/>local, 0 token]
P1 --> P2[Pass 2<br/>extraction sémantique<br/>LLM, optionnelle]
P1 --> G[NetworkX graph<br/>+ clustering Leiden]
P2 --> G
G --> OUT1[graph.json<br/>requêtable]
G --> OUT2[GRAPH_REPORT.md<br/>god nodes, connexions]
G --> OUT3[graph.html<br/>visu interactive]mermaidextends/implements Java). Extrait classes, fonctions, imports, call graphs, docstrings, commentaires de rationale. Les schémas SQL sont aussi AST-extraits sans LLM : tables, FK, jointures (extra [sql]). Aucun appel LLM, aucun octet de code n'est envoyé.--code-only.EXTRACTED / INFERRED / AMBIGUOUS.🔑 Conclusion clé
Le code source ne quitte jamais la machine (passe 1, tree-sitter local). Seules des descriptions sémantiques des docs partent vers le LLM, jamais le code brut. --code-only coupe même ça.
graph.html est une visu force-directed interactive : chaque nœud est une entité, la couleur encode la communauté Leiden, la taille encode le degré (les gros = god nodes). On clique un nœud, on filtre par communauté, on cherche.

Rendu réel de graph.html : les clusters de couleurs sont les communautés Leiden, les gros nœuds les god nodes. (source : aieatingtheworld.com)
Le rapport GRAPH_REPORT.md en extrait le signal :
# NOTE: / # WHY:, décisions de design, rattachés au code via des arêtes rationale_for.💡 Grille de lecture des god nodes
Les classes de test (*Test, *StepDefinitions…) sont mécaniquement sur-connectées : un test qui référence tout n'est pas un hub d'architecture, c'est un consommateur exhaustif. Les garder dans le graphe (les step definitions BDD sont de la doc comportementale précieuse pour un agent), mais lire le classement en les filtrant mentalement. Les vrais hubs sont derrière.
Deux étapes, une seule fois. Prérequis : Python 3.10+, et de préférence uv (ou pipx).
# Étape 1 — le moteur (package PyPI : graphifyy, double y)
uv tool install graphifyy
# Étape 2 — enregistrer le skill /graphify auprès de l'assistant
graphify install # Claude Code par défaut ; --platform pour les autresbashPuis, dans le repo : /graphify .
💡 En IDE, aucune clé API nécessaire
Via le skill /graphify, la passe sémantique utilise le modèle déjà configuré dans ta session. Pas de clé à poser.
En headless (graphify extract), seule la passe sémantique demande une clé (providers larges : Anthropic, OpenAI, Gemini, Ollama, Bedrock, binaire claude…). Un graphify extract --code-only tourne sans aucune clé, 100 % offline.
Extras à la demande (le cœur est code-only) : graphifyy[pdf], [office] (.docx/.xlsx), [video] (transcription), [sql] (schémas SQL dans le graphe), [mcp] (serveur MCP), [all].
💡 L'extra [sql] : nécessaire, mais pas suffisant
Sans lui, les .sql sont bien lus mais produisent zéro nœud — un avertissement au build le signale (tree_sitter_sql not installed). Sur un repo où le backend vit dans le dépôt (migrations Drizzle, Supabase), c'est tout le schéma qui manque : tables, colonnes, FK. Pour l'ajouter à une install existante : uv tool install "graphifyy[sql]" --force.
Mais après la seule passe AST, la couche SQL forme un îlot. Les tables deviennent des nœuds, reliés entre eux (contains, reads_from, triggers) — et aucune arête ne les relie au code applicatif. Un supabase.from('watch_entry') en TypeScript n'est rattaché à aucun nœud de table. Ce pont relève de la passe sémantique (arêtes INFERRED) : à vérifier sur son propre corpus avant de compter dessus.
Ce qu'il ignore. Un .graphifyignore (syntaxe .gitignore) à la racine. Le .gitignore est respecté automatiquement et les deux sont fusionnés : .graphifyignore exclut davantage, jamais il ne réinclut ce que git exclut. Le flag --no-gitignore désactive l'héritage git si du code utile vit sous .gitignore.
Règles utiles :
.graphifyignore, avec la sémantique git des patterns (* reste dans un segment, ** traverse). Pour n'indexer qu'un sous-arbre d'un répertoire exclu, la forme canonique est :dir/*
!dir/sous-arbre
!dir/sous-arbre/**
# puis ré-exclusions fines dans le sous-arbre
mvnw, gradlew…) : à exclure d'office. Purs scripts shell, ils ne créent que du bruit dans le graphe..claude/ et les dossiers d'outillage agent : en install projet (§5), le SKILL.md de graphify fait 38 Ko et ses fiches references/ portent le total à ~100 Ko — le tout dans le corpus. Constaté : 62 nœuds parasites du type « Step 1 - Ensure graphify is installed » au milieu du graphe applicatif. Exclure .claude/ d'office, idem .agents/ et .github/skills/. Le graphe n'a rien à apprendre de sa propre documentation.pnpm-lock.yaml, snapshots de migrations, fichiers de traduction) : ce sont des cibles de la passe sémantique (YAML/JSON), donc du coût LLM pur pour zéro valeur structurelle. Un pnpm-lock.yaml pèse facilement 500 Ko.⚠️ Le réflexe **/target/ peut exclure des sources
Certains .gitignore ré-incluent des packages sources nommés target via des négations (!**/src/main/**/target/). Le .gitignore gère déjà les build dirs : ajouter un **/target/ dans le .graphifyignore exclurait ces packages sources du graphe à tort. Vérifier le .gitignore avant de recopier la règle.
⚠️ Le piège du nom — trois projets s'appellent « graphify »
graphifyy (PyPI, deux y) — celui de cette note, par Safi Shamsi. La commande installée reste graphify.graphify (npm, un seul y) — un générateur de graphes jQuery de 2015, aucun rapport.@sentropic/graphify (npm) — un fork TypeScript assumé du projet de Safi Shamsi, qui le crédite explicitement dans son README (« builds on the foundational work of Safi Shamsi's graphify »). Projet légitime et actif, mais conventions incompatibles : sortie dans .graphify/ au lieu de graphify-out/, clustering Louvain au lieu de Leiden, surface CLI différente. Un graphe construit par l'un n'est pas lu par l'autre, et les règles qu'il écrit dans CLAUDE.md pointent vers des chemins que l'original ne crée jamais.Le piège est concret : chercher « graphify » sur npm mène droit au fork, jamais à l'original — qui n'est publié que sur PyPI. Contrôle : which graphify et graphify --version (une version 0.9.x = le PyPI ; 0.1x.x = le fork npm).
Si graphify: command not found : uv tool update-shell puis nouveau terminal.
Le skill expose le slash command /graphify (build) et une couche « always-on » qui pousse l'assistant à préférer le graphe pour les questions de code (voir §6). Certaines plateformes bundlent les deux.
| Assistant | Commande |
|---|---|
| Claude Code (Mac / Linux / Win) | graphify install (auto-détecté) |
| Cursor | graphify cursor install |
| GitHub Copilot CLI | graphify copilot install |
| VS Code Copilot Chat | graphify vscode install |
| Gemini CLI | graphify gemini install |
| Codex | graphify codex install (⚠ $graphify, pas /graphify) |
| Cross-framework (Agent Skills) | graphify agents install |
Forme générique pour les ~20 plateformes : graphify install --platform <nom>.
/graphify partout. Cas normal.--project) — écrit le skill dans le repo (.claude/skills/… ou .agents/skills/…), pour le commit et le partager à l'équipe.Le graphe, lui, est toujours par repo (graphify-out/). Pas de graphe « global » multi-repos sauf dossier parent commun.
⚠️ --project sur Claude Code écrit bien plus que le skill
Malgré son nom, graphify install --project ne se contente pas de déposer un skill dans .claude/skills/. Il touche quatre endroits, dont deux fichiers suivis par git :
| Cible | Nature |
|---|---|
.claude/skills/graphify/ |
nouveau — SKILL.md + fiches references/ (~100 Ko) |
.claude/CLAUDE.md |
nouveau — déclare le skill et son trigger /graphify |
CLAUDE.md (racine) |
modifié — une section de règles y est ajoutée |
.claude/settings.json |
modifié — hooks PreToolUse enregistrés |
À savoir : CLAUDE.md et .claude/CLAUDE.md sont deux emplacements équivalents pour Claude Code — même portée « project instructions », tous deux chargés en entier au démarrage de chaque session et concaténés. Ce n'est pas une hiérarchie et il n'y a pas d'override : graphify répartit simplement les règles d'usage dans l'un et la déclaration du skill dans l'autre.
Conséquence pratique : ces règles sont injectées dans chaque session, qu'on utilise le graphe ou non. Pour un CLAUDE.md qu'on garde volontairement mince, l'alternative propre est de déplacer la section dans .claude/rules/graphify.md — même chargement, mais isolé et retirable d'un rm.
Retour en arrière : git checkout CLAUDE.md .claude/settings.json, puis supprimer .claude/skills/graphify/ et .claude/CLAUDE.md.
⚠️ Copilot : deux surfaces, deux règles
Copilot CLI. --project écrit dans .copilot/skills/, un chemin que Copilot ne scanne pas (il ne lit que .github/skills/, .claude/skills/ ou .agents/skills/). Résultat : /graphify non reconnu. Rester en global.
GitHub Copilot app (desktop). Elle synchronise les skills du repo : la voie projet fonctionne.
graphify install --platform agents --project.github/skills/graphify/ pour suivre la convention du repo. /graphify est reconnu immédiatement, même avant commit.Deux points de vigilance sur l'app :
.agents/ (à re-déplacer ; le fichier .graphify_version sert de témoin de désynchronisation)💡 Codex — extraction parallèle
multi_agent = true sous [features] dans ~/.codex/config.toml.
/graphify . # construit le graphe du dossier courant
/graphify . --code-only # AST seul, 0 appel LLM (run rapide)
/graphify ./docs --update # re-extrait uniquement les fichiers changés
/graphify --watch # rebuild auto en tâche de fond quand le code change
graphify query "comment l'auth parle à la base ?" # BFS — contexte large (défaut)
graphify query "..." --dfs # DFS — trace un chemin précis
graphify query "..." --budget 1500 # plafonne la réponse à N tokens
graphify path "AuthModule" "Database" # plus court chemin entre 2 concepts
graphify explain "RateLimiter" # explication en clair d'un nœud
graphify affected "RateLimiter" # traversée inverse : ce qui casse si on y touche
graphify export callflow-html # page d'archi Mermaid
graphify add https://arxiv.org/abs/1706.03762 # ajoute un doc au graphebashC'est l'intérêt réel. Après graphify <plateforme> install, une section est écrite dans le fichier d'instructions de l'assistant (CLAUDE.md, AGENTS.md, .cursor/rules/…) qui lui dit de consulter le graphe avant de répondre aux questions de code, et de le reconstruire après un changement. Tu ne tapes plus graphify query toi-même : tu poses ta question en langage naturel, l'agent lance la requête en arrière-plan.
Sur Claude Code et Gemini CLI, un hook PreToolUse intercepte les appels Glob / Grep (et sur Claude Code, les Read fichier par fichier) et redirige vers GRAPH_REPORT.md / graphify query avant que l'agent parte lire l'arbre brut. Par défaut c'est un nudge, une suggestion que le modèle peut ignorer. Sur Claude Code, graphify install --project --strict installe la variante bloquante : la première lecture brute de la session est refusée avec redirection vers graphify query, puis le hook retombe en nudge. Jamais plus d'un blocage par session ; GRAPHIFY_HOOK_STRICT=1/0 bascule sans réinstaller.
Échange typique (tu ne mentionnes jamais Graphify) :
Toi : « pourquoi le rate-limiter touche la base directement ? »
IA : (lance graphify query en arrière-plan, lit un sous-graphe borné)
→ « RateLimiter → DbPool via checkQuota(). La rationale attachée
(# WHY:) indique que le cache a été retiré pour la cohérence forte. »
(Re)construire reste aussi en langage naturel : « indexe ce repo » → l'agent lance /graphify . ; « réindexe les docs » → /graphify --update. Au premier build, le skill colle dans le chat les 3 sections clés du rapport (god nodes, surprises, questions suggérées) et propose d'explorer.
💡 La bascule mentale
À la main tu pilotes le graphe (query, path, explain). Via l'IA tu oublies le graphe : tu discutes normalement, la couche always-on route vers lui. Les deux modes lisent le même graph.json.
C'est le payoff de l'usage via l'IA (§6). Sans graphe, répondre à « comment l'auth parle à la base ? » force l'agent à grep puis lire des dizaines de fichiers en série : chaque lecture consomme des tokens. Avec le graphe, la même question déclenche une requête bornée qui renvoie un petit sous-graphe (quelques centaines de tokens) au lieu du contenu brut.
sequenceDiagram
participant Dev as Développeur
participant AI as Assistant
participant G as graphify-out/graph.json
Dev->>AI: "Comment l'auth parle à la base ?"
Note over AI: sans graphe → lit N fichiers en série (coûteux)
AI->>G: graphify query "..."
G-->>AI: sous-graphe borné (quelques nœuds)
AI-->>Dev: réponse ancrée sur l'archi réellemermaidChiffres annoncés par le projet : sur un corpus mixte de 52 fichiers (~92k mots), une requête coûte en moyenne ~1,7k tokens contre ~123k en lecture brute, soit 71,5× moins. À plus grande échelle (~500k mots), une requête BFS reste ~2k tokens contre ~670k. Le ratio tient parce qu'une requête renvoie un sous-graphe borné, quasi indépendamment de la taille du repo. La commande graphify benchmark [graph.json] rejoue cette mesure sur son propre graphe.
💡 Mesurer ce qu'une passe sémantique a réellement coûté
Le 71,5× mesure le gain à l'usage. Le coût de la passe elle-même se mesure autrement, et l'instrument dépend de la route choisie :
/graphify . --update) — c'est le modèle de la session qui extrait. Graphify ne voit pas passer la facture et n'écrit pas de cost.json. La mesure se prend côté client : Claude Code écrit un transcript JSONL par session dans ~/.claude/projects/<projet>/<uuid>.jsonl, où chaque message porte un bloc usage (input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens). Sommer sur le fichier donne le chiffre exact. Méthode propre : lancer la passe dans une session neuve dédiée, sans rien faire d'autre, puis sommer.graphify extract --backend <provider>, avec clé) — graphify pilote les appels et écrit lui-même graphify-out/cost.json.Deux nuances de lecture. La première méthode inclut le prompt système, les CLAUDE.md et le chargement du SKILL.md (38 Ko) : c'est le coût de l'opération, pas de l'extraction seule — souvent le chiffre qu'on veut vraiment. Et dans le total, la lecture de cache est facturée à une fraction du prix d'entrée : ce qui pèse, c'est la sortie et la création de cache.
🔑 Conclusion clé
Le gain vient du remplacement de « lire N fichiers » par « lire un sous-graphe borné ». Il n'existe que si la couche always-on est installée (§5) : un graphe construit mais jamais consulté ne fait rien gagner. L'installation elle-même (build sémantique initial, allers-retours agent) est un investissement en tokens ; le remboursement vient des requêtes quotidiennes. Les opérations mécaniques (éditer un ignore, lancer un --code-only) se font au terminal, gratuitement : réserver l'agent au jugement et au reporting.
Scénario : tu débarques sur un repo que tu ne connais pas, ici le corpus httpx fourni par Graphify (une couche transport HTTP, 6 fichiers Python). Objectif : le comprendre sans lire les 6 fichiers un par un.
1 — Installer + enregistrer (une seule fois sur la machine)
uv tool install graphifyy
graphify install # skill /graphify + couche always-on (Claude Code par défaut)bash2 — Construire le graphe
cd httpx
/graphify .bashGraphify parse le code en AST (local), passe le LLM sur les docstrings et docs, puis clusterise. Sortie dans graphify-out/ : 144 nœuds, 330 arêtes, 6 communautés. Le build de ce corpus est quasi instantané ; sur un gros repo, c'est là que le temps se passe (surtout la passe sémantique).
💡 Variante prudente : le build en deux temps
Le /graphify . plein enchaîne les deux passes d'un coup. Sur un vrai repo (surtout d'entreprise), préférer la décomposition :
/graphify . --code-only : passe AST seule, coût zéro. Vérifier graph.html, ajuster le .graphifyignore tant que le périmètre n'est pas propre./graphify . --update : la passe sémantique rattrape tout ce qui n'a pas encore été indexé (docs, markdown).Le cache sait ce qui a déjà été traité : le résultat final est identique au build plein, mais la passe LLM n'est payée qu'une fois le périmètre validé.
Le cadrage du périmètre se fait entièrement au terminal, gratuitement : lister les cibles de la passe sémantique (git ls-files '*.md' '*.yaml' '*.json' '*.png') et les peser avant de lancer quoi que ce soit. C'est là que se joue la facture, pas dans le build AST.
3 — Lire ce que l'agent te renvoie
Le skill ne te jette pas le graph.json brut : il colle dans le chat 3 sections de GRAPH_REPORT.md, celles qui donnent une prise immédiate.
Client, AsyncClient, Response, Request, les 4 classes dont tout dépend. Tu sais par où entrer dans le code.DigestAuth → Response. L'auth digest lit la réponse pour rejouer la requête signée sur un 401 : un couplage invisible à la simple lecture linéaire.…puis il te propose d'explorer.
4 — Explorer en langage naturel
Tu ne tapes pas graphify query : tu discutes, l'agent interroge le graphe pour toi (mécanique du §6).
Toi : « comment une requête passe du Client au réseau ? »
IA → Client.send() → _transport → HTTPTransport.handle_request()
(chemin tracé sur le graphe — pas les 6 fichiers relus)
Besoin d'un lien précis entre deux points ? « trace le chemin entre DigestAuth et Response » → l'agent lance un path sous le capot et te rend les sauts intermédiaires.
5 — Modifier le code, garder le graphe frais
Tu ajoutes un RetryTransport. Au git commit, le hook rebuild l'AST : le nouveau nœud et ses arêtes apparaissent dans le graphe, 0 coût API (c'est de l'AST local).
graphify hook install # une seule fois — ensuite automatique à chaque commitbashSi tu avais touché un README ou un doc, il faudrait un /graphify . --update en fin de session pour relancer la passe LLM sur ces fichiers (voir §9, les deux vitesses).
🔑 Bilan
~2 commandes pour obtenir une carte de l'archi + un point d'entrée (les god nodes), une exploration en langage naturel pour une fraction des tokens, et un graphe qui se maintient seul à chaque commit.
Le point le plus négligé : un graphe périmé ment. Deux vitesses de mise à jour à ne pas confondre :
graphify hook install pose un post-commit et un post-checkout (réalignement du graphe au changement de branche). Rebuild de la structure du code uniquement (fichiers changés), 0 coût API, en tâche de fond détachée : le commit rend la main immédiatement (log dans ~/.cache/graphify-rebuild.log), avec skip auto pendant rebase, merge et cherry-pick. Il ne relance pas la passe sémantique.--update). Pour ré-extraire les docs / markdown / images modifiés (passe LLM), il faut lancer /graphify . --update. Le hook te le signale quand des docs ont bougé.sequenceDiagram
participant Dev as Développeur
participant Hook as post-commit hook
participant AST as Graphify · AST local
participant Sem as Passe sémantique · LLM
participant Out as graphify-out/
Dev->>Dev: édite code + docs
Dev->>Hook: git commit
Hook->>AST: rebuild incrémental (fichiers changés)
AST->>Out: graph.json + callflow-html à jour (structure)
Note over AST,Sem: le hook ne lance PAS la passe sémantique
AST-->>Dev: signale « docs/images changés → --update »
Note over Dev: en fin de session, si des docs ont bougé
Dev->>Sem: /graphify . --update
Sem->>Out: nœuds docs / rationale ré-extraits (LLM)
Dev->>Out: git add graphify-out/ (artefacts portables uniquement)mermaidLes garde-fous qui rendent ça sûr :
--update comme le hook ne retouchent que les fichiers changés (cache SHA256). Markdown : cache frontmatter-aware (changer tags: seul n'invalide rien).graphify hook install installe aussi un git merge driver : graph.json est union-mergé quand deux devs commitent en parallèle, jamais de conflict markers. Il a deux moitiés : l'entrée dans .gitattributes (à commiter) et la définition dans .git/config (locale). Comme .git/hooks/ n'est jamais versionné, chaque clone relance graphify hook install une fois (idempotent, marqueurs graphify-hook-start/end). À documenter dans le README du repo.--force (ou GRAPHIFY_FORCE=1) écrase même si le nouveau graphe a moins de nœuds. Même chose après avoir durci le .graphifyignore : le rebuild affiche fail-closed: kept N node(s) … that left the scan corpus but still exist on disk et conserve les nœuds nouvellement exclus tant qu'on ne force pas.--watch (optionnel) : process de fond qui rebuild l'AST à chaque sauvegarde. Utile en workflow multi-agents où plusieurs agents écrivent en parallèle.⚠️ Savoir si la passe sémantique a réellement tourné
Piège coûteux, qui a déjà fait conclure à tort « le graphe est à jour, rien à faire » : un build AST fait apparaître des nœuds markdown. Ce ne sont pas des concepts extraits — ce sont les titres de sections parsés par tree-sitter (« Usage », « Step 1 - … »). Leur présence ne prouve rien sur la passe sémantique.
Le seul juge fiable est le champ _origin porté par chaque nœud de graph.json : en compter les valeurs suffit. Si le compteur rend {'ast': N} et rien d'autre, la passe sémantique n'a jamais tourné. Et un manifeste dépourvu de semantic_hash confirme ce diagnostic au lieu de le contredire : ce n'est pas un défaut d'enregistrement, c'est l'état réel.
Corollaire à retenir : graphify update . en CLI est toujours AST-only, quels que soient les fichiers modifiés — son propre message de fin le rappelle (« For doc/paper/image changes run /graphify --update in your AI assistant »). Seul /graphify . --update via l'assistant déclenche la passe sémantique.
En équipe : commiter le graphe, PAS l'état local. Seuls graph.json, GRAPH_REPORT.md et graph.html sont portables (chemins relatifs). Tout le reste de graphify-out/ est de l'état machine-local en chemins absolus (/Users/<name>/…) : manifest.json (cache de détection), cache/, les fichiers .graphify_*, cost.json, les snapshots datés AAAA-MM-JJ/. Poser un .gitignore dans graphify-out/ :
manifest.json
cache/
.graphify_*
cost.json
20*/
Trois choses à savoir :
grep -rl "$HOME" graphify-out/ --exclude-dir=cache doit sortir vide (hors .graphify_*)🔑 Changer de machine ne coûte rien — si on a commité le bon sous-ensemble
La question « si je change de machine, je dois tout regénérer ? » a une réponse nette : non, parce que les trois artefacts portables sont commités et lus tels quels. Ce qu'on évite ainsi, c'est de repayer la passe sémantique — la seule dépense réelle. L'AST, lui, se rebuild en quelques secondes gratuitement : il n'y a aucune raison de chercher à le préserver.
💡 Brancher le rafraîchissement sur un workflow spec-driven
En spec-driven (la spec écrite avant le code, ex. OpenSpec), le moment naturel pour la passe sémantique est la fin de feature : l'étape d'archive, quand les specs deviennent la vérité. Deux niveaux de branchement :
AGENTS.md / CLAUDE.md) du type « après un archive, lancer graphify . --update ».graphify --version (si absent, indiquer la commande d'install à l'utilisateur, sans installer un outil global à sa place).grep graphify-hook-start .git/hooks/post-commit, sinon graphify hook install (idempotent)./graphify . --update.
Le rafraîchissement devient une étape du workflow, impossible à oublier.Deux subtilités selon l'installation OpenSpec :
specs/ consolidé, les specs validées vivent dans changes/archive/<change>/specs/. Ré-inclure alors uniquement les spec.md d'archive (forme canonique du §4), en ré-excluant proposal.md, design.md et tasks.md : des délibérations, pas la vérité finale.Voir outiller-developpement-ia-skills-agents-instructions pour le levier « fichier d'instructions ».
⚠️ Le graphe à jour ≠ le graphe committé aveuglément
Sur Claude Code, écrire graphify-out/ dans le workspace invalide le prompt cache à chaque extraction. Choix binaire : soit .claudeignore, soit tu le commit pour l'équipe. Décide, pas les deux à moitié.
⚠ Ne pas confondre cet arbitrage avec la question du partage : l'invalidation du prompt cache concerne l'écriture pendant une session, pas le fait de commiter. Commiter le graphe et l'ignorer côté contexte ne sont pas exclusifs.
| Graphe (Graphify) | RAG vectoriel | |
|---|---|---|
| Trouve | relations structurelles (qui appelle quoi) | chunks sémantiquement proches |
| Question type | « quelles fonctions appellent cet endpoint ? » | « où parle-t-on d'authentification ? » |
| Mise à jour | incrémentale (sous-graphe touché) | ré-embedding |
| Multi-modal | code + doc + diagramme sur un même graphe | store plat |
| Coût tokens | faible (carte compacte) | variable |
Quand le choisir :
⚡ TL;DR — chaque concept en une ligne
Graphify ✓ Transforme un repo en graphe de connaissances que l'agent interroge au lieu de lire les fichiers. ⚠ C'est un skill pour assistant de code (CLI / IDE), pas pour un chat LLM classique.
Package graphifyy
✓ S'installe avec deux y sur PyPI ; la commande reste graphify.
⚠ Trois projets portent ce nom : le jQuery de 2015 (npm, un y) et surtout @sentropic/graphify (npm), un fork TypeScript légitime mais aux conventions incompatibles (.graphify/, Louvain). Chercher « graphify » sur npm mène au fork.
Init en IDE
✓ La passe sémantique utilise le modèle de ta session IDE, aucune clé API à poser.
⚠ En headless, seule la passe sémantique demande une clé : graphify extract --code-only tourne sans clé, 100 % offline.
--project sur Claude Code
✓ Dépose le skill dans .claude/skills/ pour le partager à l'équipe.
⚠ Touche aussi CLAUDE.md et .claude/settings.json, deux fichiers suivis par git. Et il faut exclure .claude/ dans le .graphifyignore, sinon le skill s'auto-indexe.
Économie de tokens ✓ ~71,5× moins de tokens par requête annoncé (sous-graphe borné vs lecture brute). ⚠ N'existe que si la couche always-on est installée : un graphe non consulté ne gagne rien.
Usage à la main vs via l'IA
✓ À la main : query / path / explain / affected. Via l'IA : tu discutes, le hook route vers le graphe.
⚠ Sans la couche always-on (§5), l'agent continue de grep et le bénéfice tokens disparaît.
Graphe à jour — deux vitesses
✓ Commit = rebuild AST-only auto (0 API) ; --update = passe sémantique sur les docs, à la main.
⚠ Le hook ne relance jamais le LLM ; et graphify update . en CLI est toujours AST-only. Vérifier par _origin.
Partage en équipe
✓ graph.json / GRAPH_REPORT.md / graph.html sont portables (chemins relatifs) et se commitent.
⚠ manifest.json, cache/, .graphify_*, cost.json = état local en chemins absolus : gitignore dédié dans graphify-out/, jamais commités.
🎓 À retenir
/graphify . --update manuel. Ne pas confondre._origin est le seul juge de la passe sémantique : des nœuds markdown ne prouvent rien, ce sont des titres de sections parsés par l'AST. {'ast': N} seul = la passe n'a jamais tourné, et un manifeste sans semantic_hash le confirme au lieu de l'infirmer.CLAUDE.md/AGENTS.md, hook PreToolUse, voire --strict sur Claude Code) qui fait que l'agent interroge le graphe au lieu de grep.SKILL.md de graphify lui-même s'y glissent sans qu'on le voie. Se lister et se peser au terminal, gratuitement.query traverse large ; --dfs trace un chemin, --budget N plafonne le coût..gitattributes se committe ; hooks et config restent locaux. Chaque clone relance graphify hook install une fois (git ne versionne jamais .git/hooks/, par conception).--force sert aussi après un changement d'ignore, pas seulement après un refactor : sans lui, le rebuild fail-closed conserve les nœuds qu'on vient d'exclure..graphify_* (chemins absolus, auto-régénérés) restent locaux. Un grep "$HOME" graphify-out/ avant commit coûte 2 s et évite de pousser son username à toute l'équipe.graphify-mcp).--strict, portabilité des chemins (fin des fuites username), sémantique des patterns ignore, écritures atomiques@sentropic/graphify sur npm) : crédite l'upstream, étend vers ontologies configurables et réconciliation d'entités--projectgraphify query