feat: real creative bridge, lab wiring, and Slack metric-anomaly alerts
Three iterations autónomas siguiendo el roadmap:
Fase A — Bridge creativo real
BridgeCreativeProvider ahora hace HTTP real contra el upstream en lugar de fallback al stub. Contrato documentado (brief → assets). Cualquier vendor (Scenario/Layer/Seeles) se conecta con un traductor pequeño externo. Raise explícito en fallos HTTP/JSON/schema — el library marca el brief failed.
Fase B — Lab wired a campaign_runs
-
aggregate_campaign_runs→ destila lista de runs en un ExperimentResult (lift medio, mejor p-value, samples sumados, duración, AND sobre incrementality). -
ExperimentationLab.evaluate_from_campaign_runs→ lookup + aggregate + guardrail → persistencia dePromotionDecision. -
GET /api/lab+POST /api/lab/evaluate. - CLI
cmoagent lab summaryycmoagent lab evaluate <id> --since-days N.
Fase C — Slack metric-anomaly alerts
Añade un cuarto check al notifier:
- CPI delta ≥ +20% (cost spike)
- CTR delta ≤ -30% (engagement drop)
- IPM delta ≤ -25% (creative fatigue)
- Incrementality flipped negative
Dedup por run_id en el state file. Wired en run_notifier, CLI --anomalies + --all.
Test plan
-
199/199 pytest verde (21 nuevos) -
Container reconstruido, imports ok, /api/labresponde con guardrail defaults -
Notifier service activo en compose (polling cada 5 min con los 4 checks) -
Bridge real: esperar a que haya credenciales de Scenario/Layer -
Anomalías reales: esperar a que el agente empiece a ejecutar campañas con metrics_snapshot completo