reading time : 12 minutes

Your codebase is growing. Dependencies between modules are multiplying. Architecture documentation becomes obsolete even before it’s written. What if your Gradle build could automatically generate up-to-date diagrams from the actual code structure? That’s exactly what the Graphify + PlantUML Gradle Plugin pipeline does:`graphify . --no-viz`extracts the Knowledge Graph,`./gradlew generateKnowledgeGraphDiagram`turns it into PlantUML diagrams. Zero LLM, zero manual, 100% deterministic.

tic

[]

The problem: diagrams always lagging behind the code

Any project that exceeds a few thousand lines knows this syndrome:

  1. We draw an architecture diagram at the beginning of the project

  2. The code evolves, dependencies change

  3. The diagram becomes a decorative lie

  4. Nobody updates it because it’s tedious.

  5. Newcomers base themselves on it and make mistakes

@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #FDEDEC
skinparam ActivityDiamondBackgroundColor #FFF3CD

start

:Diagramme d'architecture créé\n(manuellement, à la main);

:Le code évolue\n(nouvelles classes, nouvelles dépendances);

:Diagramme obsolète\n(ne reflète plus le code);

if (Qui met à jour ?) then (Personne)
    :Documentation mensongère;
    note right: Les nouveaux développeurs\nse basent dessus... et font des erreurs
