tempo di lettura : 14 minutes

Per mesi, ho accumulato le regole di governance degli agenti. Alcuni file EAGER, liste di controllo LAZY, protocolli di fine sessione in sei fasi. E tuttavia, una domanda rimaneva in sospeso : come il LLM sa ciò che ha il diritto di fare con un file?*

JBake CLI Commands ` # Initialize a new JBake project jbake -i

Bake (generate) the site jbake -b

Bake and serve locally jbake -b -s

Bake and watch for changes jbake -b --reset

Specify source and destination jbake source_folder output_folder

Clear the output directory before baking jbake -b . output --reset `

La risposta non è in un prompt. È nel sistema di file.

Ecco la specifica di architettura che rende la risposta sfruttabile — la matrice di governance LLM.

Il Problema : il Prompt Engineering è un Castello di sabbia

Quando si dà un file a un LLM, gli si dà tutto. Il contenuto, sì — ma anche l’assenza di salvaguardie. Il LLM non sa se questo file contiene un segreto, un’opinione speculativa o del codice closed source. Lo indicizzerà, riassumerlo, citarlo, mescolarlo con altri dati — e potenzialmente pubblicarlo in un embedding pubblico o un utente

La parata classica, è il prompt :

"Tu es un assistant sécurisé. Ne divulgue jamais d'informations confidentielles.
Si tu détectes un secret, ignore-le. Si tu détectes une opinion, ne la répète pas."

Questo prompt ha tre problemi:

  1. Si basa sulla buona volontà del LLM. Un modello abbastanza grande per

risolvere bug complessi è abbastanza grande per aggirare un’istruzione di sicurezza sommerse in 200k token di contesto

  1. # Comandi CLI di JBake

----
# Initialize a new JBake project
jbake -i

# Bake (generate) the site
jbake -b

# Bake and serve locally
jbake -b -s

# Bake and watch for changes
jbake -b --reset

# Specify source and destination
jbake source_folder output_folder

# Clear the output directory before baking
jbake -b . output --reset
----

*È contestuale, non strutturale.* Cambiate prompt, cambiate LLM,

cambia sessione — e la regola scompare.

1. *Non scala.* Ogni nuovo tipo di file, ogni nuovo livello

di riservatezza richiede una nuova clausola. Il tuo prompt diventa un testo normativo che nessuno legge per intero.

[CAUTION]
====
La sicurezza di un sistema non deve mai dipendere da un'istruzione che si Può dimenticare, bypassare o non caricare. Lei deve dipendere da una barriera che non si può superare senza volerlo esplicitamente.
====

== La mia risposta: la matrice 4×4

La soluzione che ho implementato nel mio workspace è una **matrice zona × diritto di accesso LLM**. Non chiede al LLM di essere prudente. Ella rende l'imprudenza strutturalmente impossibile.

[plantuml, format=svg, id=diag-matrix-overview, alt="Vue d'ensemble de la matrice de gouvernance LLM — 5 zones × 4 droits d'accès"]
----
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam wrapWidth 220

title La Matrice di Governance LLM — Zona × Diritto di Accesso
package "area di lavoro" {

  rectangle "RADICE
(Cerchio 0)
━━━━━━
Brain dump
Pensiero libero
[INTERDITTO LLM]" as Z0 #FFB3B3
  rectangle "configuration/
(Cerchio 1)
━━━━━━
Secrets, tokens
Infra privata
[VIETATO LLM]" as Z1 #FFB3B3
  rectangle "office/\n(Cerchio 2)\n━━━━━━\nData editoriale\nArticoli, inquadrature\n[Visione filtrata]" as Z2 #FFF3B3
  rectangle "foundry/private/
(Cerchio 3)
━━━━━━
Code closed source
[DATASET PRIVATO]" as Z3 #B3D9FF
  rectangle "foundry/public/
(Cerchio 3)
━━━━━━
Codice open source
Apache 2.0
[ACCESSO LIBRE]" as Z4 #B3FFB3

}

Z0 -[hidden]-> Z1
Z1 -[hidden]-> Z2
Z2 -[hidden]-> Z3
Z3 -[hidden]-> Z4

@enduml
----

=== Le Cinque Zone (Dimensione Spaziale — RGPD)

Ogni zona del workspace ha un livello RGPD che determina *dove* il file può essere instradato :

