> ## Documentation Index
> Fetch the complete documentation index at: https://internal.softcrum.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Registro de Preguntas Abiertas (v1.0)

> Consolida toda pregunta abierta que hoy impide que un spec pase a approved. Formato de respuesta: OQ-XXX-NN: respuesta. Cada una lleva mi recomendación (REC).

> Consolida toda pregunta abierta que hoy impide que un spec pase a `approved`.
> Formato de respuesta: `OQ-XXX-NN: respuesta`. Cada una lleva mi recomendación (**REC**).
> Al responderse, la decisión se traslada al spec correspondiente, el spec sube a `1.0.0`, y esta
> fila se marca cerrada. Las respuestas que cambian una decisión ya cerrada del
> [registro de decisiones](/design/decision-registry-v1) exigen un ADR primero.

Estado: **0 abiertas** · **27 cerradas el 2026-08-17** · los 14 specs de fidelización y su PRD
quedaron en `0.2.0` / `review`, esperando solo el visto bueno para pasar a `approved` y `1.0.0`.

Dos respuestas cambiaron el diseño y no solo lo ratificaron:

* **OQ-LOY-02** — la expiración pasa a ser política de la **moneda de puntos**, no de su tipo. Los
  puntos de estatus pueden expirar o no, según lo configure cada empresa. Consecuencia que se cerró
  en el mismo movimiento: cuando una moneda de estatus expira, el período de gracia y el evento
  `tier.grace_started` dejan de ser opcionales, porque si no un member pierde nivel sin haber
  dejado de comprar.
* **OQ-LOY-07** — multi-programa es capacidad de primera clase en F1. Revierte DEC-H2, así que
  primero se escribió [ADR-021](/adr/adr-021-multi-program-from-day-one) y desde ahí se
  aplicó a los specs. La cantidad de programas es un **entitlement**, no una métrica medida.

Además, **OQ-LOY-14** dejó un principio transversal que ahora vive en `standards/api.md`: todo
parámetro de política es configurable por tenant con un default publicado.

***

## Bloqueantes de fase F1a

Estas siete impiden aprobar los seis specs que componen F1a, y por lo tanto impiden escribir código
bajo la regla R-S1. Son las primeras que necesito.

| ID              | Pregunta                                                                                                              | Afecta                        | REC                                                                                                                                                                                                                                                                      |
| --------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ✅ **OQ-LOY-01** | ¿La ventana de devolución (el tiempo que un `earn` queda `pending`) vive en el programa o por regla de acumulación?   | FS-LOY-0002                   | **Por programa.** Por regla es más expresivo, pero un member que ve dos acumulaciones distintas volverse disponibles en plazos distintos no lo entiende, y soporte tampoco. La expresividad la puede dar una regla que simplemente no acredite hasta el evento correcto. |
| ✅ **OQ-LOY-02** | ¿Los puntos de estatus expiran, o solo los canjeables?                                                                | FS-LOY-0002, FS-LOY-0010, PRD | **Los de estatus no expiran por lote; caducan por ventana de calificación.** Son dos mecanismos distintos y mezclarlos produce el bug clásico de que alguien pierde nivel por una expiración que no vio. La ventana de calificación ya hace ese trabajo.                 |
| ✅ **OQ-LOY-03** | ¿`revoke` es distinto de un `adjust` negativo, o la distinción es solo de reportería?                                 | FS-LOY-0002                   | **Distinto, y la diferencia es intención.** `revoke` es "esto nunca debió acreditarse" (fraude, reversa); `adjust` es "corregimos un monto". Reportería, disputas y antifraude necesitan separarlos, y el costo es una fila en un catálogo.                              |
| ✅ **OQ-LOY-04** | ¿`points_lifetime_earned` vive en `contact_balances` o en una proyección de reportería aparte?                        | FS-LOY-0003                   | **En `contact_balances`.** Crece monótonamente y se actualiza en la misma transacción que ya está abierta; una proyección aparte agrega un job por un entero.                                                                                                            |
| ✅ **OQ-LOY-05** | Cuando varias reglas calzan con un evento, ¿aplican todas o una prioridad se detiene en la primera?                   | FS-LOY-0004                   | **Aplican todas, con `stop_on_match` opcional por regla.** El caso común es acumulativo (una regla base más una campaña). Detenerse por defecto sorprende; permitir detenerse explícitamente cubre el caso exclusivo.                                                    |
| ✅ **OQ-LOY-06** | ¿El presupuesto por contacto se evalúa sobre la vida de la campaña o sobre una ventana móvil?                         | FS-LOY-0004                   | **Vida de la campaña.** Una campaña ya tiene ventana de vigencia; una ventana móvil dentro de otra ventana es difícil de explicar y de auditar. Quien quiera recurrencia crea campañas sucesivas.                                                                        |
| ✅ **OQ-LOY-07** | ¿El programa por defecto recibe un nombre visible para el tenant, o uno interno fijo hasta que llegue multi-programa? | FS-LOY-0001                   | **Interno fijo.** En v1 el tenant no debe enterarse de que existe el concepto de programa; darle un nombre editable lo expone antes de tiempo y crea expectativa de que puede crear otro.                                                                                |

