# Twitter Digest Orchestration (Single Source of Truth)

Este es el unico documento operativo actualizado del repo.

## 1) Estructura

Todo esta separado por fase:

- `PHASES/PHASE-01-INGEST/`
- `PHASES/PHASE-02-CAPTIONS/`
- `PHASES/PHASE-03-DIGEST-CONTRACT/`
- `PHASES/PHASE-04-RENDER/`
- `PHASES/PHASE-05-ORCHESTRATOR/`
- `PHASES/PHASE-06-NOTIFICATIONS/`
- `PHASES/PHASE-07-SCHEDULE/`

## 2) Como inicia el flujo

Hoy el flujo inicia manualmente (comandos).
Solo se vuelve automatico cuando configuras scheduler/cron en `PHASES/PHASE-07-SCHEDULE/README.md`.

Orden obligatorio:

1. Phase 1 (Ingest)
2. Phase 2 (Captions + gate)
3. Phase 3 (Digest contract)
4. Phase 4 (Render)
5. Phase 5 (Orchestrator)
6. Phase 6 (Notifications)
7. Phase 7 (Scheduler)

## 3) Definiciones basicas

- `Gate`: condicion obligatoria para avanzar.
- `Artifact`: archivo de salida esperado.
- `DATE`: fecha en formato `YYYY-MM-DD`.

## 4) Phase 1 - Ingest

Objetivo: obtener tweets del dia y generar data procesada con/sin imagenes.

### Script A: `PHASES/PHASE-01-INGEST/scrape_slot.sh`

Que hace:
- Ejecuta scraper para un slot (`morning`, `midday`, `evening`).
- Guarda una corrida por slot.
- Re-mergea todas las corridas del dia a un `raw_feed.csv` canonico.

Input:
- `slot`
- `DATE`
- `PHASES/PHASE-01-INGEST/cookies.json`

Output:
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/raw_feed_runs/HHMM_slot.csv`
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/raw_feed.csv`

### Script B: `PHASES/PHASE-01-INGEST/process_day.sh`

Que hace:
- Toma `raw_feed.csv`.
- Separa tweets con y sin imagen.
- Descarga imagenes cuando aplica.
- Construye manifest para captions.