|===
|Zona |Livello GDPR |Contenuto |Diritto di accesso RAG pubblico |Radice |0 — Intimo |Brain dumps, conversazioni LLM |**PROIBITO**— mai indicizzato |`configuration/` |1 — Proprietario limitato |Segreti, token, chiavi API |**vietato**— mai indicizzato |`office/` |2 — Collaborativo ristretto |Data editoriale, inquadratura, formazione |**FILTRATO**— Solo visione |`foundry/private/` |3 — Aperto condizionale |Codice sorgente chiuso, SaaS non pubblico |**VIETATO**— dataset privato esclusivamente |`foundry/public/` |4 — Pubblico nativo |Codice Apache 2.0, plugin pubblicati |**libero**— indicizzazione completa
|===

La regola è semplice : *il percorso del file determina ciò che il LLM può farne.* Nessun metadato da mantenere, nessun tag da aggiungere nel frontmatter, Nessuna classificazione manuale ad ogni commit. Il file è dentro`OSS/`? È pubblico. È in`configuration/`? È intoccabile.

=== La classificazione epistemica (seconda dimensione)

La dimensione spaziale dice *dove* instradare. Ma c'è un secondo asse, perpendicolare: *che cosa* router. Alcuni file in una zona autorizzata contengono informazioni che non dovrebbero essere diluite tali quali:

[plantuml, format=svg, id=diag-epistemic-filter, alt="Filtre épistémique Vision/Opinion/Stratégie appliqué aux zones 2 et 3"]
----
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam wrapWidth 240

title La Doppia Cascata — Filtro Spaziale + Filtro Epistemico
start

:Le LLM rencontre un fichier;

if (Zone physique ?) then (Cercle 0-1)
  :ACCÈS BLOQUÉ\n(secret, brain dump);
  stop
elseif (Zone CSS/)
  :DROIT D'ACCÈS PRIVÉ\n→ dataset fine-tuning;
  :Filtre épistémique\nVision/Opinion;
  if (Classification ?) then (VISION)
    :Dataset privé\n→ entraînement autorisé;
  else (OPINION)
    :CONFINÉ\n→ pas d'entraînement;
  endif
elseif (Zone office/)
  :DROIT D'ACCÈS FILTRÉ\n→ accès conditionnel;
  :Filtre épistémique\nVision/Opinion/Stratégie;
  if (Classification ?) then (VISION)
    :DILUTION COMPLÈTE\n→ docs racine + blog;
  elseif (STRATÉGIE)
    :DILUTION RESTREINTE\n→ docs racine seulement;
  else (OPINION)
    :CONFINEMENT\n→ office/ uniquement;
  endif
else (Zone OSS/)
  :ACCÈS LIBRE\n→ indexation complète;
endif

stop

@enduml
----

La griglia di classificazione epistemica, incisa nella Regola 2bis della mia governance agente :

### JBake CLI Commands ``` # Initialize a new JBake project jbake -i

# Bake (generate) the site jbake -b

# Bake and serve locally jbake -b -s

# Bake and watch for changes jbake -b --reset

# Specify source and destination jbake source_folder output_folder

# Clear the output directory before baking jbake -b . output --reset ```

| Stato | Definizione | Segnale LLM | Destinazione | | VISION | Architettura stabilizzata, pattern testato | Linguaggio dichiarativo, riferimenti sessioni/test | Diluzione completa + Blog | | STRATEGIA | Posizionamento business, pricing | Vocabolario mercato, concorrenza | Documenti radice esclusivamente | | OPINION | Speculazione, ipotesi non validata | Linguaggio ipotetico, intuizione | Confinamento Cerchio 0 |

La combinazione delle due dimensioni — zona fisica × classificazione epistemica — forma la**matrice completa**:

[plantuml, format=svg, id=diag-full-matrix, alt="La matrice complète : 5 zones × 3 classifications épistémiques"]
----
@startuml
skinparam backgroundColor #FEFEFE

title La Matrice Completa — Zone × Classificazione
salt
{
{T
+ Zone | VISION | STRATÉGIE | OPINION
+ Racine (0) | ✗ Interdit | ✗ Interdit | ✗ Interdit
+ configuration/ (1) | ✗ Interdit | ✗ Interdit | ✗ Interdit
+ office/ (2) | ✓ Docs + Blog | ✓ Docs seulement | ✗ Confiné
+ CSS/ (3) | ✓ Dataset privé | ✓ Dataset privé | ✗ Confiné
+ OSS/ (4) | ✓ Public libre | ✓ Public libre | ✓ Public libre
}
}

@enduml
----

