2026Desarrollo completo — CLI, clasificador y skill de OpenCode
mail-triage — Triaje de correo basura
Un CLI local que ordena tu correo basura en borrar, rescatar o revisar — con razones.
- Python
- Microsoft Graph
- SQLite
- OpenCode
- Keychain
- Cloudflare
- Junk Mail
Problema
Mi carpeta de correo basura se llena de dos poblaciones muy distintas: estafas que suplantan bancos y a Microsoft, y promociones legítimas a las que sí estoy suscrito. Borrar todo arriesga perder el comprobante que estaba esperando; ignorar la carpeta deja el phishing real escondido entre los códigos de descuento.
Los filtros del proveedor dan una respuesta binaria y sin motivo, y los limpiadores de correo en la nube quieren acceso completo al buzón. Quería una herramienta local que clasifique cada mensaje, diga por qué y nunca mueva nada sin mi confirmación.
Enfoque
Local-first, sin servicios en la nube
Todo corre sobre la biblioteca estándar de Python más SQLite y Keychain de macOS, guardando decisiones y aprendiendo de mis correcciones en disco. Nada sale de la máquina.
Descarté los servicios de limpieza de correo en la nube: exigen acceso total al buzón vía OAuth o contraseña, y los datos que ven son más sensibles de lo que el problema justifica.
Un clasificador con razones explícitas
Cada mensaje recibe un puntaje de riesgo 0–1 y una razón legible: posible suplantación de marca, reply-to distinto del remitente, dominio registrado hace días, fallos SPF/DKIM, urgencia. El correo legítimo rescatado a la bandeja de entrada imprime por qué fue rescatado.
Descarté un modelo de caja negra: sin razones no puedo auditar falsos positivos, y un solo auto-borrado equivocado te enseña a nunca volver a confiar en la herramienta.
Humano en el bucle, aprendiendo de correcciones
Nada se borra ni se mueve sin una confirmación explícita, e `undo` revierte el último lote. Las correcciones alimentan listas de dominios permitidos/bloqueados; un dominio recibe una regla automática solo tras tres correcciones explícitas coincidentes.
Descarté el borrado automático: el costo de un error (perder un comprobante, una cita, un contrato) es asimétrico, por lo que el diseño mantiene a un humano como puerta final.
Núcleo agnóstico del proveedor, un backend hoy
El motor habla con una interfaz `MailProvider`; solo Outlook (Microsoft Graph, device-code flow) está implementado hoy, con Gmail e IMAP listos para enchufarse sin tocar el clasificador. `scan`, `purge`, `undo` y `feedback` aceptan `--provider`.
Descarté acoplar Graph al clasificador: la lógica de triaje no debería cambiar cuando cambia el transporte.
Resultados
- Publicado en GitHub con tests en CI (GitHub Actions) y una skill de OpenCode que envuelve el CLI para uso interactivo.
- Cada corrida produce un informe auditable: puntaje y razón por mensaje, y undo completo de cualquier lote.