reading time: 12 minutes

Your codebase grows. Module dependencies multiply. Architecture documentation becomes obsolete before it’s even 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`transforms it into PlantUML diagrams. Zero LLM, zero manual work, 100% deterministic.

toc

[]

The problem: diagrams always lagging behind the code

Every project exceeding a few thousand lines experiences this syndrome:

  1. An architecture diagram is drawn at the start 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 rely on it and make mistakes

probleme diagrammes obsoletes

The question isn’t do we need diagrams? — everyone knows we do. The question is:who keeps them up to date?

The answer: nobody. Unless it’s automatic.

The solution: a deterministic Knowledge Graph → PlantUML pipeline

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

pipeline complet

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`diagrams/knowledge-graph/, versioned in Git, always in sync 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

Configuring exclusions

Create a`.graphifyignore`file at the project root 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/

Extracting the Knowledge Graph

graphify . --no-viz

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

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

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

  • Communities: automatic groupings of linked nodes

Example 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 LLM calls. Only documentation files (.adoc, .md) require an LLM call for semantic extraction. Therefore`--update`on Kotlin code is nearly instantaneous.

Step 2: The Gradle plugin transforms the Knowledge Graph into PlantUML

Pipeline architecture

The`com.cheroliv.plantuml`plugin integrates a`generateKnowledgeGraphDiagram`task that transforms`graph.json`into PlantUML diagrams in atotally deterministic manner:

architecture pipeline kg

Internal components

Component Role

KnowledgeGraphParser

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

KnowledgeGraphRenderer

Deterministically transforms a`KnowledgeGraph`into PlantUML code. Groups by type, communities into 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 plugin tasks).

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 be verified)

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

Step 3: Daily usage

Full 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 properties reference

Property Default Description

plantuml.kg.community

(all)

Filter communities by name (substring match)

plantuml.kg.edgeTypes

(all)

Comma-separated edge types:`EXTRACTED`, INFERRED, AMBIGUOUS

plantuml.kg.minConfidence

0.0

Minimum confidence threshold for edges

plantuml.kg.maxNodes

(unlimited)

Maximum number of nodes to display

plantuml.kg.nodeTypes

(all)

Comma-separated node types (e.g.class, code)

plantuml.kg.outputDir

diagrams/knowledge-graph

Output directory for`.puml` et .png

files

The complete pipeline in a Gradle workflow

workflow complet

Typical workflow

Integration into the development cycle

cycle developpement

The pipeline integrates naturally into key development stages:

Incremental update

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

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

`--update`When code changes, we don’t rebuild the entire graph from scratch:`graphify-out/cache/`re-extracts only modified files (detected by SHA256 in

). On Kotlin code, this is nearly instantaneous because tree-sitter works locally without LLM calls.

Dogfooding: the plugin documents itself

dogfooding pipeline

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.

Associated Gradle tasks: LLM ? Task

generateKnowledgeGraphDiagram

Description

Non`graph.json`Transforms

generateDiagramDocs

into PlantUML (deterministic)

Yes`.prompt`Generates

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

# Documentation LLM (plus riche, consomme des tokens)
./gradlew generateDiagramDocs

from the graph, processes them via LLM (dogfooding)

Why it’s deterministic (and why it matters)generateKnowledgeGraphDiagram`The key point of thepipeline:it makes no LLM calls`graph.json. The

determinisme vs llm

→ PlantUML transformation is a pure function.

Concrete advantages: Advantage

Impact

Reproducibility`graph.json`Same

→ same diagram. Exactly. Every time.

Zero cost

No LLM call = no tokens = no API bill.

Zero latency

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

CI Compatible

No API key required. No flaky tests due to variable LLM responses.

Le `.puml`Versionable`diff`generated is text. It can be

, reviewed in PR, versioned in Git.

Diagrams of the pipeline itself

pipeline sequence

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

Integration into project governance

strategie hybride

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 auto-updated graph.

  • The marriage of the two systems is complementary:The strategy manages the WHEN and the HOW

  • — governance, workflow, archivingGraphify manages the WHAT and the WHERE

— code structure, relations, targeted queries __The session strategy manages the et le WHENHOW(governance, workflow, thresholds), Graphify manages the et le WHATWHERE(code structure, relations, targeted queries). The PlantUML pipeline manages theWITH WHAT (deterministic, versioned, always up-to-date diagrams).

__

Setup: 5-minute checklist # Step

1

Command

uv tool install graphifyy

2

Install Graphify

Configure exclusions`.graphifyignore`

3

Create

graphify . --no-viz

4

Extract Knowledge Graph

./gradlew generateKnowledgeGraphDiagram

5

Generate diagrams

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/

Commit results

Pitfalls and mitigations Pitfall Description

Mitigation

Graph too dense

A large project generates hundreds of unreadable nodes`-Pplantuml.kg.maxNodes=30`Use

and filter by community

Exclusions too broad`.graphifyignore`Too many files in

reduces the graph’s value

Start by excluding only credentials and build

Arrow direction

INFERRED edges may have an ambiguous direction`-Pplantuml.kg.edgeTypes=EXTRACTED`Filter by

for certain relations only

Obsolete graph

Code changes but the graph is not rebuilt`graphify . --update`Use`graphify hook install`

regularly or the git hook

Update cost

Incremental updates are nearly free (local tree-sitter)`.adoc`Only docs (

) consume LLM tokens

recap visuel

What we get in the end

Concrete benefits: Benefit

Detail

Documentation always up to date

Diagrams reflect current code, not a manual snapshot

Zero maintenance effort

Diagrams regenerate on every build

Reduction of technical debt

No more maintaining diagrams by hand

Visual context for newcomers

A new developer understands the architecture by looking at the diagrams

Potential fine-tuning

(sub-graph → diagram) pairs are AI training examples

`PlantumlService.validateSyntax()`Automatic validation

verifies each generated diagram

Fast onboarding

5 diagrams = complete view of the architecture __ He who has a why can bear almost any how.

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

Related articles