📚 KERN — Wiki Données

Documentation complète des formats de données pour tous les modules

🗺️ Vue d'ensemble

KERN stocke toutes ses données dans le localStorage du navigateur. Chaque type de données a sa propre clé.

⚠️ RÈGLE D'OR

Les clés doivent correspondre exactement. Une erreur de nom = données invisibles.

Clés localStorage

Clé localStorage Type Module(s) Requis
kern_agent_profile Object Tous (profil agent) ✅ Oui
kern_dossiers Array DOSSIERS, NEXUS Non
kern_entities Array PANOPTICON Non
kern_network_contacts Array Contact Network Non
kern_knowledge Array Knowledge Graph Non
kern_missions Array Missions Non
kern_journal Array Journal Non
kern_partners Array Partners Non
kern_protocole Object Protocole Insurrection Non
🚨 ATTENTION : Clé Agent

La clé est kern_agent_profile (pas kern_agent). C'est la cause #1 des plantages !

👤 Agent Profile

Le profil agent est obligatoire. Sans lui, KERN plante.

Clé localStorage

kern_agent_profile

Structure complète

{
  "codename": "GANDALF-PRIME",        // Requis - Nom de code
  "level": 12,                          // Requis - Niveau actuel
  "xp": 15420,                          // Requis - XP actuel
  "xpToNext": 20000,                    // Requis - XP pour niveau suivant
  "clearance": 4,                        // Niveau d'habilitation (0-7)
  "streak": 42,                          // Jours consécutifs
  "lastLogin": "2026-01-06",            // Date dernière connexion
  
  // ⚠️ OBLIGATOIRE - Skills
  "skills": {
    "investigation": { "level": 8, "xp": 720 },
    "network":       { "level": 10, "xp": 890 },
    "analysis":      { "level": 7, "xp": 650 },
    "documentation": { "level": 9, "xp": 810 },
    "fieldwork":     { "level": 6, "xp": 520 },
    "opsec":         { "level": 11, "xp": 980 }
  },
  
  // ⚠️ OBLIGATOIRE - Stats (cause des plantages si absent !)
  "stats": {
    "dossiersCreated": 6,
    "entitiesCreated": 21,
    "contactsAdded": 16,
    "notesWritten": 10,
    "missionsCompleted": 3,
    "linksDiscovered": 45,
    "daysActive": 42,
    "totalActions": 150
  },
  
  // ⚠️ OBLIGATOIRE - Achievements (peut être vide)
  "achievements": [],
  
  // ⚠️ OBLIGATOIRE - Settings
  "settings": {
    "theme": "dark",
    "notifications": true,
    "soundEffects": true
  }
}
🚨 Propriétés OBLIGATOIRES
  • stats — Sans ça : Cannot read properties of undefined (reading 'dossiersCreated')
  • skills — Requis pour l'affichage du profil
  • achievements — Peut être [] mais doit exister
  • settings — Requis pour les préférences

Agent minimal (pour démarrer)

{
  "codename": "NOUVEAU-AGENT",
  "level": 1,
  "xp": 0,
  "xpToNext": 1000,
  "clearance": 0,
  "lastLogin": "2026-01-06",
  "skills": {
    "investigation": { "level": 1, "xp": 0 },
    "network": { "level": 1, "xp": 0 },
    "analysis": { "level": 1, "xp": 0 },
    "documentation": { "level": 1, "xp": 0 },
    "fieldwork": { "level": 1, "xp": 0 },
    "opsec": { "level": 1, "xp": 0 }
  },
  "stats": {
    "dossiersCreated": 0,
    "entitiesCreated": 0,
    "contactsAdded": 0,
    "notesWritten": 0,
    "missionsCompleted": 0,
    "linksDiscovered": 0,
    "daysActive": 1,
    "totalActions": 0
  },
  "achievements": [],
  "settings": {
    "theme": "dark",
    "notifications": true,
    "soundEffects": true
  }
}

📁 Dossiers

Clé localStorage

kern_dossiers

Type

Array d'objets dossier

Structure d'un dossier