## Fase F1b

| ID              | Pregunta                                                                                                                       | Afecta      | REC                                                                                                                                                                                                                                             |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------ | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ✅ **OQ-LOY-08** | ¿`per_contact_limit` de una recompensa se cuenta sobre la vida del member o sobre un período móvil?                            | FS-LOY-0005 | **Configurable, con default vida.** "Una vez por cliente" es el caso dominante; "una vez al mes" es real pero minoritario. Un campo `limit_window_days` nullable cubre ambos sin bifurcar la lógica.                                            |
| ✅ **OQ-LOY-09** | Al revertir un canje, ¿los puntos restaurados mantienen su vencimiento original o se reinicia?                                 | FS-LOY-0006 | **Mantienen el original.** Reiniciar convierte el rollback en una forma de extender vencimientos, y alguien lo va a descubrir. Si el lote original ya expiró, el spec ya define un lote nuevo que hereda el vencimiento más próximo.            |
| ✅ **OQ-LOY-10** | ¿Hay un límite de tiempo tras el cual un canje ya no se puede revertir?                                                        | FS-LOY-0006 | **Sí, configurable por programa, default 90 días.** Sin límite, un canje de hace dos años se puede revertir contra un saldo y un catálogo que ya no existen.                                                                                    |
| ✅ **OQ-LOY-11** | Largo y alfabeto del código de cupón: ¿cuánta entropía frente a que sea legible en voz alta?                                   | FS-LOY-0007 | **10 caracteres sobre alfabeto Crockford Base32** (sin I, L, O, U). Da \~50 bits, que con rate limiting es holgado, y se dicta por teléfono sin ambigüedad.                                                                                     |
| ✅ **OQ-LOY-12** | ¿Un código genérico se puede restringir a un segmento en vez de a un contacto?                                                 | FS-LOY-0007 | **Sí.** Es la forma natural de una campaña ("20% para clientes VIP") y el segmento ya existe en `core`. La validación agrega una verificación de pertenencia, nada más.                                                                         |
| ✅ **OQ-LOY-13** | Cuando se viola un conjunto no combinable, ¿el motor conserva el beneficio de mayor precedencia o rechaza el request completo? | FS-LOY-0008 | **Conserva el de mayor precedencia y reporta la exclusión.** Rechazar todo en un mostrador deja al cajero sin salida; conservar el mejor beneficio es lo que el cliente espera y la razón tipada explica por qué el otro no aplicó.             |
| ✅ **OQ-LOY-14** | Ventana de atribución de referidos por defecto: ¿30, 60 o 90 días?                                                             | FS-LOY-0009 | **60 días.** 30 castiga ciclos de compra lentos (suscripciones, servicios); 90 amplía la ventana de fraude y diluye la atribución.                                                                                                              |
| ✅ **OQ-LOY-15** | ¿Las conversiones marcadas por fraude expiran si nadie las revisa, y después de cuánto?                                        | FS-LOY-0009 | **No expiran; escalan.** A los 14 días sin revisar, alerta al tenant. Expirarlas automáticamente significa perder referidos legítimos por inacción administrativa, que es exactamente lo que la política de "marcar, no rechazar" quiso evitar. |
| ✅ **OQ-LOY-16** | Ventana de calificación de niveles por defecto: ¿12 meses móviles o año calendario?                                            | FS-LOY-0010 | **12 meses móviles.** Es continua y justa, y evita el precipicio de enero. El año calendario existe como modo para quien lo pida, pero no como default.                                                                                         |
| ✅ **OQ-LOY-17** | ¿Entrar en período de gracia emite un evento, para poder hacer una campaña "estás a punto de perder Gold"?                     | FS-LOY-0010 | **Sí, `loyalty.tier.grace_started`.** Es una de las campañas de retención de mayor rendimiento del formato, y omitir el evento la haría imposible sin sondear la base.                                                                          |
| ✅ **OQ-LOY-18** | ¿Un member puede saltarse un nivel cuando un solo evento cruza dos umbrales?                                                   | FS-LOY-0010 | **Sí, salta al nivel más alto alcanzado, y emite un solo evento.** Retenerlo un escalón es arbitrario y el member ya cumplió el umbral.                                                                                                         |
| ✅ **OQ-LOY-19** | Horizontes de aviso de vencimiento por defecto: ¿30 y 7 días, o un único aviso a 14?                                           | FS-LOY-0011 | **30 y 7.** El de 30 da tiempo real de reaccionar; el de 7 es el que convierte. Uno solo a 14 es un compromiso que no hace bien ninguna de las dos cosas.                                                                                       |
| ✅ **OQ-LOY-20** | ¿`cohort_key` es la fecha de vencimiento o el mes?                                                                             | FS-LOY-0011 | **La fecha.** El mes agrupa lotes con vencimientos distintos en un solo aviso, y el member recibe "vencen 1 200 puntos" cuando en realidad vencen 400 el día 3 y 800 el día 28.                                                                 |

