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.
112 lines
5.7 KiB
Markdown
112 lines
5.7 KiB
Markdown
# Projection cœur → Web en lecture seule — lot J3
|
|
|
|
> **État :** `CURRENT` local, expérimental, uniquement sur fixture synthétique
|
|
> **Runtime lu :** schéma V20
|
|
> **Contrat transport :** `labfy.web_graph.snapshot.v2`
|
|
|
|
Ce lot relie pour la première fois le prototype Web aux données réellement
|
|
persistées et relues par le cœur C :
|
|
|
|
```text
|
|
core_graph_demo
|
|
→ database_initialize + DAO de production
|
|
→ Enquete.sqlite V20 synthétique
|
|
→ database_open_read_only
|
|
→ CoreGraphProjectionService
|
|
→ snapshot JSON v2 atomique
|
|
→ serveur Python statique
|
|
→ prototype Web
|
|
```
|
|
|
|
Le JSON n'est ni une nouvelle base métier, ni une source de vérité. Le serveur
|
|
Python ne lit pas SQLite, ne reçoit aucun chemin de base par HTTP et ne complète
|
|
pas les décisions du cœur.
|
|
|
|
## API, ownership et cohérence
|
|
|
|
- `database_open_read_only(path, error)` ouvre un fichier existant avec
|
|
`SQLITE_OPEN_READONLY`, active `query_only`, refuse toute version autre que
|
|
V20 et n'appelle ni migration ni installation de schéma. L'appelant ferme la
|
|
connexion avec `database_close()`.
|
|
- `database_transaction_begin_read_only()` démarre une transaction différée :
|
|
la première lecture fixe le snapshot SQLite sans demander de verrou
|
|
d'écriture. Le service valide ou annule cette transaction avant de retourner.
|
|
- L'ouverture ne change ni `journal_mode` ni `synchronous` et n'active pas
|
|
`immutable`. Le writer de fixture utilise donc le journal de rollback du
|
|
runtime ; son éventuel fichier `Enquete.sqlite-journal` est transitoire et
|
|
supprimé à la fermeture. Le lecteur fermé ne laisse ni `-journal`, ni `-wal`,
|
|
ni `-shm`, propriété vérifiée par le test C ciblé.
|
|
- `core_graph_projection_service_collect()` emprunte la connexion et retourne
|
|
un `CoreGraphSnapshot` possédé par l'appelant. Une erreur DAO ou une limite
|
|
atteinte invalide toute la collecte ; aucun graphe vide n'est présenté comme
|
|
complet.
|
|
- Le snapshot possède ses chaînes, nœuds, arêtes et capabilities. Les vues de
|
|
getters sont empruntées jusqu'à `core_graph_snapshot_free()`.
|
|
- `core_graph_snapshot_write_atomic()` sérialise entièrement en mémoire, vérifie
|
|
UTF-8 et volume, écrit un staging privé voisin puis renomme. Aucun fichier
|
|
final tronqué n'est publié.
|
|
|
|
## Mapping actuel
|
|
|
|
| Objet demandé | Stockage V20 | API de lecture | Provenance exposée | Limite honnête |
|
|
|---|---|---|---|---|
|
|
| Entité/personne/identifiant | `entites` | `InvestigationGraphLoader` / `EntityDao` | état et identité persistante | provenance uniforme absente |
|
|
| Relation métier | `relations` | `InvestigationGraphLoader` / `RelationDao` | identité, direction, sémantique | justifications non projetées dans ce lot |
|
|
| Preuve | `preuves` | `EvidenceDao` | source/description si présentes | aucun fichier servi par HTTP |
|
|
| Rattachement preuve-entité | `preuve_entites` | `EvidenceEntityDao` | lien `evidence_attachment` | rattachement ≠ preuve d'identité |
|
|
| Observation | `evidence_entity_observations` | variante typée `list_observations()` | brut, normalisé, corrigé, revue, origine et promotion | transformation parfois non identifiée |
|
|
| Exécution OSINT historique | `osint_executions` | `OsintExecutionDao` typé | outil/version, dates, état, extrait brut borné et liens | pas d'artefact/transformation séparé en V20 |
|
|
| Claims/hypothèses/finance V21 | non raccordés au runtime supporté | aucune dans ce lot | aucune | aucune ligne ou chaîne fictive |
|
|
|
|
Les références sont qualifiées par `investigation_id`, `object_kind` et
|
|
`object_id`. Les identifiants de graphe préfixent la catégorie, par exemple
|
|
`entity:<uuid>` et `evidence:<uuid>` : deux tables peuvent donc partager une
|
|
valeur d'identifiant sans collision. Les arêtes composites sans UUID de table
|
|
utilisent une identité dérivée déterministe à partir des clés persistées ; leur
|
|
sémantique indique explicitement cette projection.
|
|
|
|
## Contrat snapshot v2
|
|
|
|
La v1 J2 reste stricte et inchangée. La v2 ajoute :
|
|
|
|
- `origin: "core"`, `schema_version: 20`, `transport_revision: 1` ;
|
|
- `complete` et les limites ayant gouverné l'export ;
|
|
- `object_ref` avec contexte d'enquête ;
|
|
- détails structurés d'observation et de provenance ;
|
|
- sémantique et disposition des arêtes ;
|
|
- absence de coordonnées métier.
|
|
|
|
Le pont Web calcule une disposition déterministe en mémoire. Les déplacements
|
|
et positions épinglées restent de l'état de vue et ne sont jamais réécrits dans
|
|
SQLite. Les limites actuelles sont 500 nœuds, 1 000 arêtes, 1 MiB de JSON et
|
|
512 octets UTF-8 pour l'extrait stdout autorisé. Un dépassement échoue au lieu
|
|
de publier un résultat partiel. La navigation de provenance du prototype reste
|
|
bornée à 12 niveaux et 20 branches.
|
|
|
|
Les paramètres/argv, chemins absolus, stderr et fichiers de preuve ne sont pas
|
|
exportés. La fixture atteste explicitement son caractère synthétique au
|
|
sérialiseur ; celui-ci ne le déduit jamais du nom du dossier.
|
|
|
|
## Démonstration
|
|
|
|
Après compilation :
|
|
|
|
```bash
|
|
make -j8 core-graph-demo
|
|
cd prototypes/web-graph
|
|
python3 run_core_demo.py --port 8765
|
|
```
|
|
|
|
Le lanceur crée un répertoire temporaire privé, invoque l'exécutable fixé avec
|
|
des argv séparés, borne son exécution à 30 secondes, charge uniquement
|
|
`core-snapshot.json` accompagné de son manifeste, puis écoute sur
|
|
`127.0.0.1`. Un échec d'export affiche un état d'erreur et ne retombe jamais sur
|
|
les fixtures Python J2.
|
|
|
|
Ce lot ne clôt pas J3 : provenance uniforme en écriture, publication
|
|
transactionnelle généralisée, backend Web de production, Toolkit, jobs,
|
|
policies, claims/hypothèses et migration financière restent distincts.
|
|
|
|
L'extension ciblée [analyse EML → graphe](EML_ANALYSIS_TO_GRAPH.md) réutilise
|
|
ce lecteur, ajoute le snapshot v3 pour les extractions persistées et ne modifie
|
|
ni la v2 ni la fixture de ce lot.
|