Input:
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/raw_feed.csv`

Output:
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/no_images.csv`
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/with_images.csv`
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/manifest.json`
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/images/*`

## 5) Phase 2 - Captions + Gate

Objetivo: completar descripciones de imagen y bloquear publicacion si falta alguna.

### Script A: `PHASES/PHASE-02-CAPTIONS/caption_until_complete.sh`

Que hace:
- Ejecuta loop: AI captions -> apply -> validate.
- Repite hasta completar o llegar a limite/timeout.

Input:
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/manifest.json`
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/with_images.csv`
- Contrato AI: `PHASES/PHASE-02-CAPTIONS/CLAUDE.md`

Output:
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/image_descriptions.jsonl` (append-only)
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/with_images.csv` (actualizado)
- `PHASES/PHASE-01-INGEST/tweets/archive/DATE/images_done.ok` (solo si completo)

### Script B: `PHASES/PHASE-02-CAPTIONS/apply_image_descriptions.py`

Que hace:
- Aplica `image_descriptions.jsonl` al campo `image_description` de `with_images.csv`.

Input:
- `image_descriptions.jsonl`
- `with_images.csv`

Output:
- `with_images.csv` actualizado
- `with_images.before_apply.csv` (backup de seguridad)

### Script C: `PHASES/PHASE-02-CAPTIONS/validate_captions.py`

Que hace:
- Verifica que cada imagen de `manifest.json` tenga caption util.

Output de validacion:
- Exit `0`: completo
- Exit `1`: incompleto
- Exit `2`: error de inputs

### Gate de esta fase

`images_done.ok` es el gate duro.
Si no existe, el digest no se publica.

## 6) Phase 3 - Digest Contract

Objetivo: definir reglas para generar digest consistente.

Archivo:
- `PHASES/PHASE-03-DIGEST-CONTRACT/CLAUDE.md`

Preferencias del usuario:
- `PHASES/PHASE-03-DIGEST-CONTRACT/INTEREST.md`

Output esperado de esta fase (vía agente digest):
- `PHASES/PHASE-05-ORCHESTRATOR/digests/archive/DATE/digest.json`
- `PHASES/PHASE-05-ORCHESTRATOR/digests/archive/DATE/digest_checkpoint.md`

## 7) Phase 4 - Render

Objetivo: renderizar `digest.json` a pagina navegable.

Template:
- `PHASES/PHASE-04-RENDER/index.php.template`

Frontend:
- `PHASES/PHASE-04-RENDER/twitter-app/`

Que hace:
- Muestra resumen + tweets + embeds.
- Acepta feedback por POST y lo agrega a `PHASES/PHASE-03-DIGEST-CONTRACT/INTEREST.md`.

## 8) Phase 5 - Orchestrator

Objetivo: ejecutar flujo final de publicacion de punta a punta.

Script:
- `PHASES/PHASE-05-ORCHESTRATOR/run_digest.sh`

Que hace:
- Verifica/mergea `raw_feed.csv` si falta.
- Corre Phase 1 process + Phase 2 captions.
- Exige gate `images_done.ok`.
- Invoca agente digest (Phase 3 contract).
- Copia template de Phase 4 a `index.php`.
- Ajusta permisos.
- Ejecuta notificacion (Phase 6).
- Marca dia publicado y actualiza ledger.

Artifacts finales:
- `PHASES/PHASE-05-ORCHESTRATOR/digests/archive/DATE/digest.json`
- `PHASES/PHASE-05-ORCHESTRATOR/digests/archive/DATE/digest_checkpoint.md`
- `PHASES/PHASE-05-ORCHESTRATOR/digests/archive/DATE/index.php`
- `PHASES/PHASE-05-ORCHESTRATOR/digests/archive/DATE/published.ok`
- `PHASES/PHASE-05-ORCHESTRATOR/COMPLETED-DAYS.md`

## 9) Phase 6 - Notifications

Objetivo: enviar Telegram post-publicacion.

Script:
- `PHASES/PHASE-06-NOTIFICATIONS/notify_telegram.sh`

Valida antes de enviar:
- `digest.json` existe y parsea
- `index.php` existe
- `images_done.ok` existe

ENV requeridas:
- `TELEGRAM_BOT_TOKEN`
- `TELEGRAM_CHAT_ID`
- `PUBLIC_BASE_URL`

Output:
- Mensaje Telegram enviado con URL del digest del dia.

## 10) Phase 7 - Scheduler

Objetivo: automatizar ejecucion por hora y logs.

Runbook:
- `PHASES/PHASE-07-SCHEDULE/README.md`

Horarios recomendados:
- 08:00 / 13:00 / 18:00 -> ingest
- 08:10 / 13:10 / 18:10 -> captions
- 22:00 -> digest final

## 11) Prueba paso a paso (manual)

```bash
# Phase 1
bash PHASES/PHASE-01-INGEST/scrape_slot.sh morning YYYY-MM-DD
bash PHASES/PHASE-01-INGEST/process_day.sh YYYY-MM-DD

# Phase 2
bash PHASES/PHASE-02-CAPTIONS/caption_until_complete.sh YYYY-MM-DD
test -f PHASES/PHASE-01-INGEST/tweets/archive/YYYY-MM-DD/images_done.ok && echo "GATE OK"

# Phase 5 (incluye Phase 6)
bash PHASES/PHASE-05-ORCHESTRATOR/run_digest.sh YYYY-MM-DD
```

## 12) Smoke checks tecnicos

```bash
bash -n PHASES/PHASE-01-INGEST/scrape_slot.sh PHASES/PHASE-01-INGEST/process_day.sh PHASES/PHASE-02-CAPTIONS/caption_until_complete.sh PHASES/PHASE-05-ORCHESTRATOR/run_digest.sh PHASES/PHASE-06-NOTIFICATIONS/notify_telegram.sh
python3 -m py_compile bin/twitter-scraper bin/twitter-process bin/twitter-analyze bin/tweet-csv-merge PHASES/PHASE-02-CAPTIONS/apply_image_descriptions.py PHASES/PHASE-02-CAPTIONS/validate_captions.py
php -l PHASES/PHASE-04-RENDER/index.php.template
node --check PHASES/PHASE-04-RENDER/twitter-app/app.js
```
