# sistema.md — Especificación de un sistema funcional

> Ejemplo de referencia · Fundamentos de Inteligencia Artificial para Marketing
> Instructor: André Paredes Vega · Panamerican Business School
> Formato laboratorio · Semana 2 · versión 2.0

Este archivo es un **ejemplo completo y ejecutable**. Sirve para dos cosas:

1. **Como prompt**: pegalo en ChatGPT, Claude o Gemini y el modelo se comporta como el sistema.
2. **Como brief de construcción**: pegalo como primera instrucción en Lovable, Codex o Claude Code
   y obtenés una aplicación funcional con interfaz, validaciones y llamada real al modelo.

Copiá la estructura, reemplazá el contenido con tu propio caso y no borres ninguna sección:
las secciones 9 a 13 son las que hacen que la interfaz salga funcional y no un cascarón.

---

## 1. Identidad del sistema

- **Nombre:** Radar de Contenido Distintivo
- **Dueño:** equipo de marketing de una marca de café de especialidad
- **Una frase:** convierte notas sueltas de la semana en tres ideas de contenido que
  suenan a nuestra marca y no a un promedio de internet.
- **Problema que resuelve:** el equipo publica contenido genérico porque escribe
  bajo presión y sin criterio previo.
- **Usuario principal:** content lead, sin conocimientos técnicos, con 10 minutos por semana.
- **Frecuencia de uso:** una vez por semana, lunes por la mañana.
- **Definición de éxito:** al menos un ángulo por semana llega a publicación sin reescritura mayor.

---

## 2. Alcance

**Sí hace**
- Recibe notas crudas, señales de la categoría y el manifiesto de marca.
- Devuelve tres ángulos de contenido con justificación, evidencia y riesgo de AI Slop.
- Guarda el histórico de ángulos generados, elegidos y descartados.

**No hace**
- No publica ni agenda.
- No inventa datos ni cifras.
- No decide presupuesto ni pauta.
- No genera imágenes.

**Fuera de alcance por ahora (backlog explícito)**
- Integración con el calendario editorial.
- Multi-marca / multi-cuenta.

---

## 3. Inputs (qué entra)

| Campo | Tipo UI | Obligatorio | Validación | Mensaje de error |
|---|---|---|---|---|
| `notas_semana` | textarea, alto 200px | sí | mínimo 100 palabras | "Necesito al menos 100 palabras de notas para trabajar." |
| `manifiesto_marca` | textarea, alto 150px | sí | debe incluir tono, enemigo y creencia central | "Falta el manifiesto: incluí tono, enemigo y creencia central." |
| `senales_categoria` | lista dinámica de texto (0–5 filas, botón "agregar") | no | cada fila ≤ 200 caracteres | "Cada señal debe tener menos de 200 caracteres." |
| `formato_objetivo` | select: `post` · `newsletter` · `guion` | sí | uno de los tres valores | "Elegí un formato objetivo." |
| `nivel_riesgo` | slider 1–3 (conservador → arriesgado) | no | default 2 | — |

**Regla de entrada:** si un input obligatorio falta o no pasa validación, el sistema
**no genera**: el botón queda deshabilitado y se muestra el mensaje de error debajo del campo.
Nunca se envía una petición incompleta al modelo.

**Persistencia:** el manifiesto de marca se guarda localmente y se autocompleta en la
siguiente sesión. Las notas no se guardan hasta que se genera.

---

## 4. Reglas de procesamiento

1. Leer el manifiesto antes que las notas; el manifiesto manda sobre todo lo demás.
2. Descartar cualquier ángulo que pudiera escribir igual un competidor.
3. Cada ángulo debe anclarse en al menos una observación concreta de `notas_semana`.
4. Nada de adjetivos vacíos: "innovador", "revolucionario", "único", "en un mundo donde".
5. Si el sistema no está seguro de un dato, lo marca como `[verificar]` en vez de afirmarlo.
6. Los tres ángulos deben ser mutuamente distintos: distinta tensión, no tres variantes del mismo tema.
7. `nivel_riesgo` 1 favorece ángulos verificables; 3 permite ángulos con opinión fuerte.
8. Si las notas no dan para tres ángulos honestos, devolver dos y explicar por qué falta el tercero.

