Aprobar es editar. Escribir encima del borrador siempre fue el gesto, y el teclado nunca fue la única forma de escribir. Mantienes el micrófono, dices qué está mal, y la carta se rehace. Debajo cambia el motor: el redactor deja de ser un routine suelto y pasa a ser un agente de Eve — sin tocar la ley, la ventana de cinco segundos ni el despacho.
Mantén presionado el micrófono de la carta. Suéltalo cuando termines. La animación de abajo no es decorativa: cada estado corresponde a algo que de verdad está pasando, y el del medio existe porque la transcripción tarda.
La regla que gobierna toda la animación es una: nunca fingir progreso que no existe. En un teléfono con mala señal, saber si te oyó o si se colgó es exactamente la información que hace falta — y un pulso continuo que no cambia de carácter no la da.
El micrófono vive pegado al ✎ porque son la misma cosa: las dos formas de escribir encima del borrador. Mandar se estrecha para hacerles sitio, y las cuatro conservan más de 44 px de área táctil a 390 px. El ✎ sigue siendo el último hijo — la afordancia que el capítulo dos protege por escrito no se toca.
| gesto | qué hace | por qué así |
|---|---|---|
| Mantener | Hablas, y la carta se reescribe con lo que dijiste — «más corta», «dile que el jueves no puedo», «más seca» | Es «aprobar es editar» dicho con la voz |
| Tocar | Otra vez: se vuelve a correr el redactor tal cual, sin instrucción | A veces no sabes qué está mal, solo que está mal |
Un botón para las dos porque son la misma petición: reescribe esto, con mis palabras o sin ellas. Solo la forma respuesta lo tiene — una carta de accion no tiene qué reescribir.
Y volver a correrlo no es gratis, y el diseño lo dice. Eve no tiene API de regenerar, ni de bifurcar una sesión, ni de editar el último mensaje: re-redactar es un turno nuevo sobre la misma sesión durable, y paga tokens de entrada por todo el historial. Por eso la carta recuerda cuántas veces se reescribió — no como contador de vanidad, sino como la señal de que quizá el problema no es el borrador sino la carta.
Se decidió que la voz pueda aprobar, no solo corregir. Eso abre un hueco que no es de reconocimiento sino de tiempo: sueltas el botón, miras a otro lado, y la transcripción tarda. El temporizador arrancaría cuando ya no estás mirando, y de cinco segundos te quedarían tres.
Así que los cinco segundos empiezan cuando el acuse aparece en pantalla, no cuando sueltas el botón. Y el acuse de una aprobación por voz es más ruidoso que el del dedo: más alto, con la barra de drenaje más gruesa, porque no estabas mirando.
Siguen siendo los mismos cinco segundos de sDrain, la misma única fuente. Lo que cambia es cuándo empieza a contar, y eso es del cliente. El servidor conserva su execute_after = now() + 5s desde que la fila entra al outbox: la ley no se movió.
Una transcripción que confunda una corrección con una firma encola algo en tu nombre. No hay reconocimiento perfecto, y por la vía viable en iOS ni siquiera se puede sesgar el reconocedor hacia tu vocabulario: Safari no soporta phrases, ni grammars, ni processLocally.
Lo que cubre ese riesgo es la ventana — y por eso la ventana tuvo que cambiar de reloj. Queda anotado aquí, no escondido en un commit.
Eve —el framework de agentes de Vercel— sustituye al routine de Claude que redactaba las cartas. Y no sustituye nada más, por una razón que dan sus propios documentos: Eve tiene aprobación humana de verdad, pero advierte que «no es un flujo de cuatro ojos… para eso, crea una petición de aprobación propia de tu aplicación». Vercel te manda a construir exactamente la tabla outbox que al día ya tiene — y la nuestra ya está probada contra Postgres real con dos despachadores simultáneos.
al día · Supabase Eve · Vercel · Node 24
───────────────────────── ──────────────────────────
cosecha · 4 adaptadores
│
cards ─────────────────────────→ agent/instructions.md
│ agent/skills/al-dia-redactor/
la pila ←── el borrador
│
🎙 hablas ──── transcripción ────→ turno nuevo, misma sesión
│ ←── el borrador reescrito
apruebas
│
outbox · execute_after +5s
│
despachador · Vault
│
Gmail / Slack / Notion / Calendar
Eve NO toca: la ley · la ventana · el despacho · el VaultEl skill ya existe y es el mismo formato. Eve instala skills de Markdown en agent/skills/ con el mismo CLI que crescō ya usa. al-dia-redactor, versionado en cresco-skills, se instala tal cual: cambiar la voz de al día sigue siendo un PR.
Node 24, y eso es una decisión de arquitectura. eve@0.30.6 declara "engines": {"node": ">=24"}, así que el redactor no cabe dentro de una edge function de Supabase, que corre Deno. Necesita su propio deployment.
Decidido con los números delante. OpenRouter no está en el catálogo de AI Gateway — verificado contra su endpoint público: 315 modelos, 34 proveedores, cero coincidencias. Se conecta pasándole a defineAgent un LanguageModel del AI SDK; compila, y el propio clasificador de Eve devuelve {"kind":"external","provider":"openrouter"}. Pero nadie ha documentado nunca eve + OpenRouter funcionando en vivo, y grep sobre los 96 archivos de documentación del paquete no devuelve ni una mención.
Esto no es una objeción: es la lista de lo que el Gateway regalaba y ahora es trabajo explícito de al día.
| se pierde | lo que hay que construir |
|---|---|
| el coste en los traces | al día cuenta sus propios tokens por carta y los guarda |
| la ventana de contexto | fijar modelContextWindowTokens a mano — equivocarse descalibra la compactación |
| el corte por presupuesto | un guardián de gasto propio. El techo por sesión de Eve son 40 millones de tokens de entrada: un número simbólico, no una protección |
| el fallback | OpenRouter tiene el suyo, pero pasarlo por modelOptions.providerOptions de Eve no está documentado — hay que probarlo, no asumirlo |
| la caché de Anthropic | verificar si Eve activa caching:'auto'. Sin caché, cada re-redacción re-ingesta el historial a precio lleno — la pregunta abierta más cara del diseño |
| ZDR por request | revisar la política de datos de OpenRouter. Esto muele correo, Slack y Notion privados del dueño |
Y la llave sale del Vault de Supabase y se va a las variables de entorno de Vercel. No es un problema por sí solo; es un sitio más donde vive un secreto, y se dice.
Una cosa que hay que apagar el primer día: bash, read_file, write_file, glob y grep vienen activas por defecto en Eve y corren en Vercel Sandbox, que factura. Un agente que solo redacta texto las apaga con disableTool().
La respuesta obvia sería la Web Speech API: la que hace aparecer las palabras mientras hablas, gratis y sin servidor. No se puede.
Que es exactamente cómo se usa al día. Lo dice una ingeniera de WebKit en el bug 225298:
SpeechRecognition API is not available in SafariViewController and web apps added to Home Screen for now.
Cerrado como LATER desde 2021, sin arreglo en las notas de Safari 26 ni de Safari 27 beta. Y lo peor no es que falle: es que el fallo no se puede detectar. 'webkitSpeechRecognition' in window devuelve true en la app instalada, no lanza excepción, y simplemente no dispara eventos nunca. Cualquier bifurcación tiene que mirar el modo standalone, no la presencia de la API.
Por eso el camino es getUserMedia + MediaRecorder, que sí funcionan en standalone desde iOS 13.4 — push-to-talk con ida y vuelta. Es también la razón de que el estado «viajando» exista en el diseño en vez de esconderse.
Y nada de esto se probó todavía en un iPhone real: todo es documental. Antes de construir, una tarde de prueba — instalar una página en la pantalla de inicio y comprobar en la versión de iOS del dueño que la API existe pero no dispara, y que el micrófono sobrevive a matar y reabrir la app. El permiso no persiste de forma fiable entre arranques en frío (bug 215884), así que el botón tiene que tolerar que le vuelvan a preguntar en cualquier momento.