== Come il LLM consuma questa matrice

La matrice non è un documento che il LLM legge. È un **vincolo implicita** codificata nel vettore composto di contesto (EPIC 9 — in corso di implementazione)

Ecco ciò che il LLM riceve ad ogni sessione:

[source]
----
VECTEUR COMPOSITE DE CONTEXTE
├── RAG pgvector → OSS/ + office/Vision
│   (similarité sémantique sur contenu publiable)
├── Knowledge Graph graphify → OSS/
│   (relations exactes entre artéfacts publics)
├── Knowledge Graph privé → CSS/
│   (relations entre code closed source — jamais exporté)
├── Métadonnées de zone → chaque fichier taggé par zone physique
│   (le LLM sait s'il est dans office/ ou OSS/)
└── Historique des décisions → WORKSPACE_VISION.adoc
    (contexte temporel des arbitrages)
----

Concretamente, quando il LLM mi dice :

[source,text]
----
Je vais indexer le contenu de edster/ pour enrichir le knowledge graph...
----

La metadata di zona risponde anche prima che il LLM finisca la sua frase: `edster/`### JBake CLI Commands ``` # Initialize a new JBake project jbake -i

# Bake (generate) the site jbake -b

# Bake and serve locally jbake -b -s

# Bake and watch for changes jbake -b --reset

# Specify source and destination jbake source_folder output_folder

# Clear the output directory before baking jbake -b . output --reset`CSS/`</think>

, livello 3 →**accesso vietato al knowledge graph pubblico** Il RAG non lo vede. Il grafo non lo tocca. La risposta dell'utente non non lo cita.

[TIP]
====
L'ontologia spaziale funziona come una**permessi Unix** pour les LLM. Non chiedete a un processo di essere prudente con`/etc/shadow`[No output] gli neghi l'accesso in lettura. Stesso principio.
====

== Implementazione : Attività Gradle tipate

La matrice non è una filosofia. È codice. Ecco il contratto di compito Gradle che lo implementa :

[source,kotlin]
----
abstract class ZoneAwareIndexer @Inject constructor(
    private val rootDir: DirectoryProperty,
    private val configServer: ConfigServerProperty  // → configuration/
) : DefaultTask() {

    @Input
    val zoneFilter: SetProperty<Zone> = project.objects.setProperty(Zone::class.java)

    @OutputFile
    val ragIndex: RegularFileProperty = project.objects.fileProperty()

    @TaskAction
    fun index() {
        val allowedPaths = zoneFilter.get().flatMap { it.resolve(rootDir.get()) }
        val forbiddenPaths = Zone.RESTRICTED.resolve(rootDir.get())
                            + Zone.INTIMATE.resolve(rootDir.get())
        // Le RAG ne voit jamais configuration/ ni la racine
        // CSS/ alimente un index privé, pas celui-ci
        // office/ est filtré par le classifieur Vision/Opinion
    }
}

enum class Zone {
    INTIMATE,      // Cercle 0 — racine
    RESTRICTED,    // Cercle 1 — configuration/
    EDITORIAL,     // Cercle 2 — office/
    CLOSED_SOURCE, // Cercle 3 — foundry/private/
    OPEN_SOURCE    // Cercle 3 — foundry/public/
}
----

L'attività è *testable*. Puoi scrivere un test che verifica:

[source,kotlin]
----
@Test
fun `le RAG n'indexe jamais configuration`() {
    val index = ZoneAwareIndexer(rootDir, configServer)
    index.zoneFilter.set(setOf(Zone.OPEN_SOURCE, Zone.EDITORIAL))
    index.index()

    assertThat(index.ragIndex).doesNotContain("configuration/")
}

@Test
fun `le code closed source est exclu du RAG public`() {
    val index = ZoneAwareIndexer(rootDir, configServer)
    index.zoneFilter.set(setOf(Zone.OPEN_SOURCE))  // OSS only

    assertThat(index.ragIndex).doesNotContain("edster")
}
----

380 tests, 380 PASS. Come per plantuml-gradle — la sicurezza è testata, non sperata.

== Perché è un Manifesto, Non Solo una spec

Questo documento è una specifica di architettura perché definisce:

* Des **dimensioni**(spaziale, epistemico)
* Des **regole deterministe**(zona → diritto di accesso)
* Un **contratto di incarico**(Gradle tipizzato, testabile)
* una**implementazione di riferimento**(mio workspace)

Ma è anche un**manifesto**perché prende posizione su un dibattito plus large : *comment gouverner l'accès d'un LLM à des données ?*

La risposta dell'industria, è il prompt engineering + i guardrail +
i classificatori post-hoc. La mia risposta è: **metti i tuoi file nella le buone cartelle.** Il resto è automatico.

[IMPORTANT]
====
Questo manifesto non dice "i LLM devono essere allineati". Dice: "l'allineamento di un LLM sulle tue regole di sicurezza è una conseguenza del tuo sistema di file, non il tuo prompt.
====

== La Cascata Completa — dal Brain Dump all'Articolo del Blog

Per illustrare il ciclo completo, ecco come è nata questa idea di matrice ed è stata diluita :

[source]
----
Session 4 mai 2026 — Feedback global du workspace
  │
  ├→ Le LLM identifie : "la dualité public/privé est invisible"
  │   → Classifié VISION (constat architectural vérifiable)
  │
  ├→ PICTURE_ME_ROLLIN_MATRICE_4X4.adoc — STIMULUS (Cercle 0)
  │   → Brain dump structuré, classification VISION confirmée
  │
  ├→ DILUTION → WORKSPACE_AS_PRODUCT.adoc (section Matrice 4×4)
  │   → La spec vit dans les documents racine
  │
  ├→ DILUTION → WORKSPACE_ORGANIZATION.adoc (OSS/CSS)
  │   → La granularisation est documentée
  │
  └→ ARTICLE 0117 (ce document) → cheroliv.com
      → La VISION est publiée
----

Ciò che è iniziato come un'osservazione in sessione ("ehi, il RAG non sa que edster est closed source") è diventata una specifica di architettura pubblicata in meno di una sessione. È il pattern STIMULUS in azione.

== Pro e contro

|===
|Questo approccio (Ontologia Spaziale + Matrice) |L'approccio Classico (Prompt + Guardrails)

|*Meccanica* — il sistema di file blocca l'accesso, non il LLM |*Dichiarativa* — il prompt chiede al LLM di essere prudente |*Testable* — le contrat de tâche Gradle est vérifié par 380+ tests |### Comandi CLI JBake ``` # Initialize a new JBake project jbake -i
|*Indépendante du LLM* — changez de modèle, les dossiers restent |*Dipendente dal LLM* — ogni modello interpreta il prompt in modo diverso |*Scalable* — nuovo tipo di dati = nuova cartella, nessun cambiamento di codice |*Non scalabile* — nuovo tipo di dati = nuova clausola di prompt, nuovo rischio di regressione |### JBake CLI Commands ``` # Initialize a new JBake project jbake -i
|*Contrainte* : richiede una disciplina di organizzazione iniziale |*Contrainte* : richiede una disciplina nella redazione dei prompt per ogni sessione
|===

== Conclusion: Organizza i tuoi file, non i tuoi prompt

La matrice di governance LLM che ho appena descritto non è un prodotto. È una**specifica di architettura** — et c'est pour ça qu'elle est pubblicabile

Ciò che la rende robusta è che non chiede nulla al LLM. Non le Non si fida. Non si basa sul suo allineamento, sulla sua comprensione. del francese, o della sua buona volontà. Si basa sul sistema di file — il livello più basso, più stabile, più testato di tutta la stack.

Quando dico al mio LLM "puoi indicizzare tutto in`OSS/`, niente in `configuration/`, et `office/`solo se è classificato Vision — non è un'istruzione. È un *filtre* — implementato in Kotlin, verificato da 380 test, eseguito prima che il LLM veda i dati.

È la differenza tra dire a qualcuno "non guardare in questo cassetto e chiudere il cassetto a chiave. La governance dell'agente che sto costruendo da i mesi sono la chiave. La matrice è il progetto del mobile.

== Riferimenti

* xref:0116_compartimentage_epistemique_automatise_llm_post.adoc[Articolo 0116 — Il Compartimentaggio Epistemico Automatizzato]
* xref:0114_gouvernance_cercles_confiance_ontologie_spatiale_alignement_llm_post.adoc[Articolo 0114 — I Cerchi di Fiducia e l'Ontologia Spaziale]
* xref:0108_gouvernance_agent_opencode_eager_lazy_post.adoc[Article 0108 — Governare un Agente IA con AsciiDoc]
* link:../2026/0115_anonymiseur_dataset_mvp0_realite_augmentee_llm_post.html[Articolo 0115 — L'anonimizzatore MVP0]

Articoli correlati