else (Quelqu'un)
    :Mise à jour manuelle\n(2-3 heures de travail);
    note right: Déjà obsolète\nà la prochaine PR
endif

stop

@enduml

The question is not should there be diagrams? — everyone knows that yes. The question is:who keeps them up to date?

The answer: nobody. Unless it’s automatic.

The solution : a deterministic pipeline Knowledge Graph → PlantUML

The principle is simple: instead of drawing the diagrams by hand, we themgenerates from the actual code structure.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

actor Développeur
component "Graphify\n(pip install graphifyy)" as Graphify
collections "graphify-out/graph.json\n(Knowledge Graph)" as KGJSON
component "PlantUML Gradle Plugin\n(generateKnowledgeGraphDiagram)" as Plugin
component "KnowledgeGraphParser" as Parser
component "KnowledgeGraphRenderer" as Renderer
component "PlantumlService\n(validation + PNG rendering)" as PS
collections "diagrams/knowledge-graph/\n(.puml + .png)" as Output

Développeur --> Graphify : graphify . --no-viz
Graphify --> KGJSON : extrait la structure\ndu code source
Développeur --> Plugin : ./gradlew generateKnowledgeGraphDiagram
Plugin --> Parser : parse(graph.json)
Parser --> Plugin : KnowledgeGraph\n(noeuds + arêtes + communautés)
Plugin --> Renderer : render(graph, filters)
Renderer --> Plugin : code PlantUML\ndéterministe
Plugin --> PS : validateSyntax + generateImage
PS --> Output : .puml + .png

note bottom of Plugin
  Pipeline DÉTERMINISTE
  Aucun appel LLM
  Résultat reproductible
end note

@enduml

Two commands. That’s it.

# Étape 1 : extraire le Knowledge Graph
graphify . --no-viz

# Étape 2 : générer les diagrammes PlantUML
./gradlew generateKnowledgeGraphDiagram

The result? Files`.puml` et .png`in </output>`diagrams/knowledge-graph/, versioned in Git, always up to date with the code.

Step 1: Install Graphify and extract the Knowledge Graph

Installation

Graphify is a Python tool that analyzes your codebase and builds a structured knowledge graph:

# Méthode recommandée
uv tool install graphifyy && graphify install --platform opencode

# Alternative avec pip
pip install graphifyy && graphify install --platform opencode

Configure exclusions

Create a file`.graphifyignore`at the root of the project to exclude files that are not part of the business logic:

# Secrets — JAMAIS dans le graphe
*-context.yml
*.env

# Fichiers générés
build/
.gradle/

# Tests fonctionnels
src/functionalTest/

Extract the Knowledge Graph

graphify . --no-viz

The flag`--no-viz`skips HTML generation (useless in a Gradle pipeline). The result is a file`graphify-out/graph.json`containing:

  • Nodes: classes, functions, files — with their type and community

  • Edges: relations between nodes (EXTRACTED from the code, INFERRED by the LLM)

  • Communities: automatic groupings of linked nodes

Exemple de structure → .Example of structure

But must output only translated text:

Example of structure`graph.json`
{
  "nodes": [
    {"id": "0", "label": "LlmService", "file_type": "code", "community": 0},
    {"id": "1", "label": "ApiKeyPool", "file_type": "code", "community": 0},
    {"id": "2", "label": "PlantumlService", "file_type": "code", "community": 1}
  ],
  "links": [
    {"source": "1", "target": "0", "relation": "uses", "confidence": "EXTRACTED", "weight": 0.9},
    {"source": "0", "target": "2", "relation": "calls", "confidence": "INFERRED", "weight": 0.7}
  ]
}

The source code (.kt, .java) is analyzed locally by tree-sitter,without appeal LLM. Only documentation files (.adoc, .md) require an LLM call for semantic extraction. So`--update`on the Kotlin code is nearly instantaneous

Step 2: The Gradle plugin converts the Knowledge Graph to PlantUML

@startuml
skinparam backgroundColor #FEFEFE

participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS

collections "graphify-out/graph.json" as JSON

G -> Task : execute
Task -> JSON : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph\n(noeuds + arêtes + communautés)
Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML\n(déterministe)
Task -> PS : validateSyntax(plantumlCode)
alt syntaxe valide
    Task -> PS : generateImage → .png
else syntaxe invalide
    Task -> Task : save .puml avec warning
end

@enduml

The plugin`com.cheroliv.plantuml`integrates a task`generateKnowledgeGraphDiagram`which transforms`graph.json`in PlantUML diagrams in a waytotally deterministic:

@startuml
skinparam backgroundColor #FEFEFE

participant "Gradle
has" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS

collections "graphify-out/graph.json" as JSON

G -> Task : execute
Task -> JSON : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph\n(noeuds + arêtes + communautés)
Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML\n(déterministe)
Task -> PS : validateSyntax(plantumlCode)
alt syntaxe valide
    Task -> PS : generateImage → .png
else syntaxe invalide
    Task -> Task : save .puml avec warning
end

@enduml

The internal components

Component Role

KnowledgeGraphParser

Parse`graph.json`— supports 3 formats: native graphify (nodes+links), legacy (communities), flat. Resolves numeric IDs to labels.

KnowledgeGraphRenderer

Transform deterministically a`KnowledgeGraph`in PlantUML code. Groups by type, communities in packages, automatic legend.

GenerateKnowledgeGraphDiagramTask

Gradle task that orchestrates: parse → render → validate → PNG. Configurable via Gradle properties.

kgmodels.kt

Data models:`KnowledgeGraph`, KnowledgeGraphNode, KnowledgeGraphEdge, KnowledgeGraphCommunity, EdgeType.

PlantumlService

Syntax validation + PNG rendering (reused by all tasks of the plugin).

Rendering rules

The renderer applies deterministic visual conventions:

Edge type PlantUML notation Meaning

extracted

-→(solid line, black)

Relation extracted from source code (certainty)

INFERRED

..>(dotted line)

Relation inferred by the LLM (confidence score)

AMBIGUOUS

--x(dotted red line)

Ambiguous relation (to verify)

Communities are rendered as PlantUML packages with an automatic color palette.

Step 3: Daily Use

Complete diagram

# Générer le diagramme du Knowledge Graph complet
./gradlew generateKnowledgeGraphDiagram

Output:`diagrams/knowledge-graph/knowledge-graph-full.puml`+.png

Filter by community

# Une seule communauté
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.community=community_0

# Limiter le nombre de noeuds (lisibilité)
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.community=community_0 \
  -Pplantuml.kg.maxNodes=15

Filter by edge type

# Uniquement les relations certaines (EXTRACTED)
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.edgeTypes=EXTRACTED

# Relations certaines + inférées
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.edgeTypes=EXTRACTED,INFERRED

Filter by node type and confidence

# Uniquement les classes de code
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.nodeTypes=code

# Seuil de confiance minimum (pour les INFERRED)
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.minConfidence=0.7

Custom output directory

./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.outputDir=docs/architecture

Complete reference of properties

Property Default Description

plantuml.kg.community

(all)

Filter communities by name (substring match)

plantuml.kg.edgeTypes

(all)

Edge types separated by commas :`EXTRACTED`, INFERRED, AMBIGUOUS

plantuml.kg.minConfidence

0.0

Minimum confidence threshold for the edges

plantuml.kg.maxNodes

(unlimited)

Maximum number of nodes to display

plantuml.kg.nodeTypes

(all)

Types of nodes separated by commas (ex.class, code)

plantuml.kg.outputDir

diagrams/knowledge-graph

Output directory for the files`.puml` et .png

@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #E8F4FD
skinparam ActivityDiamondBackgroundColor #FFF3CD
skinparam ActivityBorderColor #2C3E50

start

partition "EXTRACTION" {
    :graphify . --no-viz;
    note right: Analyse le code source\ntree-sitter (local, pas de LLM)

    :graphify-out/graph.json;
    note right: Noeuds + arêtes\n+ communautés
}

partition "GENERATION" {
    :./gradlew generateKnowledgeGraphDiagram;
    note right: Pipeline déterministe\nparse → render → validate → PNG

    if (Filtres actifs ?) then (Oui)
        :Appliquer filtres\n(community, edgeTypes,\nmaxNodes, nodeTypes);
    else (Non)
        :Diagramme complet;
    endif

    :diagrams/knowledge-graph/\nknowledge-graph-full.puml\nknowledge-graph-full.png;
}

partition "INTEGRATION" {
    :git add diagrams/knowledge-graph/;
    :git commit;
    note right: Diagrammes versionnés\ntoujours à jour avec le code
}

stop

@enduml

Workflow type

@startuml
skinparam backgroundColor #FEFEFE
skinparam ActivityBackgroundColor #E8F4FD
skinparam ActivityDiamondBackgroundColor #FFF3CD
skinparam ActivityBorderColor #2C3E50

start

partition "EXTRACTION" {
    :graphify . --no-viz;
    note right: Analyse le code source\ntree-sitter (local, pas de LLM)

    :graphify-out/graph.json;
    note right: Noeuds + arêtes\n+ communautés
}

partition "GENERATION" {
    :./gradlew generateKnowledgeGraphDiagram;
    note right: Pipeline déterministe\nparse → render → validate → PNG

    if (Filtres actifs ?) then (Oui)
        :Appliquer filtres\n(community, edgeTypes,\nmaxNodes, nodeTypes);
    else (Non)
        :Diagramme complet;
    endif

    :diagrams/knowledge-graph/\nknowledge-graph-full.puml\nknowledge-graph-full.png;
}

partition "INTEGRATION" {
    :git add diagrams/knowledge-graph/;
    :git commit;
    note right: Diagrammes versionnés\ntoujours à jour avec le code
}

stop

@enduml
@startuml
skinparam backgroundColor #FEFEFE

state "Development" as dev
state "Extraction\ngraphify . --no-viz" as extract
state "Generation\n./gradlew generateKnowledgeGraphDiagram" as generate
state "Commit\nversioned diagrams" as commit

[*] --> dev
dev --> extract : Code modifié
extract --> generate : graph.json à jour
generate --> commit : .puml + .png générés
commit --> dev : Diagrammes dans le repo

note right of extract
  Quasi instantané sur du code Kotlin
  (tree-sitter, pas de LLM)
end note

note right of generate
  Déterministe
  Pas de LLM
  Résultat reproductible
end note

@enduml

The pipeline integrates naturally into the key stages of development:

@startuml
skinparam backgroundColor #FEFEFE

state "Development" as dev
state "Extraction
graphify . --no-viz" as extract
state "Generation
./gradlew generateKnowledgeGraphDiagram" as generate
state "Commit
versioned diagrams" as commit

[*] --> dev
dev --> extract : Code modifié
extract --> generate : graph.json à jour
generate --> commit : .puml + .png générés
commit --> dev : Diagrammes dans le repo

note right of extract
  Quasi instantané sur du code Kotlin
  (tree-sitter, pas de LLM)
end note

note right of generate
  Déterministe
  Pas de LLM
  Résultat reproductible
end note

@enduml

Incremental update

When the code changes, we do not rebuild the entire graph from scratch:

# Mise à jour incrémentale (fichiers modifiés uniquement)
graphify . --update

# Puis régénérer les diagrammes
./gradlew generateKnowledgeGraphDiagram

--update`re-extracts only the modified files (detected by SHA256 in`graphify-out/cache/) On Kotlin code, this is nearly instantaneous because tree-sitter works locally without an LLM call.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Normal pipeline\n(user → diagrams)" as normal {
    [Fichier .prompt] as prompt
    [LlmService\n+ ApiKeyPool] as llm1
    [ProcessPlantumlPromptsTask] as task1
    [Diagramme PNG] as out1

    prompt --> task1
    task1 --> llm1
    llm1 --> out1
}

