Preserve the local graph-first investigation stack through macro V1. Include reviewed source, tests, contracts, documentation and synthetic assets. Retain the standalone financial V21 test foundation without runtime migration. Runtime remains V20; operational JobStore remains V3. Local experimental checkpoint, not a stable release. |
||
|---|---|---|
| .. | ||
| contracts | ||
| docs | ||
| public | ||
| tests | ||
| .gitignore | ||
| fixtures.py | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| report_bundle.py | ||
| run_core_demo.py | ||
| run_eml_demo.py | ||
| run_local_toolkit_demo.py | ||
| run_web_workspace.py | ||
| server.py | ||
| workspace_server.py | ||
Prototype Web Graph J2 et connexion cœur J3
Prototype expérimental en lecture seule. Toutes les données sont des fixtures
SPECIMEN; aucune base d'enquête n'est ouverte et aucune action réseau OSINT n'est exécutée.
Lancer
Prérequis d'exécution : Python 3.11+ et un navigateur moderne. Le serveur
n'utilise que la bibliothèque standard Python ; jsonschema sert aux tests de
contrat et n'est pas requis pour afficher le prototype.
cd prototypes/web-graph
python3 server.py --port 8765
Ouvrir http://127.0.0.1:8765/, puis arrêter avec Ctrl+C. Le serveur écoute
uniquement sur loopback et ne sert que public/ et les endpoints de fixtures.
Mode snapshot du cœur C
Depuis la racine du dépôt, compiler puis lancer :
make -j8 core-graph-demo
cd prototypes/web-graph
python3 run_core_demo.py --port 8765
Cette commande crée un répertoire temporaire privé, génère une base SQLite V20
neuve via Database et les DAO C, ferme les writers, exporte un snapshot v2 via
une connexion réellement read-only, puis sert ce seul snapshot. L'écran affiche
« Snapshot du cœur C » et n'ouvre aucun flux SSE. Un échec C est affiché comme
tel, sans repli vers fixtures.py.
Le serveur Python ne lit jamais SQLite, n'accepte aucun chemin de base par HTTP
et ne sert aucun fichier de preuve. Les coordonnées du mode cœur sont calculées
par le pont Web comme état de présentation. Le contrat et le mapping sont dans
CORE_GRAPH_READONLY.md.
Mode analyse EML C persistée
Depuis la racine du dépôt :
make -j8 eml-graph-demo
cd prototypes/web-graph
python3 run_eml_demo.py --port 8765
Le générateur crée une base V20 synthétique, importe une preuve EML par
EvidenceImporter, exécute réellement eml_analyzer, publie deux extractions
avec leurs dérivés et observations proposées, vérifie un replay idempotent,
ferme le writer puis exporte en lecture seule un snapshot v3. Python ne fabrique
aucun objet du graphe. --variant alternate utilise un second message fictif
et permet de vérifier que les valeurs affichées proviennent bien de l'analyse.
Le contrat complet est décrit dans
EML_ANALYSIS_TO_GRAPH.md.
Comportements démontrés
Le scénario demo contient 14 nœuds et 12 arêtes, dont deux relations distinctes
entre person-a et username et deux sources de provenance de artifact.
- Les relations métier, support, contradiction et provenance ont un libellé, un motif/couleur et, lorsqu'elles sont dirigées, une flèche. Les relations parallèles suivent des courbes déterministes distinctes, y compris après drag.
- Rendu, liste, compteurs, clavier et focus utilisent une projection commune. Les filtres vides restent navigables sans exception et invalident proprement les détails/actions devenus invisibles.
- Sélection, mode focus, historique, viewport, filtres et positions épinglées
sont séparés.
Vue globaleconserve les positions ;Réinitialiser la dispositionest la seule commande qui les efface. - Les capabilities sont un instantané serveur par
object_ref. Une personne, un domaine et une preuve reçoivent des actions différentes ; RDAP n'apparaît que sur le domaine et reste désactivé comme simulation sans contact réseau. - La provenance parcourt toutes les origines avec limites de profondeur et de branches. Chaque source peut être ouverte séparément ; cycles et références manquantes sont signalés sans boucle ni chaîne inventée.
- Le flux SSE applique deux patches réels (révisions 1 → 2 → 3), reconnecte avec les identifiants du scénario, puis annonce une fin normale. Doublons et anciens événements sont ignorés ; trou ou curseur inconnu déclenchent le snapshot courant ; JSON/contrat inattendu produisent un diagnostic explicite.
Les jeux 100, 1000 et 5000 gardent des graines fixes et exposent
respectivement deux fois plus d'arêtes que de nœuds. Ils servent aux contrats/API,
pas à promettre la fluidité du renderer SVG ni à choisir le moteur de J6.
Tester
Les tests Node de logique ne demandent aucune dépendance npm. Les tests Python de
schéma demandent jsonschema. L'automatisation navigateur utilise
puppeteer-core 24.28.0 (Apache-2.0), verrouillé dans package-lock.json, avec
un Firefox local et un profil temporaire dédié ; elle ne télécharge pas de
navigateur et n'ouvre jamais un profil personnel.
cd prototypes/web-graph
npm ci --ignore-scripts --no-audit --no-fund
npm test
python3 -m unittest discover -s tests -p 'test_*.py' -v
npm run test:browser
Si Firefox n'est pas /usr/bin/firefox, fournir explicitement son chemin :
FIREFOX_PATH=/chemin/vers/firefox npm run test:browser
Le dernier scénario de cette matrice valide le poste Web graph-first
aux formats 1440×900, 1366×768, 700×900 et au zoom 200 %. Ses captures locales
inspectables sont /tmp/labfy-workbench-{selected,context,planner,provenance,report,empty,narrow}.png.
Le scénario J9 clique séparément les cinq liens de rapport, attend la fin des
téléchargements Firefox dans un répertoire privé, puis vérifie leurs tailles,
SHA-256, HTML hors ligne, PDF et manifeste sans lire le dossier export serveur.
Relevé de validation locale du 25 septembre 2026
Environnement observé : Firefox 156.0.1, Node 26.10.0, npm 12.1.0,
Python 3.14.7 et jsonschema 4.26.0.
| Validation | Résultat observé |
|---|---|
npm test |
9/9 tests Node réussis |
| tests Python | 6/6 tests réussis, dont schémas, sécurité HTTP, tailles et reprise SSE |
npm run test:browser |
PASS Firefox sans exception JavaScript |
| Rendu large | sélection/focus, trois voisins, deux liens parallèles et fin SSE visibles |
| Rendu étroit | une colonne, projection vide, commandes et diagnostic lisibles |
| État erreur | JSON SSE invalide refusé et affiché sans faux statut synchronisé |
Le scénario navigateur exerce chargement, sélection de nœud et d'arête, drag en
plusieurs mouvements avec relâchement extérieur, pointercancel, distinction
clic/drag, zoom, pan, focus, retour, projection vide + clavier, repli/dépli,
capabilities par objet, provenance multiple, deux reconnexions SSE, conservation
du contexte, doublon, trou et rattrapage snapshot. Les captures sont des preuves
visuelles complémentaires ; les assertions d'interaction font foi.
Relevé du lot J3 local du 26 septembre 2026
| Validation | Résultat observé |
|---|---|
tests/test_core_graph |
5/5 : read-only, schéma, projection, stabilité, erreurs |
npm test |
9/9 tests Node J2 réussis |
| tests Python | 8/8, dont snapshot v2 réellement généré par le binaire C |
npm run test:browser |
PASS J2/SSE puis PASS cœur C dans Firefox isolé |
| Rendus cœur | large, étroit et erreur d'export réellement inspectés |
Le second scénario navigateur vérifie 9 nœuds et 8 arêtes issus de SQLite : personnes/identifiants, preuves, observation promue et non promue, exécution historique, deux origines de provenance, lacune explicite, capabilities locales, HTML inerte, recherche, focus/retour, filtre vide, drag et positions épinglées.
Relevé du lot J3 EML local du 26 septembre 2026
| Validation | Résultat observé |
|---|---|
tests/test_eml_analysis_persistence |
6/6 scénarios : publication, replay/conflit, rollback, chemins/sources/limites, analyse vide/annulation, projection |
| tests Python | 9/9, dont validation JSON Schema du snapshot EML v3 produit en C |
npm test |
9/9 tests Node réussis |
npm run test:browser |
PASS J2, cœur v2 et EML v3 dans Firefox isolé |
| Rendus EML | large, étroit et erreur sans repli réellement inspectés |
Le scénario EML vérifie deux extractions, deux dérivés et les observations
réellement calculées depuis le message. Il contrôle notamment
Elodie@Atelier.test → elodie@atelier.test, les états proposed et
unpromoted, la navigation jusqu'à la preuve originale, le contenu HTML
inerte, ainsi qu'une variante indépendante contenant maelle@variant.test.
Mode Toolkit local J4
make -j8 local-toolkit-demo
cd prototypes/web-graph
python3 run_local_toolkit_demo.py --port 8765
Le lanceur génère une enquête V20 SPECIMEN, analyse un EML via l'adapter natif, crée les métadonnées fictives d'une image avant import, exécute l'ExifTool réel via le runner borné, publie les deux parcours puis sert uniquement le snapshot C relu en read-only. Les actions documentaires sont visibles mais désactivées dans ce client, avec la raison « Exécution par le lanceur local ».
Limites
Le serveur Python et les contrats restent des instruments de prototype. Le mode cœur consomme un fichier d'échange généré mais n'accède pas lui-même à SQLite. Il n'y a ni authentification utilisateur, mutation, OSINT, backend de production ou garantie exactly-once. Host/Origin, CSP, méthodes et racine servie sont testés ; TLS, CSRF de mutation, DNS rebinding complet, multi-utilisateur, packaging et durcissement de production restent hors de cette consolidation J2.
Clôture Workbench sur réseau alimenté
test_workbench_populated_browser.mjs exécute les six analyses proposées
depuis les commandes visibles du Web. Sur la fixture du 26 septembre 2026, le
cœur exporte réellement 62 nœuds et 100 arêtes. Ces nombres sont vérifiés mais
ne sont jamais codés dans le renderer.
Le scénario contrôle formes métier, arêtes dirigées, Infrastructure → Réseau,
provenance cliquable et retour, actualisation à UUID constants, réduction du
tiroir, Maj+F10/Échap et invalidation de l’aperçu. Les captures produites
sont /tmp/labfy-workbench-populated-{network,navigation,provenance,drawer,menu,report,narrow}.png.
Espace vide et import local
make web-workspace-local WORKSPACE=/tmp/labfy-local-workspace n’appelle aucun
générateur SPECIMEN. Le formulaire authentifié crée l’enquête vide via le cœur
C. Le dialogue Ajouter des preuves utilise un véritable sélecteur multiple,
prépare EML/PNG/JPEG, permet le retrait, puis confirme chaque publication.
Le serveur fixe l’identité du lot, réserve atomiquement places et octets, borne
la lecture silencieuse/lente et interdit de rouvrir un upload préparé ou importé.
La reprise revalide intention, reçu, record V20 et original publié.
test_local_workspace_import_browser.mjs, inclus dans npm run test:browser,
part de zéro et poursuit jusqu’au planner, au graphe et au rapport PDF.
Revue et aperçu d’une preuve locale
Le bridge Web demande au cœur C l’aperçu d’une preuve EML, PNG ou JPEG après contrôle de son intégrité et des limites de rendu. Il retourne une représentation inerte bornée ; ni l’original, ni un chemin d’original, ni un répertoire de preuves ne sont servis par HTTP. L’identifiant de cache affiché décrit cet aperçu de réponse et ne correspond pas à un cache disque persistant.
Les observations sont relues puis revues transactionnellement. Une décision de revue, une correction humaine, une création/rattachement explicite d’indicateur ou un retrait ont un UUID d’opération, une révision attendue, un auteur et un motif. La confirmation concerne l’observation et ne constitue jamais une attribution d’identité. Seuls e-mail, domaine et IP sont promouvables dans ce lot ; le retrait préserve l’observation, l’entité partagée et les rattachements indépendants.
Après import ou revue, les projections graphe, corrélation et planner sont republiées depuis le persistant ; cette actualisation n’exécute pas une analyse et n’engage aucun budget. La cible ciblée est :
make web-workspace-review-check
Elle compile séquentiellement tools/local-jobs et tools/local-jobs-test,
puis exécute l'intégralité de test_local_workspace_import.py sur des
workspaces temporaires SPECIMEN, avant le parcours navigateur local. La phase
Python couvre notamment le durcissement P01–P06 (cycle de vie, rejeu,
réservations et framing HTTP) ; un échec de l'une ou l'autre phase fait échouer
la cible. Elle ne constitue pas une certification de production ni une
validation de sanitizers.