Traducción. Autoritativo: fs-core-0008-segments.md.
Contexto
Los segmentos son lo que convierte eventos almacenados en algo sobre lo que un marketero puede actuar, y la diferencia entre un segmento que se actualiza en segundos y uno que se actualiza de un día para otro es la diferencia entre una campaña que llega durante una venta flash y una que llega después. ADR-012 hace un canje deliberado: el DSL está restringido para que la evaluación incremental sea posible. Un lenguaje de consulta general sería más expresivo y obligaría a recalcular todo con cada evento. Restringir la gramática a condiciones cuya verdad solo puede cambiar de formas conocidas significa que un evento toca únicamente los segmentos que realmente puede afectar. Ser honesto sobre el límite es parte del diseño: un segmento que no se puede evaluar incrementalmente se marcanightly_only al crearse, para que quien lo construye lo sepa antes de
depender de él.
Alcance (normativo)
- El DSL JSON versionado: atributos de perfil tipados, agregados de eventos sobre una ventana, pertenencia a otros segmentos y niveles, AND/OR/NOT.
- Evaluación incremental en cada evento registrado.
core.segment_memberscon historia de entrada y salida.core.segment.enteredycore.segment.exited.- Detección de
nightly_onlyal crear, expuesta en el constructor. - Recálculo completo por tenant como red de seguridad, al tier de frescura.
- Plantillas RFM preconstruidas por taxonomía vertical.
Fuera de alcance (normativo)
- La UI del constructor de segmentos —
frontend/console. - Enviar a un segmento —
messaging. - Segmentos predictivos o derivados de ML. No planificado: son inexplicables para quien tiene que defender la campaña.
- Extender el DSL ad hoc. Un tipo de nodo nuevo es un cambio versionado con su propio spec.
Comportamiento (normativo)
- El DSL es versionado. Un segmento registra la versión del DSL contra la que se escribió, de modo que un cambio de gramática nunca reinterpreta silenciosamente una definición existente.
- La gramática es cerrada: comparaciones de atributos tipados, agregados de eventos (
count,sum(propiedad),first_seen,last_seen) sobre últimos N días o todo el tiempo, pertenencia a otro segmento o nivel, y AND/OR/NOT. PROHIBIDO: SQL arbitrario, código de usuario, joins no acotados. - Las referencias entre segmentos son acíclicas, verificado al crear. Un ciclo recalcularía para siempre.
- La evaluación es incremental: un evento evalúa solo los segmentos cuyas condiciones referencian ese nombre de evento o los atributos que cambió.
- Los cambios de membresía emiten
enteredoexited. Reevaluar sin cambio no emite nada — un segmento que se redispara con cada evento haría inusables los triggers de campaña. core.segment_membersconserva historia conentered_atyexited_at. “¿Este contacto estaba en el segmento VIP cuando enviamos ese mensaje?” tiene que ser respondible.- Una definición que no se puede evaluar incrementalmente se marca
nightly_onlyal crearse y el constructor se lo dice al usuario. Descubrirlo después, con datos rancios, es la falla que esta regla previene. - El recálculo completo corre por tenant al tier de frescura (nocturno por defecto, DEC-G5) como red de seguridad, y su divergencia con el estado incremental se alerta, no se corrige en silencio.
- Editar una definición crea una versión nueva y dispara un recálculo completo de ese segmento; la membresía bajo la versión anterior queda en la historia.
Datos (normativo)
API (normativo)
preview devuelve un conteo y una muestra, nunca la membresía completa, y su presupuesto es
deliberadamente más holgado: es una herramienta de diseño, no un camino de runtime.
Eventos (normativo)
core.segment.entered y core.segment.exited, ambos disponibles como webhooks salientes y ambos
disparadores de campaña en messaging.
Criterios de aceptación (normativo)
- Una compra que cruza un umbral de segmento emite
entereden <5 s p95. - Reevaluar una membresía sin cambios no emite nada.
- Cada tipo de nodo del DSL tiene un fixture que prueba que su diff incremental es correcto.
- Una definición con una condición no evaluable incrementalmente se marca
nightly_onlyal crearse, y la respuesta lo dice. - Una referencia cíclica entre segmentos se rechaza al crear.
- El recálculo completo reconcilia un drift sembrado deliberadamente y alerta en vez de corregirlo en silencio.
- La historia de membresía responde correctamente “¿estaba el contacto X en el segmento Y en la fecha Z?”.
- Negativo: editar una definición no reescribe las filas históricas de membresía.
Ejecución
Pipeline asíncrono. Evaluación enbackend/workers dentro de la pasada del procesador de ingesta;
recálculo completo en backend/scheduler. El evaluador del DSL vive en packages/core como función
pura con fixtures exhaustivos por nodo.