---

## 5. Output (qué sale)

Formato exacto de respuesta, siempre igual:

```markdown
## Ángulo 1 — <título en 6 palabras o menos>
**Tensión:** <la contradicción o incomodidad que activa>
**Por qué es nuestro:** <línea del manifiesto que lo sostiene>
**Evidencia:** <cita textual de las notas>
**Riesgo de AI Slop:** bajo | medio | alto — <razón en una línea>
**Primer párrafo propuesto:** <máx. 60 palabras>

## Ángulo 2 — ...
## Ángulo 3 — ...

## Checklist de validación humana
- [ ] ¿La evidencia es real y verificable?
- [ ] ¿Un competidor podría publicar esto igual?
- [ ] ¿Suena a la marca leyéndolo en voz alta?
```

---

## 6. Contrato de datos (para la interfaz)

El modelo debe devolver **JSON estricto** con esta forma, y la interfaz lo renderiza como tarjetas.
Nada de texto libre fuera del JSON.

```json
{
  "angulos": [
    {
      "titulo": "string, máx 6 palabras",
      "tension": "string",
      "por_que_es_nuestro": "string",
      "evidencia": "string, cita textual de las notas",
      "riesgo_slop": "bajo | medio | alto",
      "razon_riesgo": "string, una línea",
      "primer_parrafo": "string, máx 60 palabras"
    }
  ],
  "checklist": ["string"],
  "notas_del_sistema": "string, vacío si no hay nada que advertir"
}
```

Reglas del contrato:
- `angulos` tiene 2 o 3 elementos, nunca más, nunca menos de 2.
- Si un campo no se puede completar con honestidad, va el texto `[verificar]`.
- Si el JSON no parsea, la interfaz muestra "El sistema devolvió un formato inválido, reintentar"
  y ofrece un botón de reintento — nunca muestra el error crudo.

---

## 7. Criterios de validación (cómo sé que sirve)

| Criterio | Cómo se mide | Umbral |
|---|---|---|
| Distinción | ¿Un competidor podría firmarlo? | 0 de 3 ángulos genéricos |
| Trazabilidad | Cada ángulo cita evidencia real | 3 de 3 |
| Utilidad | El equipo publica al menos uno | 1 por semana |
| Honestidad | Datos dudosos marcados `[verificar]` | siempre |
| Latencia | Tiempo hasta ver el primer resultado | < 20 segundos |

---

## 8. Criterio humano (human-in-the-loop)

- **Indelegable:** aprobar el ángulo final y validar cualquier dato.
- **Asistido por IA:** redacción del primer borrador y variantes de titular.
- **Automatizable:** formato, longitud, checklist de estilo.

En la interfaz esto se traduce en: cada ángulo tiene botones **Elegir** / **Descartar**,
y descartar pide un motivo en una línea. Sin motivo no se descarta.

---

## 9. Interfaz (qué se ve en pantalla)

**Pantalla única, tres zonas verticales.**

1. **Encabezado**
   Nombre del sistema, una línea de qué hace, y un enlace "cómo funciona" que abre un panel
   con las reglas de la sección 4 en lenguaje llano.

2. **Zona de entrada** (columna izquierda en desktop, arriba en móvil)
   - Los campos de la sección 3, en ese orden, cada uno con su etiqueta y texto de ayuda.
   - Contador de palabras en vivo bajo `notas_semana`.
   - Botón primario **Generar ángulos**, deshabilitado hasta que todo valide.
   - Enlace secundario "Cargar ejemplo" que rellena los campos con un caso de muestra.

