Qu’est‑ce qu’un Xenkey ?
Un Xenkey est une unité atomique de sens à propos d’un objet réel — entreprise, produit, service, lieu, personne, processus ou événement. Il est écrit pour la compréhension IA, pas pour la persuasion marketing.
Chaque Xenkey représente une seule idée minimale et falsifiable. La version de spécification est déclarée dans chaque document :
{ "spec": "1.0" }Objectifs de conception
Vérité plutôt que persuasion
Décrire la réalité, pas la promotion.
Contextualité
Capturer quand, où et pour qui cela s’applique.
Composabilité
De nombreux Xenkeys décrivent un objet.
Lisibilité IA
Structure stricte pour la récupération et l’indexation.
Identité
| Champ | Type | Description |
|---|---|---|
| id | string | Identifiant principal. Format : xk_ + ULID |
| ulid | string | Optionnel. Dérivé du suffixe id (doit correspondre si présent) |
| spec | "1.0" | Version de la spécification |
Cycle de vie & mutabilité
Les Xenkeys suivent un cycle de vie strict garantissant l’intégrité et la confiance des données.
Règles de mutabilité
- •Draft — peut être modifié librement
- •Published — immuable. Les changements nécessitent un nouveau Xenkey
- •Si
published_atest défini, le statut ne peut pas êtredraft
| Champ | Type | Description |
|---|---|---|
| status | enum | draft | unpublished | published | archived |
| created_at | datetime | Horodatage de création (RFC 3339) |
| published_at | datetime | Quand le Xenkey a été publié |
| updated_at | datetime | Interne/lecture seule, défini par l’API |
| etag | string | Interne/lecture seule, utilisé pour la concurrence |
Cœur du sens
Le cœur de chaque Xenkey. Quatre champs obligatoires qui capturent une unité structurée de vérité.
| Champ | Type | Description |
|---|---|---|
| title | string | Identifiant court et descriptif de l’expérience |
| fact | string | Affirmation factuelle et vérifiable sur la réalité |
| meaning | string | Pourquoi ce fait compte pour les humains |
| context | string | Quand, où et pour qui cela s’applique |
| constraints | string | Nuance en texte libre non capturée par des champs structurés |
Portée & ancres
Les ancres relient les Xenkeys aux entités du monde réel. Chaque Xenkey doit avoir au moins une ancre. Le support multi‑ancres permet à un Xenkey de décrire l’intersection de plusieurs objets.
| Champ | Type | Description |
|---|---|---|
| organization_id | string | Organisation propriétaire |
| base_id | string | Regroupement logique (workspace/projet) |
| unit_id | string | Référence optionnelle à une entrée de données structurée |
| anchors[] | array | Tableau d’objets ancre (min 1) |
{
"anchor_id": "anchor_001",
"anchor_type": "product",
"role": "primary"
}| Champ | Type | Description |
|---|---|---|
| tags | string[] | Tags de classification (ex. booking_required, wifi) |
| emotions | string[] | Codes de contexte émotionnel (depuis emotion-codes.json) |
| vibe | string | Description d’ambiance / humeur |
| seasons | string[] | Saisons applicables |
| time_of_day | string[] | Moments de la journée applicables |
| meal | string[] | Périodes de repas applicables |
Démographie
| Champ | Type | Description |
|---|---|---|
| age_min | integer | Âge minimum recommandé |
| age_max | integer | Âge maximum recommandé (doit être >= age_min) |
| gender | string | Genre cible (si applicable) |
Géographie
Les Xenkeys peuvent être globaux ou à portée géographique. Le champ geo_scope détermine quels champs géographiques sont requis.
| Champ | Type | Description |
|---|---|---|
| geo_scope | enum | Niveau de précision géographique |
| country | string | Code pays ISO 3166‑1 alpha‑2 |
| region | string | Région / état / province |
| city | string | Nom de la ville |
| timezone | string | Fuseau horaire IANA (ex. Europe/Rome) |
| geo | [lng, lat] | Coordonnées comme [longitude, latitude] |
| availability_countries | string[] | Pays où disponible (pas l’emplacement) |
Règles de portée : Si geo_scope=country alors country est requis. Si geo_scope=region alors country et region (ou city) sont requis. Si geo_scope=point alors geo est requis.
Localisation
| Champ | Type | Description |
|---|---|---|
| locale | string | Tag de langue (ex. en‑US, ja‑JP) |
| source_locale | string | Langue d’origine du contenu |
| translation_group | string | Groupe les traductions. Format : tg_ + ULID |
| is_source_locale | boolean | Vrai si c’est la version dans la langue d’origine |
Règle : Si is_source_locale = true, alors locale doit être égal à source_locale. Les traductions réutilisent le même translation_group.
Intégrité
Les Xenkeys publiés incluent un hash cryptographique calculé au moment de la publication, garantissant l’intégrité du contenu.
| Champ | Type | Description |
|---|---|---|
| hash_alg | "sha256" | Algorithme de hash utilisé |
| hash_id | string | Identifiant unique du hash. Format : hash_ + ULID |
| hash | string | Hash SHA‑256 du payload canonique |
Indexation & confidentialité
Les Xenkeys peuvent être publiés sur plusieurs canaux. Chaque canal active des capacités de récupération différentes.
| Champ | Type | Description |
|---|---|---|
| publication | string[] | Canaux : vector, graph, aidex |
| is_published | boolean | Vrai si publié sur au moins un canal |
| is_vector | boolean | Indexé dans le store vectoriel (Qdrant) |
| is_graph | boolean | Projeté dans le graphe de connaissance (Neo4j) |
| is_aidex | boolean | Publié dans Aidex, wiki orientée robots |
| is_private | boolean | Visible uniquement pour un accès à portée organisation |
Règles :
- •
aidexexigevector(les deux doivent être en publication) - • Si
is_published=truepublication doit avoir au moins une entrée - • Aidex est une couche wiki orientée robots avec des quotas plus stricts que l’indexation vectorielle
Récupération vectorielle & graphe
Les Xenkeys publiés se transforment automatiquement en deux représentations de données complémentaires, permettant une récupération hybride pour l’IA.
Index vectoriel (Qdrant)
- • Source du texte :
fact + meaning + context - • Converti en embeddings de haute dimension
- • Permet la recherche de similarité sémantique
- • Filtres de payload : status, geo, tags, emotions, time
- • Idempotence : clé (id, version)
Graphe de connaissance (Neo4j)
- • Nœuds : Xenkey, Organization, Object, Tag, Emotion
- • Arêtes : OWNS, DESCRIBED_BY, TAGS, EXPRESSES
- • Révèle relations et structures
- • MERGE idempotent sur clés naturelles
- • Permet les requêtes de parcours de graphe
Récupération hybride combine similarité vectorielle et filtres structuraux de graphe, permettant des réponses IA fondées et explicables. Le pipeline d’indexation est asynchrone avec retries et files de lettres mortes.
Invariants
- ✓
anchorsdoivent être présents et non vides - ✓Si
age_minetage_maxsont présents : age_max >= age_min - ✓Si
geoest présent, il doit être[longitude, latitude] - ✓
geo_scope=countryexigecountry - ✓
geo_scope=regionexigecountry + region (or city) - ✓
geo_scope=pointexigegeo - ✓
aidexen publication impliquevectoren publication - ✓
is_published=trueexigepublication[] non vide
Payloads d’exemple
Brouillon Xenkey (minimum)
{
"spec": "1.0",
"id": "xk_01J8Y6S4V9ZQ3M9K2W2M8JQY5C",
"status": "draft",
"created_at": "2026-01-21T12:00:00Z",
"organization_id": "org_123",
"base_id": "base_123",
"anchors": [
{ "anchor_id": "anchor_1", "anchor_type": "product", "role": "primary" }
],
"title": "Fresh espresso",
"fact": "A 30 ml espresso shot made from 100% Arabica beans.",
"meaning": "Represents the cafe's standard espresso offering.",
"context": "Default menu item available all day.",
"locale": "en-US",
"source_locale": "en-US",
"translation_group": "tg_01J8Y6S6Q4K8FKJ1PS2H0WQ1B8",
"is_source_locale": true,
"hash_alg": "sha256",
"hash_id": "hash_01J8Y6S6Q4K8FKJ1PS2H0WQ1B9",
"hash": "6e4f8c9d8b0f7a6d3b3a0f3c1f8e9d6e...",
"is_vector": false,
"is_graph": false,
"is_aidex": false,
"publication": [],
"is_published": false,
"is_private": false
}Xenkey publié (avec geo + indexation vectorielle)
{
"spec": "1.0",
"id": "xk_01J8Y6S9QH8P2G8P6X1K3R2H5A",
"status": "published",
"created_at": "2026-01-21T12:05:00Z",
"published_at": "2026-01-21T12:10:00Z",
"organization_id": "org_123",
"base_id": "base_123",
"unit_id": "unit_456",
"anchors": [
{ "anchor_id": "anchor_1", "anchor_type": "product", "role": "primary" }
],
"title": "Fresh espresso",
"fact": "A 30 ml espresso shot made from 100% Arabica beans.",
"meaning": "Represents the cafe's standard espresso offering.",
"context": "Default menu item available all day.",
"tags": ["coffee", "espresso", "menu_item"],
"time_of_day": ["morning", "afternoon"],
"meal": ["breakfast", "coffee_time"],
"vibe": "energetic",
"geo_scope": "point",
"country": "IT",
"city": "Milan",
"timezone": "Europe/Rome",
"geo": [9.1900, 45.4642],
"locale": "en-US",
"source_locale": "en-US",
"translation_group": "tg_01J8Y6S6Q4K8FKJ1PS2H0WQ1B8",
"is_source_locale": true,
"hash_alg": "sha256",
"hash_id": "hash_01J8Y6S6Q4K8FKJ1PS2H0WQ1B9",
"hash": "6e4f8c9d8b0f7a6d3b3a0f3c1f8e9d6e...",
"is_vector": true,
"is_graph": false,
"is_aidex": false,
"publication": ["vector"],
"is_published": true,
"is_private": false
}Cette spécification est la référence canonique de Xenkey spec=1.0.
Schéma JSON canonique : xenkey_schema_v1_0.json