
Nimbus Vestige — Mis à jour !
Un moteur de reconstruction forensique pour la réponse aux incidents cloud et d'identité.
Nimbus Vestige (NV)
Un moteur de reconstruction forensique pour la réponse à incident cloud et identité.
Compte tenu de la télémétrie fragmentée du cloud, des SaaS et de l'identité — journaux du plan de contrôle, événements de connexion, activité des jetons et des consentements — NV reconstruit la manière la plus probable dont une intrusion s'est déplacée à travers les comptes et les services, énumère les autres chemins les plus probables qu'elle aurait pu emprunter, et rapporte chaque étape avec une confiance calibrée et explicable. Il refuse d'affirmer ce que les preuves ne peuvent étayer.
La détection vous dit que quelque chose s'est passé. Nimbus Vestige vous dit comment — et quoi d'autre.
Pourquoi cela existe
Les intrusions modernes ne « s'introduisent pas par effraction ». Elles se connectent. L'identité est désormais le principal vecteur d'attaque, impliquée dans la grande majorité des investigations de réponse à incident cloud, et la plupart des intrusions couvrent plusieurs surfaces — identité plus cloud plus SaaS plus endpoint. La télémétrie qui les enregistre est fragmentée et incohérente, ce qui oblige déjà les intervenants à reconstruire le récit à la main à partir de données incomplètes.
Cette reconstruction manuelle est lente et échoue d'une manière prévisible : l'intervenant s'ancre sur le premier récit plausible et rate le vrai. NV automatise la reconstruction et attaque directement ce mode de défaillance en présentant toujours l'espace hiérarchisé des chemins plausibles, et non un récit unique.
Crucialement, NV le fait avec l'honnêteté comme produit. L'ennemi déclaré du marché est la confiance en boîte noire — un outil qui affirme une conclusion sans montrer son travail. Chaque chiffre produit par NV est traçable jusqu'à la preuve spécifique qui l'a mérité, et tout ce qu'il ne peut pas étayer est omis plutôt que deviné.
Ce que c'est — et ce que ce n'est pas
NV n'est pas un détecteur, un scanner, un auditeur ou un exécuteur d'attaques. Ces outils vous disent que quelque chose s'est passé et le mesurent. NV fonctionne à rebours — reconstruction abductive du mécanisme à partir de schémas, à travers un environnement d'identité fragmenté.
- Pas un détecteur — il ne déclenche pas d'alertes sur l'activité ; il explique comment l'activité s'articule.
- Pas un SIEM — il entre par une brèche étroite (reconstruction narrative post-incident), pas comme une plateforme de journaux.
- Pas un moteur de règles — quand rien ne correspond à un schéma connu, il reconstruit quand même, en se dégradant gracieusement au lieu de devenir aveugle.
Pourquoi c'est valable à long terme
-
L'équipe bleue se régénère ; l'équipe rouge se banalise. Les outils offensifs trouvent un ensemble fini et corrigeable de failles et s'intègrent dans des pipelines de sécurité CI/CD automatisés. Reconstruire comment une intrusion s'est produite ne se résout jamais — les attaquants continuent d'inventer, le besoin est donc permanent et auto-renouvelable.
-
Le moteur est indépendant du substrat. La logique centrale — reconstruire le mécanisme à partir de schémas, avec une confiance calibrée et un garde-fou — est d'abord dédiée au cloud/identité, mais sera ensuite portée vers le réseau, l'endpoint et l'OT. La cible peut changer sans réécrire la thèse.
-
La reconstruction permet le durcissement. Une fois que vous savez comment ils sont entrés — et quelles autres portes étaient ouvertes — vous construisez les défenses. Les chemins non empruntés mais plausibles constituent un arriéré de durcissement, souvent plus précieux que la reconstruction elle-même, car la plupart des violations exploitent une exposition évitable, et non un savoir-faire inédit.
-
Il se dégrade gracieusement face à l'intrusion inédite — l'incident même qui compte le plus. Un moteur de signatures/règles devient aveugle face à un zero-day ; le cœur abductif de NV produit encore un chemin le plus probable, honnêtement signalé comme de confiance moindre.
-
L'honnêteté est un fossé défensif. Une confiance calibrée, fondée sur les cas, avec des alternatives hiérarchisées, est exactement ce que le marché dit vouloir et ce que les concurrents en boîte noire ne peuvent structurellement pas offrir sans refonte.
Architecture
Journaux bruts du fournisseur → graphe normalisé d'événements/entités → moteur de reconstruction → JSON → GUI.``` O365 / Entra audit logs nv_extract_identity_events.py AWS CloudTrail (IAM/STS/S3) nv_extract_cloudtrail_events.py (ingest + normalize) ▼ normalized identity events (JSONL) ← one event model, any substrate │ nv/graph.py (typed per-actor timelines) ▼ reconstruction engine ├─ nv/patterns.py known layer: ATT&CK identity pattern library ├─ nv/providers.py provider packs: per-substrate op→ATT&CK vocab (Entra + AWS) ├─ nv/validation.py Phase 3: provenance + integrity gate on every pattern ├─ nv/feeds.py live ATT&CK STIX / TAXII / Sigma clients + scheduler ├─ nv/confidence.py evidence-corroboration scorer (calibratable weights) ├─ nv/calibration.py fit + measure confidence against labeled ground truth ├─ nv/reconstruct.py most-likely chain + ranked competing paths + trust floor └─ nv/scope.py authorized-scope gate (refuses unauthorized tenants/accounts) │ run_nv.py ▼ reconstruction.json ──► nv_gui.html (embedding canvas + two-column view + trust slider)
L'interface graphique est une **pure couche de vue** — elle affiche la sortie du moteur et permet à l'analyste de déplacer
le plancher de confiance. Elle ne contient aucune logique de reconstruction propre.
---
## Le modèle de confiance (la crédibilité de l'ensemble du produit)
Chaque étape porte une confiance dans [0, 1], construite par **corroboration des preuves**:```
confidence = per-technique base rate
+ bonus for each independent corroborating signal
(source IP, device, successful outcome, temporal adjacency, broad-consent flags)
− penalty for missing signals (e.g. no source IP to corroborate origin)
- verified — confiance ≥ 0,70 et deux signaux indépendants ou plus concordent.
- pattern-only — au-dessus du seuil de confiance, mais faiblement ou avec un seul signal.
- withheld — sous le seuil de confiance ; affiché grisé, jamais deviné ou masqué silencieusement.
Les scores de chemin composent leurs liens par moyenne géométrique, si bien qu'un lien faible fait honnêtement baisser un chemin plutôt que d'être noyé dans la moyenne.
Chaque pondération ci-dessus — les taux de base par technique, les bonus par signal, les
pénalités pour données manquantes — vit dans une table PARAMS unique dans nv/confidence.py. Ce sont les a priori v1 de NV, et ils sont calibrables : nv/calibration.py peut les réajuster sur une vérité terrain étiquetée, et le moteur chargera le résultat, en revenant aux a priori v1 si aucune calibration n'est fournie (voir plus bas).
Le seuil de confiance
La règle de rétention, intégrée au contrat de sortie du moteur — pas seulement à l'interface. Sous le seuil, une étape est retenue. Déplacer le seuil, c'est le compromis honnêteté-couverture rendu physique : vers le haut pour un mode strict/confiance élevée, vers le bas pour un mode permissif/couverture élevée. Le seuil par défaut est une décision éditoriale sur la position de NV avant que l'analyste n'intervienne.
Calibrer la confiance sur la vérité terrain
Les poids v1 sont défendables, mais ce sont des a priori. nv/calibration.py les ajuste
sur une vérité terrain étiquetée — des événements dont nous savons lesquels faisaient partie de l'intrusion et lesquels étaient bénins — et, point crucial, mesure si l'ajustement a réellement aidé, si bien qu'une calibration n'est adoptée que si elle réduit l'erreur de calibration plutôt que de simplement déplacer les chiffres.
Une confiance calibrée signifie une chose : la confiance de NV pour une étape doit être égale à la probabilité que cette étape ait réellement fait partie du chemin d'attaque. Ainsi, la confiance de chaque événement étiqueté est traitée comme une probabilité prédite, et le banc d'essai ajuste :
- taux de base par opération — le taux de réussite empirique pour cette opération, rétréci par méthode bayésienne vers l'a priori v1 afin que les petits échantillons ne surajustent pas ; et
- bonus par signal et les deux pénalités — par descente de coordonnées bornée qui minimise le score de Brier avec un rappel L2 vers les valeurs v1.
Les seuils verified/withheld relèvent de la politique, pas de la calibration, et sont laissés intacts.
Il rapporte le score de Brier, la log-loss, l'ECE, l'AUC, une table de fiabilité et un balayage du seuil de confiance (rappel des étapes réelles vs taux de faux positifs bénins à chaque seuil), avant et après — afin que le compromis honnêteté-couverture soit lisible plutôt qu'un nombre unique.```bash
calibrate against a real, labeled BadZure / MAAD-AF run
python3 calibrate.py --labeled run_labeled.jsonl --origin live
--run-label "badzure-2026-07 tenant-x" --out calibration.json
demonstrate on the bundled documented-shape proxy corpus
python3 calibrate.py --out calibration.json
run the engine on calibrated weights (opt-in; v1 priors are the default)
python3 run_nv.py events.jsonl out.json --authorize t.onmicrosoft.com
--calibration calibration.json
**Source de vérité terrain.** L'entrée honnête est la télémétrie d'une exécution BadZure / MAAD-AF dans un locataire réel, étiquetée en croisant le journal d'audit unifié avec le propre enregistrement d'activité de l'outil d'attaque (chaque événement provoqué par l'outil figure dans la chaîne ; tout le reste est bénin — voir `LABELED_SCHEMA` dans `nv/calibration.py`). Tant que vous ne le pointez pas vers une exécution réelle, `eval/calibration_cases.py` fournit un corpus **proxy** de forme documentée, et chaque artefact ajusté à partir de celui-ci est estampillé `source="proxy"` dans sa provenance, de sorte qu'un ajustement proxy ne puisse jamais être confondu avec un ajustement réel. `calibration.proxy.json` est cet artefact proxy inclus.
Sur le corpus proxy fourni, l'ajustement est une nette amélioration — Brier 0.398 → 0.045, ECE 0.576 → 0.081, AUC 0.81 → 0.91, et le taux de faux positifs bénins au plancher de 0.60 s'effondre de 0.69 à 0.00 (les a priori de la v1 étaient nettement trop confiants sur l'activité bénigne). Le proxy est délibérément conservateur ; une exécution en locataire réel est ce qui produit les poids que vous devriez réellement déployer.
## Intégrité de la confiance (Phase 3)
Deux contrôles de premier ordre protègent la reconstruction contre les mauvaises entrées :
- **Passerelle de périmètre autorisé** (`nv/scope.py`) — NV refuse de s'exécuter sur tout parc qui ne figure pas sur la liste autorisée. Exécutez avec `--authorize <tenant-domain>` pour chaque parc que vous êtes autorisé à investiguer.
- **Validation de la source des motifs** (`nv/validation.py`) — aucun motif n'entre dans la bibliothèque sans passer : (1) liste blanche de sources de confiance, (2) somme de contrôle du contenu / vérification d'altération, (3) bonne formation du schéma, (4) identifiant de technique valide de style ATT&CK. Chaque motif admis conserve un enregistrement d'audit ; les rejets sont journalisés avec une raison. Un flux empoisonné ou malformé est arrêté en amont avant de pouvoir fabriquer une fausse reconstruction. C'est le même scepticisme que le moteur applique aux preuves, transposé aux motifs eux-mêmes.
---
## Maintenir les connaissances à jour (garder une longueur d'avance sur l'évolution des attaquants)
Un moteur de reconstruction n'est à jour que dans la mesure où sa bibliothèque de motifs l'est, et où il sait traiter ce que la bibliothèque n'a jamais vu. NV traite l'obsolescence sur **deux fronts indépendants**, par conception :
### 1. La couche connue reste fraîche grâce à un pipeline de mise à jour validé
La bibliothèque n'est pas codée en dur — `nv/patterns.py` charge chaque motif (y compris l'ensemble intégré) via `nv/validation.py`, de sorte que les flux externes entrent par le même chemin de confiance. Les clients réseau actifs qui récupèrent ces flux selon un calendrier sont implémentés dans `nv/feeds.py` et pilotés par `update_feeds.py`. Sources, par niveau de confiance :
- **MITRE ATT&CK (STIX)** — la taxonomie de techniques faisant autorité. Le connecteur lit l'index STIX d'ATT&CK, récupère la dernière version Enterprise et actualise, pour chaque opération sur laquelle NV raisonne, le nom de technique et la tactique faisant autorité — abandonnant toute opération dont la technique a depuis été révoquée ou dépréciée par ATT&CK. NV conserve la propriété de la liaison opération→technique et de l'a priori de taux de base ; ATT&CK possède la taxonomie.
- **CTI vérifiée via TAXII 2.1** — un client complet discovery → api-root → collection → objects. Il extrait les objets attack-pattern STIX d'une collection CTI vérifiée et actualise les techniques suivies par NV. Pondérée en dessous d'ATT&CK.
- **Ensemble de règles communautaires Sigma** — récupéré sous forme d'archive git ; chaque règle cloud/identité qui nomme une opération O365/Entra et porte une balise `attack.tXXXX` devient un candidat opération→technique, avec un taux de base dérivé du niveau de sévérité `level` de la règle elle-même, puis réduit par le poids de la source communautaire. Les règles qui ne correspondent pas sont ignorées avec une raison, jamais devinées.
En cas de collision d'opération, l'union est ordonnée par confiance croissante avant application, de sorte qu'une liaison ATT&CK faisant autorité gagne toujours sur une liaison communautaire ; le contenu de niveau inférieur est toujours admis et enregistré dans l'audit comme corroboration. `update_library(candidates)` réingère l'ensemble complet via la validation et reconstruit la bibliothèque de manière atomique, de sorte qu'un flux empoisonné ne puisse jamais laisser la bibliothèque à moitié mise à jour.
**Deux listes blanches, pas une seule.** La validation filtre déjà sur la balise de source ; les connecteurs ajoutent une liste blanche *d'hôtes* au niveau réseau, de sorte qu'un connecteur ne peut récupérer que depuis un hôte de confiance via TLS — l'équivalent transport de la liste blanche de sources, et une protection contre une URL de flux détournée ou mal saisie. Chaque récupération enregistre le sha256 de la charge utile brute, l'URL et l'heure comme provenance, afin qu'une ré-extraction ultérieure puisse détecter une mutation en amont.
**Pourquoi la couche de validation compte davantage à mesure que les flux croissent :** plus vous automatisez les mises à jour, plus un pipeline de mise à jour automatique devient un risque de confiance déguisé — un flux erroné ou empoisonné injecte de faux motifs et fabrique de fausses reconstructions. NV traite l'ingestion comme hostile : liste blanche, somme de contrôle, schéma et piste d'audit sur chaque motif, à chaque mise à jour.
### 2. La couche abductive couvre ce qu'aucun flux n'a encore nommé
Les flux sont toujours en retard sur les techniques les plus récentes. Le cœur abductif est la parade : lorsqu'une opération observée ne correspond à **aucun** motif de la bibliothèque, NV ne l'écarte pas — il reconstruit le chemin le plus probable à partir des premiers principes et le marque comme `no known match` avec une confiance réduite. Cela est validé dans la suite d'évaluation (`eval/ground_truth_cases.py`), où une étape de vol de jeton d'identité managée délibérément inconnue est détectée, séquencée correctement et honnêtement pondérée à la baisse sous le plancher de confiance.
Ensemble, cela signifie que NV ne devient jamais complètement obsolète : la couche connue suit la frontière publiée via un pipeline résistant à l'empoisonnement, et la couche abductive empêche l'outil de devenir aveugle face à l'intrusion que la frontière n'a pas encore rattrapée.
### Cadence de mise à jour suggérée
`nv/feeds.py` porte une cadence par flux et `update_feeds.py` ne récupère que ce qui est dû, de sorte qu'il peut être placé directement dans cron ou une minuterie systemd :
- ATT&CK STIX — 90 jours (quelques versions officielles par an).
- CTI/TAXII — 7 jours (au rythme des publications du flux), toujours via la validation.
- Sigma — 30 jours.```bash
# run whatever is due, keeping state under ./.nv_feeds (cron-friendly)
python3 update_feeds.py
# force all feeds now but only report what would change
python3 update_feeds.py --force --dry-run
# run fully offline against captured fixtures (no network)
python3 update_feeds.py --offline eval/fixtures --force
Après toute modification de la bibliothèque, réexécutez eval/run_eval.py pour confirmer que les formes d'attaque connues se reconstruisent toujours,
eval/validation_cases.py pour confirmer que la validation rejette toujours les entrées invalides, et
eval/feeds_offline_test.py pour confirmer que le chemin d'alimentation est intact de bout en bout.
Note sur les données de démonstration
La reconstruction affichée dans nv_gui.html est construite à partir d'un jeu de données de recherche public
— le corpus de journaux d'audit unifiés Office 365 d'invictus-ir — et non à partir du tenant en production d'une
entreprise. Il existe pour que le moteur puisse être démontré et testé en interne de bout en bout sans
la coopération de personne. Pour utiliser NV pour de vrai, une organisation branche ses propres données d'audit Entra/M365,
comme décrit ci-dessous. Aucune donnée propriétaire ou client n'est incluse où que ce soit dans
ce projet.
Connecter vos propres données
NV s'exécute là où vous l'exécutez ; vos journaux n'ont jamais à quitter votre environnement. Quatre étapes :
1 — Exportez vos journaux d'audit. NV lit le journal d'audit unifié Microsoft 365. Obtenez-le
à partir de Microsoft Purview (Recherche d'audit → export CSV), de l'applet de commande PowerShell Exchange Online Search-UnifiedAuditLog,
des points de terminaison Microsoft Graph auditLogs / signIns,
ou d'une exportation Sentinel/SIEM de OfficeActivity et SigninLogs.
2 — Normalisez-le dans le modèle d'événements sur lequel NV raisonne :```bash python3 nv_extract_identity_events.py your_audit_export.csv your_events.jsonl
Ceci conserve les connexions, les octrois de consentement, les modifications de principal de service et de rôle, et l'accès aux boîtes aux lettres — y compris les opérations d'identité que NV n'a jamais nommées, afin qu'elles atteignent toujours la couche abductive — et rejette le reste. Il lit un CSV portant la colonne standard `AuditData`, ou du JSON/JSONL où chaque enregistrement est un objet `AuditData` (la forme sous laquelle le corpus de recherche invictus-ir est fourni).
**3 — Reconstruire, à portée contrôlée.** Le moteur refuse de s'exécuter sur un locataire que vous n'avez pas explicitement autorisé :```bash
python3 run_nv.py your_events.jsonl reconstruction.json \
--authorize yourtenant.onmicrosoft.com
4 — Affichage. Ouvrez nv_gui.html et cliquez sur ⤒ load reconstruction.json pour le pointer vers
le fichier que le moteur vient de produire — le même écran affiche alors votre incident, vos
entités et vos bandes de confiance. Chaque point du canevas d'intégration réexécute la
reconstruction de cette entité lors d'un clic.
Analyser AWS CloudTrail à la place
Le moteur est indépendant du substrat — seul le vocabulaire des opérations est spécifique au fournisseur
(nv/providers.py). Le parcours AWS suit les mêmes trois étapes avec CloudTrail :```bash
python3 nv_extract_cloudtrail_events.py cloudtrail.json aws_events.jsonl
python3 run_nv.py aws_events.jsonl reconstruction.json --authorize aws:123456789012
L’ingestion conserve les événements IAM/STS/de connexion (y compris les nouvelles opérations IAM, afin qu’elles atteignent la couche abductive) ainsi que les lectures d’objets S3, et limite le périmètre au **compte** AWS plutôt qu’à un domaine de locataire. Le même noyau abductif, le modèle de confiance et le plancher de confiance s’appliquent sans changement.
L’interface graphique comporte également un **bandeau de données de démonstration** et un guide intégré « Connecter vos propres données », afin que quiconque l’ouvre comprenne que la reconstruction repose sur des données d’exemple publiques tant qu’ils n’ont pas branché les leurs.
## Structure du projet```
run_nv.py reconstruction engine entrypoint (scope-gated)
nv_extract_identity_events.py ingest: M365/Entra unified audit log -> event model
nv_extract_cloudtrail_events.py ingest: AWS CloudTrail -> event model [iteration 3]
update_feeds.py pull + validate threat-intel feeds on a cadence [iteration 1]
calibrate.py fit confidence weights from labeled ground truth [iteration 2]
nv/ the engine package
graph.py patterns.py validation.py confidence.py reconstruct.py scope.py
providers.py per-substrate op->ATT&CK vocabulary packs (Entra + AWS) [iteration 3]
feeds.py ATT&CK STIX / TAXII 2.1 / Sigma clients + scheduler [iteration 1]
calibration.py metrics + parameter fit [iteration 2]
eval/ evals + offline fixtures (no network, no tenant)
nv_gui.html pure view layer (loads engine reconstruction.json)
calibration.proxy.json bundled proxy calibration artifact [iteration 2]
Exécutez tout depuis la racine du projet afin que le package nv soit importable.
Exécution```bash
1. normalize raw O365/Entra audit logs into the event model
python3 nv_extract_identity_events.py auditrecords.csv nv_identity_events.jsonl
2. reconstruct (scope-gated; add --calibration calibration.json to use fitted weights)
python3 run_nv.py nv_identity_events.jsonl reconstruction.json
--trust-floor 0.6 --authorize your-tenant.onmicrosoft.com
3. view — open nv_gui.html (renders reconstruction.json)
Gardez la bibliothèque de modèles à jour et ajustez la confiance :```bash
python3 update_feeds.py # pull + validate feeds that are due
python3 calibrate.py --labeled run.jsonl --origin live --out calibration.json
Évaluations```bash
python3 eval/run_eval.py # attack shapes reconstruct correctly python3 eval/validation_cases.py # poisoned patterns are rejected python3 eval/feeds_offline_test.py # feed connectors + scheduler (offline) python3 eval/providers_aws_test.py # AWS chain reconstructs through the same engine python3 calibrate.py # calibration harness on the bundled proxy corpus
---
## Statut
**Fonctionne de bout en bout sur des données réelles** (jeu de données O365 d'invictus-ir), sur l'ensemble du plan :
| Phase | Élément | Statut |
|---|---|---|
| 1 | Modèle normalisé événement/entité | fait |
| 1 | Ingestion + normalisation (tête de pont Entra/M365) | fait |
| 2 | Couche connue (bibliothèque de motifs ATT&CK) | fait |
| 2 | Modèle de confiance par corroboration des preuves | fait |
| 2 | Plancher de confiance dans le contrat de sortie | fait |
| 2 | Noyau abductif (couche inconnue) | fait, prouvé par évaluation |
| 2 | Hypothèses concurrentes classées | fait |
| 3 | Couche de validation des sources de motifs | fait |
| 3 | Contrôle du périmètre autorisé | fait |
| 3 | Connecteurs de flux en direct (ATT&CK STIX / TAXII / Sigma) + planificateur | fait |
| 4 | Écran à deux colonnes sur la sortie réelle du moteur | fait |
| 4 | Toile d'intégration / similarité | fait |
| 4 | Reconstruction par entité pilotée par la toile (le clic relance la chaîne) | fait |
| 4 | L'interface graphique charge le `reconstruction.json` du moteur (pointez-la vers votre fichier) | fait |
| 4 | Substrat multi-fournisseur (AWS CloudTrail, prouvé par évaluation) | fait |
| 5 | Esthétique / habillage | fait |
| 5 | Harnais de calibrage de la confiance + intégration au moteur | fait |
### Lacunes connues et assumées (prochaines itérations)
- **Chiffres de calibrage en environnement réel.** Le *harnais* de calibrage est
complet et l'interface est éprouvée, mais le `calibration.proxy.json` fourni est
ajusté sur des données proxy à forme documentée. Des poids déployables nécessitent
d'exécuter le harnais sur un vrai run BadZure / MAAD-AF — une étape opérationnelle
pour l'adoptant.
- **Croissance du vocabulaire pilotée par les flux.** Les connecteurs actualisent les
opérations sur lesquelles le NV raisonne déjà ; laisser un flux *introduire* une
nouvelle opération (et la câbler dans la classification initial/pivot/collecte)
est un travail futur.
- **Profondeur du deuxième fournisseur.** AWS est intégré comme preuve
d'indépendance du substrat (pack + ingestion + évaluation), mais seulement
IAM/STS/S3. Élargir le pack AWS, ajouter des connecteurs de flux spécifiques aux
fournisseurs et un troisième substrat (GCP, Okta) sont les prochaines étapes.
---
## Licence
Nimbus Vestige est **disponible en code source** sous la **licence non commerciale
PolyForm 1.0.0** (voir [LICENSE](https://gitlab.com/dobybaxter127/nimbus-vestige/-/blob/main/LICENSE)). L'outil complet — moteur de reconstruction,
les deux ingestions fournisseurs, l'interface graphique et le harnais d'évaluation —
est libre d'inspection, d'exécution et d'utilisation à toute fin
**non commerciale** : projets personnels, recherche, enseignement, organisations à
but non lucratif et évaluation. Lisez chaque ligne avant de vous décider.
**L'utilisation commerciale requiert une licence payante** — l'utiliser dans un
produit ou un service que vous vendez ou hébergez, dans les systèmes de production
ou internes d'une entreprise à but lucratif, ou lors d'interventions payantes de
réponse aux incidents ou de missions clients. Voir
[COMMERCIAL-LICENSE.md](https://gitlab.com/dobybaxter127/nimbus-vestige/-/blob/main/COMMERCIAL-LICENSE.md).
---
### Auteur
Doby Baxter 2026