feat(short): generación y render de Shorts vía shortsmith
Build & Deploy ResearchOwl / build-and-push (push) Successful in 9s

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>
This commit is contained in:
ChemaVX
2026-08-01 21:55:42 +00:00
co-authored by Claude Opus 5
parent 8b81ef87e4
commit 20c8d03aa7
27 changed files with 4350 additions and 23 deletions
+41
View File
@@ -39,9 +39,50 @@ OutputGenerator (Ollama)
| `/status` | Check progress |
| `/finish` | Stop early, proceed to generation |
| `/generate podcast\|blog\|report\|thread` | Generate output |
| `/generate short_en` | Vertical Short: shot spec → grounding check → MP4 |
| `/short_spec` | Last shot spec as a JSON file, to hand-edit and re-render |
| `/sources` | List all sources found |
| `/cancel` | Cancel current research |
## Shorts (`/generate short_en`)
Claude writes a **shot spec** — typed JSON, not prose — which
[shortsmith](https://git.chemavx.xyz/chemavx/shortsmith) renders into a 1080×1920
MP4. The bot sends the video and, in a separate message, a **claims report**.
```
/research JAL 1628 Alaska 1986 …
/generate blog en → Ghost draft, article URL stored on the output row
/generate short_en → spec → grounding → render → video + claims report
(YouTube upload is deliberately manual)
```
Three things make this different from generating text, and each has its own
mitigation:
- **It is a contract, not prose.** The template schemas are fetched live from
`GET /templates` and never copied here, so a template added to shortsmith is
available immediately. A spec is validated locally against those schemas
before anything renders, and the exact error paths
(`shots.0.radar_sweep.props.sweeeps`) go back to the model verbatim — up to 3
attempts.
- **It contains figures and quotes.** `grounding.py` extracts every quote,
figure, date and proper noun and checks it against the exact chunks the model
was given. No LLM in that path: normalisation plus substring, deterministic
and free. Whatever is not in the chunks is checked against the worked example
that travels in the prompt, so a figure lifted from it is reported as a
**prompt leak**, not as an invention — different diagnosis, different fix.
Neither ever blocks the render: both are surfaced next to the video and a
human decides.
- **It becomes a published video.** Nothing is uploaded anywhere. The MP4 lands
in Telegram for review, and in `/data/shorts/{session_id}.mp4`.
Fallbacks hold throughout: if shortsmith is unreachable, the job errors, or the
spec never validates, the spec JSON comes back as a file. The expensive part is
the generation, not the render.
Full spec of the phase: `docs/shortsmith-phase2-spec.md`.
## Local Development
```bash