Skip to main content
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 marca nightly_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_members con historia de entrada y salida.
  • core.segment.entered y core.segment.exited.
  • Detección de nightly_only al 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)

  1. 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.
  2. 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.
  3. Las referencias entre segmentos son acíclicas, verificado al crear. Un ciclo recalcularía para siempre.
  4. La evaluación es incremental: un evento evalúa solo los segmentos cuyas condiciones referencian ese nombre de evento o los atributos que cambió.
  5. Los cambios de membresía emiten entered o exited. Reevaluar sin cambio no emite nada — un segmento que se redispara con cada evento haría inusables los triggers de campaña.
  6. core.segment_members conserva historia con entered_at y exited_at. “¿Este contacto estaba en el segmento VIP cuando enviamos ese mensaje?” tiene que ser respondible.
  7. Una definición que no se puede evaluar incrementalmente se marca nightly_only al crearse y el constructor se lo dice al usuario. Descubrirlo después, con datos rancios, es la falla que esta regla previene.
  8. 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.
  9. 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)

  1. Una compra que cruza un umbral de segmento emite entered en <5 s p95.
  2. Reevaluar una membresía sin cambios no emite nada.
  3. Cada tipo de nodo del DSL tiene un fixture que prueba que su diff incremental es correcto.
  4. Una definición con una condición no evaluable incrementalmente se marca nightly_only al crearse, y la respuesta lo dice.
  5. Una referencia cíclica entre segmentos se rechaza al crear.
  6. El recálculo completo reconcilia un drift sembrado deliberadamente y alerta en vez de corregirlo en silencio.
  7. La historia de membresía responde correctamente “¿estaba el contacto X en el segmento Y en la fecha Z?”.
  8. Negativo: editar una definición no reescribe las filas históricas de membresía.

Ejecución

Pipeline asíncrono. Evaluación en backend/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.

Preguntas abiertas

Changelog

Registro de entrega

Aún no implementado.