## Fase F2

| ID              | Pregunta                                                                                                   | Afecta      | REC                                                                                                                                                                                                         |
| --------------- | ---------------------------------------------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ✅ **OQ-LOY-21** | ¿Un desafío puede ser repetible (mensual, con reinicio), o cada instancia es un desafío distinto?          | FS-LOY-0012 | **Instancias distintas, generadas por una plantilla.** Un desafío repetible con reinicio destruye la historia de participación; instancias separadas la conservan y el reporte funciona solo.               |
| ✅ **OQ-LOY-22** | ¿Las insignias otorgan puntos de estatus, convirtiéndolas en entrada de nivel?                             | FS-LOY-0012 | **No por sí mismas; sí como efecto de regla opcional.** Acoplar insignias a niveles hace que cada insignia nueva mueva la distribución de niveles sin que nadie lo pretenda.                                |
| ✅ **OQ-LOY-23** | TTL de reserva de presupuesto en `apply_discount`: ¿15, 30 o 60 minutos?                                   | FS-LOY-0013 | **30 minutos.** Cubre un checkout con fricción real (pago rechazado, cambio de tarjeta) sin inmovilizar presupuesto de campaña por carros abandonados.                                                      |
| ✅ **OQ-LOY-24** | ¿Soportamos descuentos por línea en la primera versión de `apply_discount`, o solo a nivel de carro?       | FS-LOY-0013 | **Solo carro en la primera versión.** Por línea exige un modelo de producto y de categorías que hoy no tenemos, y el 80% de las promociones son a nivel de carro.                                           |
| ✅ **OQ-LOY-25** | ¿El snapshot del carro queda sujeto al tier de retención estándar, o a uno más corto por no ser una orden? | FS-LOY-0013 | **Más corto: 90 días fijos.** Sirve para reconciliación y disputa; conservar carros por 25 meses acumula datos de comportamiento de compra que no necesitamos y que sí tendríamos que defender.             |
| ✅ **OQ-LOY-26** | Ventana de agrupación de push de wallet passes: ¿5, 15 o 60 minutos?                                       | FS-LOY-0014 | **15 minutos.** A 5 el member siente cada compra; a 60 el saldo del pass se ve desactualizado justo cuando lo abre en la caja.                                                                              |
| ✅ **OQ-LOY-27** | ¿El wallet pass se ofrece automáticamente a cada member, o solo a solicitud?                               | FS-LOY-0014 | **A solicitud, con un enlace prominente.** Empujarlo automáticamente exige un push que el member no pidió y en Apple es fricción de revisión; el enlace en el correo de bienvenida convierte igual de bien. |