{
  "id": "dossier_xxx_001",              // Requis - ID unique
  "created": "2025-06-15T10:00:00.000Z", // ISO date
  "updated": "2026-01-05T18:30:00.000Z", // ISO date
  "title": "🔥 Titre du dossier",         // Requis
  "description": "Description longue...",   // Texte
  "status": "active",                      // active|completed|archived
  "priority": "critical",                  // critical|high|medium|low
  "tags": ["tag1", "tag2"],                // Array de strings
  
  // Timeline - événements chronologiques
  "timeline": [
    { 
      "date": "2025-06-15", 
      "event": "Description de l'événement", 
      "type": "discovery"  // discovery|breakthrough|intel|critical|meeting|incident
    }
  ],
  
  // Preuves
  "evidence": [
    { 
      "id": "ev_001", 
      "type": "document",  // document|artifact|testimony|data
      "title": "Titre preuve", 
      "source": "Source", 
      "reliability": 4  // 1-5
    }
  ],
  
  // Liens vers autres éléments
  "linkedEntities": ["entity_xxx"],   // IDs d'entités
  "linkedContacts": ["contact_xxx"]   // IDs de contacts
}

Statuts possibles

ValeurDescription
activeDossier en cours
completedDossier terminé
archivedDossier archivé

Priorités possibles

ValeurCouleur
critical🔴 Rouge
high🟠 Orange
medium🟡 Jaune
low🟢 Vert

🕸️ Entités (PANOPTICON)

Clé localStorage

kern_entities

Type

Array d'objets entité

Structure d'une entité

{
  "id": "entity_xxx",                    // Requis - ID unique
  "name": "Nom de l'entité",              // Requis
  "type": "person",                        // Requis - voir types
  "subtype": "Sous-catégorie",            // Optionnel
  "emoji": "👤",                           // Optionnel - icône
  "description": "Description...",        // Texte
  "tags": ["tag1", "tag2"],                // Array
  "created": "2025-01-01T00:00:00.000Z", // ISO date
  
  // Liens vers autres entités
  "links": [
    { 
      "targetId": "entity_yyy",  // ID cible
      "type": "controls",        // Type de relation
      "label": "Contrôle"         // Label affiché
    }
  ]
}

Types d'entité

TypeIcôneCouleur
person👤#6366f1 (indigo)
organization🏛️#22d3ee (cyan)
company🏢#4ade80 (vert)
media📰#fbbf24 (ambre)
institution🏦#a78bfa (violet)
event📅#f87171 (rouge)
document📄#f472b6 (rose)
location📍#38bdf8 (bleu)
other#888 (gris)

Types de liens

Les types de liens sont libres. Exemples courants :

👥 Contacts (Network)

Clé localStorage

kern_network_contacts

Type

Array d'objets contact

Structure d'un contact

{
  "id": "contact_xxx",                    // Requis - ID unique
  "firstName": "Prénom",                   // Requis
  "lastName": "Nom",                       // Requis
  "emoji": "🧙‍♂️",                          // Avatar emoji
  "organization": "Nom organisation",     // Employeur
  "role": "Poste/Fonction",                // Titre
  "category": "ally",                      // Voir catégories
  "strength": 5,                           // Force du lien 1-5
  
  // Coordonnées
  "email": "email@example.com",
  "phone": "+32 XXX XX XX XX",
  "location": "Ville, Pays",
  
  "notes": "Notes sur le contact...",
  "tags": ["tag1", "tag2"],
  "lastContact": "2026-01-05",            // Date YYYY-MM-DD
  
  // Connexions avec autres contacts
  "connections": ["contact_yyy", "contact_zzz"]
}

Catégories de contact

CatégorieIcôneDescription
ally🤝Allié, soutien actif
source🎭Source d'information
professional💼Contact professionnel
official🏛️Officiel, institutionnel
media📰Journaliste, média
academic🎓Académique, chercheur
other👤Autre

🧠 Notes (Knowledge Graph)

Clé localStorage

kern_knowledge

Type

Array d'objets note

Structure d'une note