package "Knowledge Graph pipeline\n(deterministic, no LLM)" as kg {
    [graphify-out/graph.json] as kgjson
    [KnowledgeGraphParser] as parser
    [KnowledgeGraphRenderer] as renderer
    [PlantumlService] as ps
    [Diagramme PNG\n(documentation du plugin)] as out2

    kgjson --> parser
    parser --> renderer
    renderer --> ps
    ps --> out2
}

package "Dogfooding pipeline\n(LLM → plugin documentation)" as dogfood {
    [GraphifyPromptAdapter] as gpa
    [Fichiers .prompt\nauto-générés] as auto_prompt
    [LlmService\n+ ApiKeyPool] as llm2
    [ProcessPlantumlPromptsTask] as task2
    [Diagramme PNG\n(documentation LLM)] as out3

    kgjson --> gpa
    gpa --> auto_prompt
    auto_prompt --> task2
    task2 --> llm2
    llm2 --> out3
}

note "Same LlmService, same ApiKeyPool,\nsame PlantumlService\n— ZERO duplication" as N

@enduml

The PlantUML plugin exists to transform prompts into diagrams. It can also transform the Knowledge Graph of its own codebase into documentation diagrams. This is dogfooding : the plugin consumes its own service.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Normal pipeline
(user → diagrams)" as normal {
    [Fichier .prompt] as prompt
    [LlmService\n+ ApiKeyPool] as llm1
    [ProcessPlantumlPromptsTask] as task1
    [Diagramme PNG] as out1

    prompt --> task1
    task1 --> llm1
    llm1 --> out1
}

