La nota que teníamos era falsa: los avisos `severe` de shortsmith SÍ llegan a
un humano — el informe de Telegram los saca en rojo. Lo que pasa es que llegan
colgados del render TERMINADO, así que hacerles caso significa editar el spec a
mano y pagar un segundo. Por eso nadie actuó nunca.
`x-fits` tampoco podía ser la comprobación, y a propósito: es guía blanda que el
propio ejemplo de referencia se salta por uno o tres caracteres viéndose bien.
Parar ahí sería gritar con specs buenos, y un aviso que grita se ignora — que es
justo cómo sobrevivieron los graves. Así que shortsmith publica desde 289d50e un
segundo número medido por campo, `x-fits-hard`, y esto lo comprueba antes de
gastar el render: cuesta un reintento del modelo en vez de un render. El mismo
movimiento que hizo `MAX_CUE_CHARS` con los captions en e32c59f.
Auditado contra los 17 short_en de producción: OCHO llevan al menos un texto que
se dibuja ilegible.
- El ya conocido, Cash-Landrum: `ALL THREE DEVELOPED SYMPTOMS CONSISTENT WITH
RADIATION EXPOSURE`, 36 px pedidos y 20 dibujados. Salta con 63 caracteres
contra un presupuesto de 61 — así de vertical es la curva pegada al muro.
- El que nadie había visto es peor y más común: el CARTEL DE CIERRE.
`counter_close.lines` pide 110 px y se dibujó a 28 en el peor caso, y por
debajo de 64 en cinco de los ocho. Es la llamada a la acción, y en un tercio
del catálogo es el texto más pequeño del fotograma.
- Y la tolerancia aguanta sobre datos reales: `STILL UNEXPLAINED` encoge de 110
a 84 px y no se avisa, que es lo correcto.
El desempate entre intentos pasa a contar averías —gancho y texto ilegible—
antes que segundos, por la misma razón que en 6d9b602: una reescritura que
arregla un rótulo pero se pasa un segundo perdía contra la que no lo arreglaba.
Un campo sin presupuesto propio (`Bar.unit`, que se dibuja dentro de la cadena
de `value_label`) se salta a conciencia: reconstruir esa cadena aquí pediría
conocer el formato de la plantilla, que es lo que este repo no sabe ni debe.
Y contra un shortsmith anterior a 289d50e esto se calla — no puede inventarse el
número —, así que de que el contrato traiga el campo se encarga
test_shortsmith_live.py, que es quien habla con el servicio.
Suite: 274 pasan.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
El gancho de un Short es lo que se DIBUJA, no solo lo que se dice. El prompt
llevaba la mitad hablada desde 4b («the first line is the whole hook») y no
tenía nada sobre la mitad vista. De los diecisiete short_en generados, once
abren mal: diez ponen la fecha en el titular —el texto más grande del vídeo—
mientras el subline de debajo ya lleva el sitio, y el output 131 abre con
document_quote.
Medido sobre el renderizador a 5,5 s de plano: las cinco plantillas con
`headline` lo ponen a tinta plena en 0,33-0,40 s, y shortsmith lo garantiza a
cualquier duración desde db1ac7e. Las tres que no lo tienen dejan la banda
superior del fotograma al nivel del fondo TODO el plano —su texto se escribe a
máquina más abajo y no está entero hasta 2,6-2,8 s—. Con 6,9 s de visionado
medio, abrir con una de esas regala el tercio de la ventana en el que se
decide todo.
La costura es `headline`, preguntada al esquema y no a una lista de nombres:
una plantilla nueva de shortsmith con titular podrá abrir sin tocar este repo,
y una sin él no podrá. El mismo pacto que el resto del contrato.
Y `_closer_to_target` ordenaba SOLO por segundos, lo que hacía decorativo el
aviso nuevo: una reescritura que arreglaba el titular pero se pasaba un
segundo perdía contra el intento que abría con una fecha. Ahora el gancho va
delante — los segundos son un gradiente, el gancho es binario.
Comprobado contra los 17 specs reales de producción: avisa de once y de
ninguno más. Los que pasan son los titulares que se quieren (62 CHILDREN,
23 HELICOPTERS, RELEASE 05).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
12 ÷ 2.8 no da 5.1, da 5.0. La cuenta trabajada la hace el modelo con el número
que ve, así que el número que ve tiene que ser el real.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
El modelo declaraba menos segundos de los que su propia línea necesitaba en 3 o
4 de cada 5 planos narrados — entre 3,8 y 8,2 s de deriva por Short. El vídeo
salía con la duración correcta porque shortsmith estira, pero el ritmo visual
que el spec escribía no era el que se renderizaba.
No era pereza del modelo: era un juego de reglas insatisfacible. El prompt pedía
a la vez líneas de hasta 18 palabras, planos de 6 s como mucho, y tiempo
declarado suficiente para la propia voz. 18 palabras piden 7,3 s, así que las
tres juntas son imposibles y el modelo rompía la única que nadie comprobaba.
Tres capas, las tres deterministas y sin gastar una generación:
- La regla enseñada llevaba el mismo error de clase que el estimador tenía antes
del 2026-08-12: palabras por segundo a secas, sin el término de las pausas.
Medida contra las 28 líneas que el bot ha narrado de verdad, `words/2.75 + 0.5`
se quedaba corta en 14 y hasta 2,27 s — obedecerla al pie de la letra seguía
infradeclarando. Ahora es de dos términos, como la voz, y el peor caso baja a
1,27 s en 5 de 28.
- El tope de palabras por línea se DERIVA del plano más largo (`max_words_in`)
en vez de escribirse a mano. La contradicción no puede volver.
- El ejemplo de referencia incumplía su propia regla en 2 de sus 6 líneas, y el
ejemplo es la señal más fuerte del prompt: le estábamos enseñando el fallo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`editorial_notes` documentaba "se comenta una vez y, si insiste, se renderiza
igual", pero el bucle reintentaba dos veces: las sesiones 166, 167 y 168
gastaron los tres intentos y las tres acabaron renderizando un spec que seguía
pasándose. Un spec que ya cumple el contrato es renderizable; los intentos que
quedan son para el contrato, que sí es binario.
Y de dos specs válidos se guarda el que menos se sale del objetivo, no el
primero. Obedecer a medias es obedecer: antes, una reescritura que bajaba de
70 s a 50 s se tiraba entera y salía el largo.
El prompt, que era la mitad que faltaba. Decirle "20-45 segundos" no le sirve
de nada: la duración real no está escrita en ninguna parte del spec, sale de
sumar plano a plano el mayor entre lo declarado y lo que tarda la voz, y eso no
lo puede calcular quien no sabe a qué velocidad se le lee. Ahora lleva el
ritmo (2,8 palabras por segundo), la cuenta por plano, un presupuesto de 80
palabras de narración, y dos topes que salen del propio ejemplo en vez de estar
inventados: 12 palabras por línea (tope 18) y 6 s por plano. El anterior — "una
línea de menos de 25 palabras" — no describía nada que el canal hubiera
publicado, y el modelo escribía líneas de 25 y 27 sin saltarse ninguna regla.
Medido con cinco generaciones reales sobre el material de la sesión 168:
antes 3 intentos siempre, con el vídeo fuera del objetivo (47,5 s y 45,4 s).
Ahora 2, y el borrador cae dentro: 39,8 / 37,3 s. En dos de las cinco el
reintento ya no fue por duración sino por un fallo de contrato.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
La primera generación con narración viva narró 5 de 7 planos. La siguiente, ya
con la sección de presupuestos de ancho en el prompt, narró 1 de 8.
La causa no era la sección 3b sino la 5: el ejemplo trabajado — un spec completo
de 8 planos presentado como "el que produjo un buen vídeo" — no llevaba ni una
narración, porque es anterior a la voz. Contra esa señal de formato, una regla
en prosa que además dice "no todos los planos necesitan una" pierde siempre.
Ahora el ejemplo narra 6 de sus 8 y calla en los dos que dibujan una cita, donde
la voz sólo competiría con palabras que ya están en pantalla. Sus duraciones
suben para pagar lo que habla: un plano que se queda corto para su propia voz
enseñaría a infradeclarar, y el render no corta la voz, alarga el plano. La
ventana de silencio se recoloca porque seguía a document_quote por tiempo.
El aviso de ancho ya no cita el hueco de 16 caracteres de quote_a: shortsmith
envuelve esas citas en dos líneas y el presupuesto vivo es 31.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
shortsmith ya compone la banda sonora (sonar); ahora publica una paleta
(pulse, static) y este repo la consume en vivo: el prompt la ofrece con sus
notas de mood, validate_spec la usa como fuente de verdad para audio.preset,
y editar el preset en /short_spec es la manera gratis de escucharlas. Sin
/audio (404 o caída) todo cae a la paleta base y nada deja de renderizar.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Añade /generate short_en y /short_spec. El pipeline genera un shot spec
con Haiku, verifica cada cifra, fecha y cita contra los chunks de la
sesión, lo renderiza en shortsmith y entrega el MP4 por Telegram junto
a un informe de claims.
- ShortsmithClient con sondeo y fallback al spec JSON si el render falla
- Contrato de plantillas obtenido de GET /templates, no codificado
- Comprobación de fundamento determinista, sin LLM
- outputs.published_url para enlazar el artículo de Ghost
- Normalización de comillas rectas a tipográficas (ver KNOWN-ISSUES.md)
Lo que no aparece en los chunks se contrasta contra el ejemplo del
prompt: si casa ahí es fuga, no invención, y se informa como tal. El
purgado de sesiones se lleva también su MP4.
La subida a YouTube queda fuera a propósito: fase 3.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>