## Bloqueadas por otra cosa, no por una decisión

| ID              | Tema                                                                       | Afecta               | Estado                                                                                                                                                                                                                                                                                                                                                                                             |
| --------------- | -------------------------------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **P-3**         | Precios unitarios por métrica medida                                       | PRD-LOY, ADR-016     | **Método acordado**: piso por costo real del stack, techo por anclaje de mercado, cuotas del primer plan que cubran el año uno del design partner. El entregable que falta es el *modelo de costos*, y debe existir **antes de G1**, no antes del lanzamiento: si servir resulta más caro de lo que el mercado paga por contacto, se quiere saber cuando todavía se puede cambiar la arquitectura. |
| ✅ **OQ-LOY-28** | Librerías de firma de wallet passes (Apple y Google)                       | FS-LOY-0014          | Necesita **un ADR nuevo** (DEC-H5). No es una pregunta, es trabajo de investigación. El FS no sale de `draft` hasta que exista.                                                                                                                                                                                                                                                                    |
| ✅ **OQ-LOY-29** | ¿La política de expiración por defecto cambia según la plantilla vertical? | PRD-LOY, FS-LOY-0002 | Depende de que existan las plantillas verticales (DEC-H7), que aún no están especificadas. Diferida hasta descomponer `core`, que es quien las posee.                                                                                                                                                                                                                                              |

***

## Respuestas del owner (2026-08-17)

Veinticinco quedaron exactamente como la recomendación. Las excepciones y matices:

| ID        | Respuesta                                                                                                                    |
| --------- | ---------------------------------------------------------------------------------------------------------------------------- |
| OQ-LOY-01 | Por programa. Ratificado además que un programa pertenece a una sola empresa.                                                |
| OQ-LOY-02 | **Configurable por moneda.** Ambos tipos pueden expirar o no; la plataforma debe permitir toda combinación.                  |
| OQ-LOY-07 | **Multi-programa desde el inicio** — ver ADR-021.                                                                            |
| OQ-LOY-11 | Aceptada, subida a **12 caracteres** para soportar cientos de millones de códigos sin que la generación pelee consigo misma. |
| OQ-LOY-14 | Aceptada **como default**, con el principio general de que toda empresa pueda configurarlo.                                  |

## Cómo se cierra una

1. Respondes `OQ-LOY-NN: <decisión>`.
2. La decisión se escribe en la sección normativa del spec afectado y desaparece de su tabla de
   preguntas abiertas.
3. El spec sube a `1.0.0` y pasa a `review`, luego a `approved` con tu visto bueno.
4. La traducción al español se actualiza en el mismo cambio — el validador `translation` lo exige.
5. Esta fila se marca cerrada con la fecha y la respuesta, para que dentro de un año se pueda
   reconstruir por qué el sistema hace lo que hace.

## Changelog

| Versión | Fecha      | Cambio                                                                                             | Por qué                                                    | Autor                  |
| ------- | ---------- | -------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | ---------------------- |
| 1.1.0   | 2026-08-17 | Las 27 respondidas y cerradas; aplicadas a los specs, que suben a 0.2.0 / review                   | El owner respondió el lote completo                        | daniel + claude-opus-5 |
| 1.0.0   | 2026-08-17 | Registro inicial: 27 preguntas abiertas del módulo de fidelización, más 3 bloqueadas por otra cosa | Consolidar en un solo lugar lo que impide aprobar 14 specs | daniel + claude-opus-5 |