package "Pipeline Knowledge Graph
(deterministic, no LLM)" as kg {
    [graphify-out/graph.json] as kgjson
    [KnowledgeGraphParser] as parser
    [KnowledgeGraphRenderer] as renderer
    [PlantumlService] as ps
    [Diagramme PNG\n(documentation du plugin)] as out2

    kgjson --> parser
    parser --> renderer
    renderer --> ps
    ps --> out2
}

package "Pipeline Dogfooding
(LLM → plugin documentation)" as dogfood {
    [GraphifyPromptAdapter] as gpa
    [Fichiers .prompt\nauto-générés] as auto_prompt
    [LlmService\n+ ApiKeyPool] as llm2
    [ProcessPlantumlPromptsTask] as task2
    [Diagramme PNG\n(documentation LLM)] as out3

    kgjson --> gpa
    gpa --> auto_prompt
    auto_prompt --> task2
    task2 --> llm2
    llm2 --> out3
}

note "Same LlmService, same ApiKeyPool,
same PlantumlService
— ZERO duplication" as N

@enduml

Associated Gradle tasks :

Task LLM ? Description

generateKnowledgeGraphDiagram

No

Transform`graph.json`in PlantUML (deterministic)

generateDiagramDocs

Yes

Generate some`.prompt`from the graph, processes them via LLM (dogfooding)

# Documentation déterministe (rapide, pas de LLM)
./gradlew generateKnowledgeGraphDiagram

# Documentation LLM (plus riche, consomme des tokens)
./gradlew generateDiagramDocs
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

rectangle "DETERMINISTIC Pipeline\n(generateKnowledgeGraphDiagram)" as det {
    [graph.json] as json
    [KnowledgeGraphParser] as parser
    [KnowledgeGraphRenderer] as renderer
    [PlantUML code] as puml

    json --> parser : parse
    parser --> renderer : KnowledgeGraph
    renderer --> puml : render (fonction pure)
}

rectangle "LLM Pipeline\n(processPlantumlPrompts)" as llm {
    [.prompt] as prompt
    [LlmService] as llmSvc
    [ChatModel] as model
    [PlantUML code] as puml2

    prompt --> llmSvc
    llmSvc --> model : API call
    model --> puml2 : réponse non-déterministe
}

note bottom of det
  Même entrée → même sortie
  Pas de latence réseau
  Pas de coût en tokens
  Reproductible en CI
end note

note bottom of llm
  Même entrée → sortie variable
  Latence réseau (1-5s)
  Coût en tokens
  Nécessite une clave API
end note

@enduml