3. **Zona de resultado** (columna derecha en desktop, abajo en móvil)
   - Estado vacío con una frase que explica qué va a aparecer ahí.
   - Estado cargando: tres tarjetas esqueleto animadas, no un spinner solo.
   - Estado con datos: una tarjeta por ángulo con los campos del contrato, el riesgo de slop
     como etiqueta de color (verde/ámbar/rojo), y los botones Elegir / Descartar / Copiar.
   - Checklist de validación humana al final, con casillas marcables.
   - Botón **Descargar en Markdown** que exporta el resultado con el formato de la sección 5.

4. **Historial** (panel colapsable al pie)
   Lista de generaciones anteriores con fecha, ángulo elegido y motivos de descarte.

**Comportamiento**
- Todo se guarda en almacenamiento local del navegador; no hace falta cuenta ni login.
- La app funciona en móvil: una sola columna, botones de ancho completo.
- Los errores se muestran en el lugar donde ocurren, nunca como alerta del navegador.

---

## 10. Estados del sistema

| Estado | Cuándo | Qué ve el usuario |
|---|---|---|
| Vacío | primera visita | explicación breve + campos vacíos + ejemplo cargable |
| Inválido | falta un obligatorio | error bajo el campo, botón deshabilitado |
| Generando | petición en curso | tarjetas esqueleto, botón en "Generando…", cancelable |
| Éxito | JSON válido | tarjetas de ángulos + checklist + exportar |
| Formato inválido | JSON no parsea | mensaje amable + botón reintentar |
| Error de red o modelo | falla la llamada | mensaje + reintentar; las notas no se pierden |
| Sin material suficiente | el modelo devuelve 2 ángulos | se muestran 2 + `notas_del_sistema` explicando |

---

## 11. Diseño visual

- Fondo claro, mucho espacio en blanco, tipografía legible; estética de documento, no de dashboard.
- Un solo color de acento para acciones primarias.
- Escala de riesgo con tres colores semánticos, sin decoración adicional.
- Sin gradientes morados, sin íconos genéricos de IA, sin animaciones de relleno.
- La jerarquía la da el tamaño y el espacio, no las cajas de colores.

---

## 12. Notas técnicas para quien lo construye

- Llamada al modelo desde el servidor, nunca desde el navegador: la clave no se expone.
- Temperatura baja (0.4–0.6) para que el formato sea estable.
- Pedir salida en JSON y validar el esquema antes de renderizar; si falla, un reintento automático.
- Enviar el manifiesto y las reglas de la sección 4 como instrucción de sistema; los inputs
  del usuario como mensaje aparte. Nunca mezclarlos en un solo bloque de texto.
- Límite de longitud de entrada: truncar `notas_semana` a 4.000 palabras avisando al usuario.
- Sin base de datos en la primera versión: almacenamiento local basta para el historial.

---

## 13. Prompt de arranque

**Para usarlo como sistema en un chat:**

> Actuá como el sistema descrito en este archivo. No respondas nada hasta
> confirmar que tenés `notas_semana`, `manifiesto_marca` y `formato_objetivo`.
> Cuando los tengas, devolvé exactamente el formato de la sección 5.

**Para construirlo como aplicación (Lovable, Codex, Claude Code):**

> Construí la aplicación descrita en este archivo. Implementá exactamente la interfaz de la
> sección 9, los estados de la sección 10, el estilo visual de la sección 11 y las decisiones
> técnicas de la sección 12. La generación debe llamar de verdad a un modelo de lenguaje desde
> el servidor y devolver el JSON de la sección 6, aplicando las reglas de la sección 4 como
> instrucción de sistema. No dejes datos simulados: si algo no se puede conectar todavía,
> decímelo en vez de fingirlo.

---

## 14. Loop de mejora

Cada semana se registra: ángulo elegido, ángulo descartado y por qué.
Cuando un motivo de descarte se repite tres veces, se convierte en una nueva
regla de la sección 4 y se versiona este archivo.

---

## 15. Versión

- `v1.0` — versión inicial del laboratorio.
- `v2.0` — se agregan contrato de datos en JSON, especificación de interfaz, estados,
  diseño visual, notas técnicas y prompt de construcción.
- Cambios futuros: anotar fecha, qué regla cambió y qué evidencia lo motivó.