{
  "id": "note_xxx",                       // Requis - ID unique
  "title": "Titre de la note",             // Requis
  "content": "Contenu en **Markdown**...", // Markdown supporté
  "tags": ["tag1", "tag2"],
  "created": "2025-06-20T10:00:00.000Z",
  "updated": "2026-01-05T14:00:00.000Z",
  
  // Liens vers autres notes (par titre)
  "linkedNotes": ["note_yyy", "note_zzz"]
}

Liens Wiki-style

Dans le contenu, utilisez [[Titre de note]] pour créer des liens :

Voir aussi [[L'Anneau Unique]] et [[Sauron]].
💡 Markdown supporté
  • # Titre, ## Sous-titre
  • **gras**, *italique*
  • - liste, 1. liste numérotée
  • [lien](url)
  • `code`

🎯 Missions

Clé localStorage

kern_missions

Type

Array d'objets mission

Structure d'une mission

{
  "id": "mission_001",                   // Requis - ID unique
  "emoji": "🔥",                          // Icône
  "name": "Nom de la mission",            // Requis
  "description": "Description...",        // Texte
  "difficulty": "hard",                   // easy|medium|hard|expert
  "xpReward": 2000,                       // XP gagnés
  "status": "active",                     // active|completed
  "created": "2025-12-25T00:00:00.000Z",
  
  // Liste des objectifs
  "requirements": [
    "Objectif 1",
    "Objectif 2",
    "Objectif 3"
  ],
  
  // Indices des objectifs complétés (0-based)
  "completedReqs": [0, 1]  // Objectifs 1 et 2 faits
}

Niveaux de difficulté

DifficultéXP typique
easy100-500
medium500-1500
hard1500-3000
expert3000-10000

📓 Journal

Clé localStorage

kern_journal

Type

Array d'objets entrée

Structure d'une entrée

{
  "id": "journal_001",                   // Requis - ID unique
  "content": "Contenu de l'entrée...\n\nSupporte le Markdown.",
  "tags": ["tag1", "tag2"],
  "createdAt": "2025-12-25T18:00:00.000Z",
  "updatedAt": "2025-12-25T18:00:00.000Z"
}

🤝 Partenaires

Clé localStorage

kern_partners

Type

Array d'objets partenaire

Structure d'un partenaire

{
  "id": "partner_xxx",
  "emoji": "🏭",
  "name": "Nom du partenaire",
  "tagline": "Slogan ou accroche",
  "sector": "Industrie",
  "revenue": 15000000,                   // CA en euros
  "tier": "platinum",                     // free|silver|gold|platinum|diamond
  "status": "active",                     // active|prospect|negotiation|premium
  "website": "https://example.com",
  "description": "Description...",
  "email": "contact@example.com",
  "phone": "+32 XXX",
  "address": "Adresse",
  
  // Produits/Services
  "products": [
    {
      "name": "Nom produit",
      "icon": "⚙️",
      "price": "€2,499",
      "description": "Description"
    }
  ]
}

⚡ Protocole Insurrection

Clé localStorage

kern_protocole

Type

Object (pas un Array !)

Structure

{
  // Missions du protocole
  "missions": [
    {
      "id": "proto_mission_01",
      "type": "tutorial",              // tutorial|campaign
      "name": "LA MÉGA-CORPORATION",
      "target": "Colruyt Group",
      "objective": "Description...",
      "difficulty": 60,             // 0-100
      "xp": 500,
      
      // Pour type "tutorial" - phases
      "phases": [
        {
          "name": "SCAN",
          "status": "completed",  // completed|active|pending
          "steps": ["Étape 1", "Étape 2"]
        }
      ],
      
      // Pour type "campaign" - niveaux
      "levels": [
        {
          "name": "OPÉRATEUR",
          "status": "active",
          "actions": ["Action 1"]
        }
      ]
    }
  ],
  
  // Flashcards
  "flashcards": [
    {
      "q": "Question ?",
      "a": "Réponse",
      "category": "partenariat"
    }
  ],
  
  // Données spécifiques (ex: Colruyt)
  "colruyt": {
    "portes": [...],
    "kpis": [...],
    "winWinWin": {...}
  }
}

📥 Import / Export

Format de fichier d'export complet

Un export complet KERN est un fichier JSON avec toutes les clés :

{
  "kern_agent_profile": { ... },    // ⚠️ Pas "kern_agent" !
  "kern_dossiers": [ ... ],
  "kern_entities": [ ... ],
  "kern_network_contacts": [ ... ],
  "kern_knowledge": [ ... ],
  "kern_missions": [ ... ],
  "kern_journal": [ ... ],
  "kern_partners": [ ... ],
  "kern_protocole": { ... }
}
🚨 PIÈGES À ÉVITER
  1. Mauvaise clé agent : kern_agentkern_agent_profile
  2. Agent sans stats : L'objet stats est obligatoire
  3. JSON invalide : Virgules en trop, guillemets manquants
  4. Fichier JS au lieu de JSON : Ne pas utiliser (function(){...})()

Import via import.html

La page import.html corrige automatiquement :

Export depuis la console

// Exporter toutes les données KERN
const exportData = {
  kern_agent_profile: JSON.parse(localStorage.getItem('kern_agent_profile')),
  kern_dossiers: JSON.parse(localStorage.getItem('kern_dossiers') || '[]'),
  kern_entities: JSON.parse(localStorage.getItem('kern_entities') || '[]'),
  kern_network_contacts: JSON.parse(localStorage.getItem('kern_network_contacts') || '[]'),
  kern_knowledge: JSON.parse(localStorage.getItem('kern_knowledge') || '[]'),
  kern_missions: JSON.parse(localStorage.getItem('kern_missions') || '[]'),
  kern_journal: JSON.parse(localStorage.getItem('kern_journal') || '[]'),
  kern_partners: JSON.parse(localStorage.getItem('kern_partners') || '[]'),
  kern_protocole: JSON.parse(localStorage.getItem('kern_protocole') || 'null')
};

// Télécharger
const blob = new Blob([JSON.stringify(exportData, null, 2)], {type: 'application/json'});
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'kern-backup-' + new Date().toISOString().slice(0,10) + '.json';
a.click();

Import depuis la console

// Coller le JSON dans la variable 'data'
const data = { /* votre JSON ici */ };

// Importer
Object.keys(data).forEach(key => {
  if (data[key]) {
    // Corriger la clé agent si nécessaire
    const targetKey = key === 'kern_agent' ? 'kern_agent_profile' : key;
    localStorage.setItem(targetKey, JSON.stringify(data[key]));
    console.log('Imported:', targetKey);
  }
});

// Recharger
location.reload();

🔧 Dépannage

Erreur : "Cannot read properties of undefined (reading 'dossiersCreated')"

Cause : L'objet stats manque dans le profil agent.

Solution :

  1. Ouvrir import.html
  2. Cliquer "🗑️ Tout effacer"
  3. Importer un fichier JSON corrigé avec stats

Erreur : Données non visibles après import

Cause : Mauvaise clé localStorage.

Vérifier :

  • kern_agent_profile (pas kern_agent)
  • kern_network_contacts (pas kern_contacts)
  • kern_knowledge (pas kern_notes)

Erreur : "Unexpected token" à l'import

Cause : Le fichier n'est pas du JSON valide.

Vérifier :

  • Pas de commentaires // ou /* */
  • Pas de code JavaScript (function(){...})()
  • Pas de virgule après le dernier élément
  • Guillemets doubles " partout (pas simples ')

Comment voir le contenu du localStorage

// Dans la console du navigateur (F12)

// Voir toutes les clés KERN
Object.keys(localStorage).filter(k => k.startsWith('kern_'));

// Voir le contenu d'une clé
JSON.parse(localStorage.getItem('kern_agent_profile'));

// Tout effacer
Object.keys(localStorage).filter(k => k.startsWith('kern_'))
  .forEach(k => localStorage.removeItem(k));

Reset complet

// Supprimer TOUTES les données KERN
Object.keys(localStorage)
  .filter(k => k.startsWith('kern_'))
  .forEach(k => localStorage.removeItem(k));
  
// Recharger la page
location.reload();

Valider un fichier JSON

Avant d'importer, validez votre JSON :