The key point of the pipeline`generateKnowledgeGraphDiagram`:it does not call any LLM. The transformation`graph.json`→ PlantUML is a pure function.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

rectangle "Deterministic Pipeline
(generateKnowledgeGraphDiagram)" as det {
    [graph.json] as json
    [KnowledgeGraphParser] as parser
    [KnowledgeGraphRenderer] as renderer
    [PlantUML code] as puml

    json --> parser : parse
    parser --> renderer : KnowledgeGraph
    renderer --> puml : render (fonction pure)
}

rectangle "Pipeline LLM
(processPlantumlPrompts)" as llm {
    [.prompt] as prompt
    [LlmService] as llmSvc
    [ChatModel] as model
    [PlantUML code] as puml2

    prompt --> llmSvc
    llmSvc --> model : API call
    model --> puml2 : réponse non-déterministe
}

note bottom of det
  Même entrée → même sortie
  Pas de latence réseau
  Pas de coût en tokens
  Reproductible en CI
end note

note bottom of llm
  Même entrée → sortie variable
  Latence réseau (1-5s)
  Coût en tokens
  Nécessite une clave API
end note

@enduml

The concrete benefits:

Advantage Impact

Reproducibility

same`graph.json`→ same diagram. Exactly. Every time.

Zero cost

No LLM call = no tokens = no API invoice

Zero latency

Parse + render takes ~100ms, not 1-5 seconds.

CI-compatible

No API key required. No flaky test due to a variable LLM response.

Versionable

Le .puml`generated is text. We can it`diff, the PR reviewer, to version it in Git

@startuml
skinparam backgroundColor #FEFEFE

participant "Developer" as Dev
participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS
collections "graphify-out/graph.json" as JSON
collections "diagrams/knowledge-graph/" as Out

Dev -> G : ./gradlew generateKnowledgeGraphDiagram
G -> Task : execute
Task -> JSON : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph

alt filtres actifs
    Task -> Task : appliquer filtres\n(community, edgeTypes, maxNodes…)
end

Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML

Task -> PS : validateSyntax()
alt valide
    Task -> PS : generateImage()
    PS --> Out : .puml + .png
else invalide
    Task -> Out : .puml (avec warning)
end

@enduml

To close the loop, here is the pipeline diagram as it would be generated by the plugin:

@startuml
skinparam backgroundColor #FEFEFE

participant "Developer" as Dev
participant "Gradle" as G
participant "GenerateKnowledgeGraphDiagramTask" as Task
participant "KnowledgeGraphParser" as Parser
participant "KnowledgeGraphRenderer" as Renderer
participant "PlantumlService" as PS
collections "graphify-out/graph.json" as JSON
collections "diagrams/knowledge-graph/" as Out

Dev -> G : ./gradlew generateKnowledgeGraphDiagram
G -> Task : execute
Task -> JSON : read
Task -> Parser : parse(graph.json)
Parser --> Task : KnowledgeGraph

alt filtres actifs
    Task -> Task : appliquer filtres\n(community, edgeTypes, maxNodes…)
end

Task -> Renderer : render(graph, filters)
Renderer --> Task : code PlantUML

Task -> PS : validateSyntax()
alt valide
    Task -> PS : generateImage()
    PS --> Out : .puml + .png
else invalide
    Task -> Out : .puml (avec warning)
end

