¿Qué es un Xenkey?
Un Xenkey es una unidad atómica de significado sobre un objeto del mundo real — un negocio, producto, servicio, lugar, persona, proceso o evento. Está escrito para comprensión de IA, no para persuasión de marketing.
Cada Xenkey representa una sola idea mínima y falsable. La versión de la especificación se declara en cada documento:
{ "spec": "1.0" }Objetivos de diseño
Verdad sobre persuasión
Describe la realidad, no la promoción.
Contextualidad
Captura cuándo, dónde y para quién aplica.
Componibilidad
Muchos Xenkeys describen un objeto.
Legibilidad para IA
Estructura estricta para recuperación e indexación.
Identidad
| Campo | Tipo | Descripción |
|---|---|---|
| id | string | Identificador primario. Formato: xk_ + ULID |
| ulid | string | Opcional. Derivado del sufijo de id (debe coincidir si está presente) |
| spec | "1.0" | Versión de la especificación |
Ciclo de vida y mutabilidad
Los Xenkeys siguen un ciclo de vida estricto que garantiza la integridad y la confianza de los datos.
Reglas de mutabilidad
- •Draft — se puede editar libremente
- •Published — inmutable. Los cambios requieren un nuevo Xenkey
- •Si
published_atestá establecido, el estado no puede serdraft
| Campo | Tipo | Descripción |
|---|---|---|
| status | enum | draft | unpublished | published | archived |
| created_at | datetime | Marca de tiempo de creación (RFC 3339) |
| published_at | datetime | Cuándo se publicó el Xenkey |
| updated_at | datetime | Interno/solo lectura, establecido por la API |
| etag | string | Interno/solo lectura, usado para control de concurrencia |
Núcleo de significado
El corazón de cada Xenkey. Cuatro campos obligatorios que capturan una unidad estructurada de verdad.
| Campo | Tipo | Descripción |
|---|---|---|
| title | string | Identificador corto y descriptivo de la experiencia |
| fact | string | Afirmación factual y verificable sobre la realidad |
| meaning | string | Por qué este hecho importa a las personas |
| context | string | Cuándo, dónde y para quién aplica |
| constraints | string | Matiz en texto libre no capturado por campos estructurados |
Alcance y anclas
Las anclas vinculan Xenkeys a entidades del mundo real. Cada Xenkey debe tener al menos una ancla. El soporte multiancla permite que un Xenkey describa la intersección de múltiples objetos.
| Campo | Tipo | Descripción |
|---|---|---|
| organization_id | string | Organización propietaria |
| base_id | string | Agrupación lógica (workspace/proyecto) |
| unit_id | string | Referencia opcional de entrada de datos estructurada |
| anchors[] | array | Arreglo de objetos ancla (mín 1) |
{
"anchor_id": "anchor_001",
"anchor_type": "product",
"role": "primary"
}| Campo | Tipo | Descripción |
|---|---|---|
| tags | string[] | Etiquetas de clasificación (p. ej., booking_required, wifi) |
| emotions | string[] | Códigos de contexto emocional (de emotion-codes.json) |
| vibe | string | Descripción de atmósfera / estado de ánimo |
| seasons | string[] | Temporadas aplicables |
| time_of_day | string[] | Momentos del día aplicables |
| meal | string[] | Periodos de comida aplicables |
Demografía
| Campo | Tipo | Descripción |
|---|---|---|
| age_min | integer | Edad mínima recomendada |
| age_max | integer | Edad máxima recomendada (debe ser >= age_min) |
| gender | string | Género objetivo (si aplica) |
Geografía
Los Xenkeys pueden ser globales o con alcance geográfico. El campo geo_scope determina qué campos geográficos son obligatorios.
| Campo | Tipo | Descripción |
|---|---|---|
| geo_scope | enum | Nivel de precisión geográfica |
| country | string | Código de país ISO 3166-1 alpha-2 |
| region | string | Región / estado / provincia |
| city | string | Nombre de la ciudad |
| timezone | string | Zona horaria IANA (p. ej., Europe/Rome) |
| geo | [lng, lat] | Coordenadas como [longitud, latitud] |
| availability_countries | string[] | Países donde está disponible (no ubicación) |
Reglas de alcance: Si geo_scope=country entonces country es obligatorio. Si geo_scope=region entonces tanto country como region (o city) son obligatorios. Si geo_scope=point entonces geo es obligatorio.
Localización
| Campo | Tipo | Descripción |
|---|---|---|
| locale | string | Etiqueta de idioma (p. ej., en-US, ja-JP) |
| source_locale | string | Idioma original del contenido |
| translation_group | string | Agrupa traducciones. Formato: tg_ + ULID |
| is_source_locale | boolean | Verdadero si esta es la versión en el idioma original |
Regla: Si is_source_locale = true, entonces locale debe ser igual a source_locale. Las traducciones reutilizan el mismo translation_group.
Integridad
Los Xenkeys publicados incluyen un hash criptográfico calculado en el momento de publicación, garantizando la integridad del contenido.
| Campo | Tipo | Descripción |
|---|---|---|
| hash_alg | "sha256" | Algoritmo de hash utilizado |
| hash_id | string | Identificador único de hash. Formato: hash_ + ULID |
| hash | string | Hash SHA-256 del payload canónico |
Indexación y privacidad
Los Xenkeys pueden publicarse en múltiples canales. Cada canal habilita capacidades de recuperación diferentes.
| Campo | Tipo | Descripción |
|---|---|---|
| publication | string[] | Canales: vector, graph, aidex |
| is_published | boolean | Verdadero si se publica en al menos un canal |
| is_vector | boolean | Indexado en el store vectorial (Qdrant) |
| is_graph | boolean | Proyectado al grafo de conocimiento (Neo4j) |
| is_aidex | boolean | Publicado en Aidex, wiki orientada a robots |
| is_private | boolean | Visible solo para acceso con alcance de organización |
Reglas:
- •
aidexrequierevector(ambos deben estar en publication) - • Si
is_published=truepublication debe tener al menos una entrada - • Aidex es una capa wiki orientada a robots con cuotas más estrictas que la indexación vectorial
Recuperación vectorial y de grafos
Los Xenkeys publicados se transforman automáticamente en dos representaciones de datos complementarias, habilitando recuperación híbrida para IA.
Índice vectorial (Qdrant)
- • Fuente de texto:
fact + meaning + context - • Convertido a embeddings de alta dimensionalidad
- • Habilita búsqueda de similitud semántica
- • Filtros de payload: estado, geo, etiquetas, emociones, tiempo
- • Idempotencia: clave (id, version)
Grafo de conocimiento (Neo4j)
- • Nodos: Xenkey, Organization, Object, Tag, Emotion
- • Aristas: OWNS, DESCRIBED_BY, TAGS, EXPRESSES
- • Revela relaciones y estructura
- • MERGE idempotente sobre claves naturales
- • Habilita consultas de recorrido de grafos
Recuperación híbrida combina similitud vectorial con filtros estructurales de grafo, habilitando respuestas de IA fundamentadas y explicables. El pipeline de indexación es asíncrono con reintentos y colas de mensajes muertos.
Invariantes
- ✓
anchorsdeben estar presentes y no vacíos - ✓Si ambos
age_minyage_maxestán presentes: age_max >= age_min - ✓Si
geoestá presente, debe ser[longitude, latitude] - ✓
geo_scope=countryrequierecountry - ✓
geo_scope=regionrequierecountry + region (or city) - ✓
geo_scope=pointrequieregeo - ✓
aidexen publication implicavectoren publication - ✓
is_published=truerequierepublication[] no vacía
Payloads de ejemplo
Xenkey en borrador (mínimo)
{
"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 publicado (con geo + indexación vectorial)
{
"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
}Esta especificación es la referencia canónica de Xenkey spec=1.0.
Esquema JSON canónico: xenkey_schema_v1_0.json