@enduml
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "EAGER\n(always loaded)" as eager {
    [PROMPT_REPRISE.adoc\n(contexte session)] as pr
    [INDEX.adoc\n(vue d'ensemble)] as idx
    [GRAPH_REPORT.adoc\n(~50 lignes)] as gr
}

package "LAZY — Strategy\n(on demand)" as lazy_strat {
    [Méthodologies] as meth
    [Archives sessions] as sessions
}

package "LAZY — Graphify\n(targeted queries)" as lazy_graph {
    [graph.json] as gj
    [Queries\n(query/path/explain)] as queries
}

package "PlantUML Pipeline\n(auto-generated)" as puml {
    [generateKnowledgeGraphDiagram] as kgTask
    [generateDiagramDocs] as ddTask
    [Diagrammes PNG] as diagrams
}

Agent --> eager : Lit en début de session
Agent ..> lazy_strat : Charge si type détecté
Agent ..> lazy_graph : Query si besoin structurel
kgTask --> diagrams : Déterministe
ddTask --> diagrams : Via LLM

note right of gr
  Condensé du Knowledge Graph
  God nodes + communautés
  Remplace ECOSYSTEM_OVERVIEW
  (225 lignes → 50 lignes)
end note

@enduml

In our project, this pipeline integrates into an EAGER/LAZY context management strategy for the AI agent. The Knowledge Graph replaces manual architecture documentation with a structured, queryable, and automatically updated graph.

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "EAGER
(always charged)" as eager {
    [PROMPT_REPRISE.adoc\n(contexte session)] as pr
    [INDEX.adoc\n(vue d'ensemble)] as idx
    [GRAPH_REPORT.adoc\n(~50 lignes)] as gr
}

package "LAZY — Strategy\n(on demand)" as lazy_strat {
    [Méthodologies] as meth
    [Archives sessions] as sessions
}

package "LAZY — Graphify
(targeted queries)" as lazy_graph {
    [graph.json] as gj
    [Queries\n(query/path/explain)] as queries
}

package "Pipeline PlantUML\n(auto-generated)" as puml {
    [generateKnowledgeGraphDiagram] as kgTask
    [generateDiagramDocs] as ddTask
    [Diagrammes PNG] as diagrams
}

Agent --> eager : Lit en début de session
Agent ..> lazy_strat : Charge si type détecté
Agent ..> lazy_graph : Query si besoin structurel
kgTask --> diagrams : Déterministe
ddTask --> diagrams : Via LLM

note right of gr
  Condensé du Knowledge Graph
  God nodes + communautés
  Remplace ECOSYSTEM_OVERVIEW
  (225 lignes → 50 lignes)
end note

@enduml

The marriage of the two systems is complementary:

  • The strategy manages WHEN and HOW— governance, workflow, archiving

  • Graphify handles the WHAT and the WHERE— code structure, relationships, targeted queries

_ The session strategy manages theWHEN et le comment(governance, workflow, thresholds), Graphify manages theWHAT et le where(code structure, relationships, targeted queries). The PlantUML pipeline handles theWITH WHAT(deterministic diagrams, versioned, always up-to-date) _

Setup: 5‑minute checklist

# Step Order

1

Install Graphify

uv tool install graphifyy

2

Configure the exclusions

Create`.graphifyignore`

3

Extract the Knowledge Graph

graphify . --no-viz

4

Generate the diagrams

./gradlew generateKnowledgeGraphDiagram

5

Commit the results

git add diagrams/knowledge-graph/

# Script complet en 5 commandes
uv tool install graphifyy
cat > .graphifyignore << 'EOF'
*-context.yml
*.env
build/
.gradle/
EOF
graphify . --no-viz
./gradlew generateKnowledgeGraphDiagram
git add graphify-out/GRAPH_REPORT.adoc graphify-out/graph.json diagrams/knowledge-graph/

Pitfalls and mitigations

@startuml
skinparam backgroundColor #FEFEFE

rectangle "BEFORE" as avant {
    card "Hand-drawn diagrams\nAlways outdated\nNo one updates them" as av1 #FDEDEC
}

rectangle "AFTER" as apres {
    card "Automatically generated diagrams\nAlways up to date with the code\nVersioned in Git\nDeterministic and reproducible" as ap1 #E8F8E8
}

avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram

@enduml

What you get in the end

@startuml
skinparam backgroundColor #FEFEFE

rectangle "BEFORE" as avant {
    card "Hand-drawn diagrams
Always outdated
No one updates them" as av1 #FDEDEC
}

rectangle "AFTER" as apres {
    card "Automatically generated diagrams
Always up to date with the code
Versioned in Git
Deterministic and reproducible" as ap1 #E8F8E8
}

avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram

@enduml

The concrete benefits:

Profit Detail

Documentation always up to date

The diagrams reflect the current code, not a manual snapshot

Zero maintenance effort

The diagrams are regenerated on each build

Technical debt reduction

No need to maintain diagrams by hand

Visual context for the newcomers

A new developer understands the architecture by examining the diagrams.

Potential fine-tuning

The pairs (subgraph → diagram) are examples of AI training.

Automatic validation

`PlantumlService.validateSyntax()`checks each generated diagram

Rapid onboarding

5 diagrams = complete view of the architecture

_ He who has a _why can bear all the how_s. _

The why : diagrams always up to date. The how : two commands in a Gradle pipeline.

Related articles