The “N steps” reel, with Nei’s real face
You write a roteiro.json; rtex returns a 1080×1920 vertical reel about a single topic: a strong hook in frame 0, numbered steps with an index, sourced evidence, an honest caveat, and, at the end, an opinion question for the audience to answer. Nei’s HeyGen avatar does the talking.

rtex is the engine Nei uses to make INEMA reels (short vertical videos) with his own face: his HeyGen avatar speaks the script, and the engine draws the screens, word-by-word captions, and end card over it. Each video covers a single topic in a fixed format: a strong hook in the opening frame, the method’s steps in “N steps,” and, at the end, an opinion question for the audience to answer in the comments. A validator, an automatic critic, and QA check the format before publication. The code is open for study and adaptation; to generate your own video, you need your own HeyGen avatar, as well as Python, Node, ffmpeg, and Whisper.
A fixed format with the real presenter
The top two-thirds show the content; the bottom third shows Nei speaking throughout the entire reel. Every number has a source on screen, and yellow appears as a surface (a yellow background) only once: on the pill with the final question’s options. Highlighted words in yellow type, such as AGENT in the headline, do not count.

🎙️ Nei’s real avatar
The voiceover goes to the HeyGen studio through the subscription; the avatar video comes back, Whisper timestamps each word, and the engine fits the screens and captions to that timing.
🧩 Step-based format
One topic: hook in frame 0, evidence by 20 s, the viewer’s problem, “N steps” with a visible index, evidence, caveat, maxim after a silence, and an opinion question.
✅ Three checks
The validator enforces the rules; a critic (claude -p) scores the script; QA measures duration, pacing, volume, screen changes per minute, silence, end card, and yellow.
The nine blocks of the rtex format
One topic per video, in this order. The checar command rejects the script if a required block is missing or out of place. A video with five different topics (a list) will not pass: “N steps” means the steps in the method for a single topic.
- thesis: the hook (frame 0 and the first 3 seconds), described below.
- authority: evidence on screen by 20 s: a number with a source (the counter lands on the source’s value) or an authority, also with a source.
- problem: the viewer’s pain point, right after the evidence, with reassurance in the spoken line (“it’s not your fault”) and an object (in the sample, a chat being crossed out).
- turn: announce “N steps”; the 01–N index appears before the first step and becomes pills at the top.
- method: numbered steps, one object per step, label “0N / NAME.”
- evidence: a sourced fact that confirms what came before.
- caveat: limitations, spoken and readable, turned into an instruction.
- maxim: a short antithesis after 0.5–0.9 s of silence (voice and music disappear).
- cta: the opinion question (below); the card stays up for 9 s after the last word.
The hook: frame 0 and the first 3 seconds
Four types, and only these
gancho.tipo field: contrario (tell people to stop doing something everyone does: “STOP CREATING AGENTS”), perda (what if something disappeared?), estatistica_medo (a scary number, with a source on screen), or historia_terceiro (someone else’s story, with a number and a source). Forbidden: lists (“5 steps this month,” “N things…”), “did you know…” and “I did…”.
A headline stronger than the voice
The frame 0 headline (tela.linhas) has up to 6 words, in uppercase, with one yellow word (tela.destaque). It is more aggressive than the spoken line: the text stops people scrolling with the sound off; the voice softens and explains. It is already complete in frame 0, which serves as the cover. Below it, a metaphor object with damage (objeto.params.metafora; today, the only accepted value is "fio") changes about every 1 s during the first 3 seconds.

The hook at the end: an opinion question
What it is
The video ends with a strong, emotional, opinionated question tied to the thesis, which people answer with their own view: by choosing one of two or three words (“ONE or MANY?”) or sharing their own experience. Nei states his side first to provoke a response. The question’s tension appears in frame 0 and returns at the end.
What is not allowed
Promising anything to people who comment. No “I’ll send it,” “I’ll share it,” “send me the link,” “link in bio,” “comment X and…” or “it’s in the pinned comment.” No one is expecting a reply, so Nei does not need to respond to anyone. Asking people to “comment ONE or MANY” is allowed; what is not allowed is tying the comment to a reward. Links and sources can sit in the post’s pinned comment.

Quick glossary
Frame 0
The video’s first frame. It already shows the complete headline and serves as the cover.
Hook
The request for a comment at the end. In rtex, it is an opinion question (the script’s isca field); the options appear in the video’s only yellow pill.
Maxim
The closing summary line, phrased as an antithesis (“She isn’t stupid. She just doesn’t know your work.”), after a short silence.
Stage
The motor/palco.html page that draws the screens. The render records this page at 30 frames per second.
HeyGen and studio
HeyGen is the service that generates the avatar video. rtex uses the studio (the website, through a subscription) in a browser open on the virtual display :99.
Karaoke captions
Captions light up word by word in sync with speech, with keywords in color.
LUFS
A measure of perceived loudness. −14 LUFS is the volume level social networks use as a standard.
CTA
“Call to action”: the video’s final prompt. Here there is just one: the opinion question.
Whisper and Playwright
Whisper transcribes the voice and timestamps each word. Playwright opens the stage in a browser and captures every frame.
Critic and reviewer
The critic is a claude -p that scores each script block. The independent reviewer is another session that only looks at the result.
QA and contact sheet
QA (“quality assurance”) is the command that measures the finished video. The contact sheet is the image it builds with 16 video frames, so everything can be checked at once.
Pill
A rounded label. The numbered pills at the top (01–03 in the sample script) show which step the video is on; the yellow pill holds the final question’s options.
Bot and queue
Only on Nei’s machine: the bot is the Telegram robot that receives the video for him to watch; the queue publishes one video every 2 hours to the YouTube channel named in the script.
What changed from r7ex
rtex starts from the r7ex v1.1.0 engine (copied, not imported: changes to one do not affect the other). The machinery stays; the script and screen change.
| r7ex | rtex | |
|---|---|---|
| Script | 7 trigger stages: hook with a number → fear → desire → ease → discovery → benefit → comment | 9 step blocks: thesis → authority → problem → turn → method → evidence → caveat → maxim → cta |
| Opening | title drawn in the opening image | headline of up to 6 words in frame 0 (contrarian hook, loss, fear statistic, or someone else’s story) and an object that breaks during the first 3 seconds |
| Avatar | half screen at the bottom for the hook, then in the corner | in the bottom third for the entire reel; the top 2/3 are for content |
| On-screen structure | panels timed to the speech, counter | 01–N index that becomes pills at the top, “0N / NAME” label on each step |
| Honesty | — | mandatory caveat before the maxim; every number has a source checked within the last 7 days |
| Ending | comment “it’s all at inema.club” | silence, antithetical maxim, opinion question with a clear side (nothing to deliver), 9 s card |
| Color | black + yellow like a TV news show | INEMA black with restrained yellow: one yellow surface, the question’s options pill (QA counts it) |
| Kept | avatar through the HeyGen studio, karaoke captions, speech pacing, Whisper, critic + independent reviewer, publishing queue with timer and sending to the Telegram bot (the latter two only on Nei’s machine) | |
From script to video.mp4
rtex.py runs each step. The avatar is the slow part: the studio can take minutes or hours to deliver the video.
Validated script
checar checks the hook, evidence by 20 s, a single topic, block order, index = method, spoken lines without numerals or “!”, a source for every number, an opinion question with no promise, and an estimated duration of 60–90 s. critico gives it a score.
Avatar and timing
The speech goes to the studio; the video comes back, Whisper timestamps the words, the speech (HeyGen speaks quickly) is stretched to about 182 words/min (by no more than 12%), and silence is added before the maxim.
Scene, render, and QA
cena links each screen to a word in the speech; render records the stage, places the avatar below, and adds the music; qa measures everything and builds the contact sheet.
What needs to be on the machine
The engine was built for Nei’s Linux machine. The paths below are in the code; on a different machine, use the listed variables or adjust the file.
Avatar: HeyGen studio
A HeyGen account with your avatar and voice. The studio opens in a browser window, so it needs a display: the virtual display :99 (Xvfb). One-time setup: (1) log in to a Playwright browser profile; (2) in the studio, create a video project named exactly TEMPLATE-AVATAR16 (or another name in RTEX_HEYGEN_TEMPLATE), with your avatar and voice: the engine opens that project, chooses “edit as new,” and replaces the speech; (3) put your HeyGen API key in the file the downloader reads (fixed path in heygen/heygen-estudio-baixar.mjs; it only checks the status and downloads the video).
npx playwright open --user-data-dir ~/.cache/inemaccbot/perfil-heygen https://app.heygen.com # login; or another dir in RTEX_HEYGEN_PERFIL mkdir -p ~/projetos/openpcbotv2 echo "HEYGEN_API_KEY=sua-chave" >> ~/projetos/openpcbotv2/.env
Whisper (inemavox)
inematds/inemavox in ~/projetos/inemavox (or another path in CS_INEMAVOX). rtex tries the Whisper service on port 7871 and, if it is unavailable, runs inemavox’s transcrever_v1.py with large-v3 (about 10 GB of NVIDIA GPU memory). The resident Whisper Python comes from CS_WHISPER_PY; the default points to a chatterbox conda environment on Nei’s machine, so point it to yours.
git clone https://github.com/inematds/inemavox ~/projetos/inemavox # dependencies: see the inemavox README export CS_WHISPER_PY=/path/to/your/python3
Node, ffmpeg, Python
Node 18+, ffmpeg with ffprobe, Python 3 with Pillow, numpy, and cairosvg, the DejaVu font (the fonts-dejavu-core package, used for the name label), and the claude CLI logged in for the critic. Product logos (e.g., Claude’s in the sample script) come from an open package that ferramentas/logos.sh downloads once to ~/.cache/r7ex/lobe-icons; without it, the prints step stops.
git clone https://github.com/inematds/rtex cd rtex npm i npx playwright install chromium pip install --user pillow numpy cairosvg # or inside a venv bash ferramentas/logos.sh # logos -> ~/.cache/r7ex/lobe-icons Xvfb :99 -screen 0 1920x1080x24 & # only for the HeyGen studio
python3 rtex.py fazer <pasta> --de seu-video.mp4. The video’s speech must match the script at least 85% (the engine checks with Whisper). This path does not need HeyGen, a key, or Xvfb. Whisper listens in Portuguese; for a reel in another language, use CS_LANG=en or CS_LANG=es.enviar sends the video to Nei’s Telegram bot (bin/enviar_bot_v3.mjs) and fila adds the video to r7ex’s publishing queue (~/projetos/r7ex/fila/fila.py, or RTEX_FILA). Away from Nei’s machine, stop at qa and publish however you prefer.From topic to checked video
Each edition lives in edicoes/<data>-<slug>/. The fazer shortcut (step 9) runs checar, prints, avatar, cena, render, and qa in one go.
Create the edition you
Copy the sample script (one topic: “one agent and one folder per task”) to a new folder dated today. The sample’s sources were checked on 28/10/2026, and checar rejects sources older than 7 days: after 04/11/2026, the untouched sample will intentionally fail (this is not a bug). Replace the sources with your own in step 2.
python3 rtex.py novo minha-edicao # -> edicoes/YYYY-MM-DD-minha-edicao/roteiro.json
Write the script with sources you
Check every number against its source that day and record it in fontes[] with valor and verificado_em. Then write the hook, the blocks (format in “The roteiro.json file”), the full spoken lines, and the hook question.
Validate and run the critic
checar applies fixed rules. critico asks a claude -p running under the subscription to score it: it passes with no blockers, a thesis (the hook) score ≥ 8, an average ≥ 7.5, and no block below 6. It writes critica.json.
python3 rtex.py checar edicoes/YYYY-MM-DD-minha-edicao python3 rtex.py critico edicoes/YYYY-MM-DD-minha-edicao
Approve and send the avatar you
The upload only proceeds with written approval for this production in avatar/APROVADO_HEYGEN (one avatar per reel). After submission, the speech is frozen: text errors are fixed in the captions (the script’s trocas field), not by generating a second avatar.
mkdir -p edicoes/YYYY-MM-DD-minha-edicao/avatar echo "ok para este reel" > edicoes/YYYY-MM-DD-minha-edicao/avatar/APROVADO_HEYGEN python3 rtex.py avatar-enviar edicoes/YYYY-MM-DD-minha-edicao # writes avatar/video_id.txt
Capture page screenshots
Real screenshots of the cited GitHub pages and the logos. Open and read the screenshots before continuing.
python3 rtex.py prints edicoes/YYYY-MM-DD-minha-edicao
Preview without the avatar optional
While the studio is working, use a copy of the folder: synthetic timings, a scene, and a few individual frames (in seconds). Catch layout errors before the avatar arrives. The preview does not call the studio or use another avatar.
rm -rf /tmp/previa && cp -r edicoes/YYYY-MM-DD-minha-edicao /tmp/previa python3 ferramentas/tempos_sinteticos.py /tmp/previa python3 rtex.py cena /tmp/previa node motor/render.mjs /tmp/previa --quadros 1,10,20 # -> /tmp/previa/q_1.jpg, q_10.jpg, q_20.jpg
Download the avatar and adjust the pacing
avatar-conferir checks once (ready or processing). avatar waits, downloads, timestamps the words with Whisper, stretches the speech to about 182 words/min (HeyGen speaks quickly), adds silence before the maxim, and holds the card for 9 s.
python3 rtex.py avatar-conferir edicoes/YYYY-MM-DD-minha-edicao python3 rtex.py avatar edicoes/YYYY-MM-DD-minha-edicao python3 rtex.py avatar edicoes/YYYY-MM-DD-minha-edicao --de avatar.mp4 # reuse an mp4
Scene, render, and QA
The stage at 30 fps, avatar in the bottom third, music, and −14 LUFS in two passes; QA writes build/qa.json and the contact sheet build/folha.jpg with 16 frames.
python3 rtex.py cena edicoes/YYYY-MM-DD-minha-edicao python3 rtex.py render edicoes/YYYY-MM-DD-minha-edicao # -> video.mp4 python3 rtex.py qa edicoes/YYYY-MM-DD-minha-edicao
Or do it all at once
checar → prints → avatar → cena → render → qa. It does not run critico (step 3). Without --de and without a ready avatar, it sends the video to the studio itself and waits up to about 290 min for HeyGen; for this, the step 4 avatar/APROVADO_HEYGEN file must exist, or it stops with that notice. With --de, HeyGen is not needed, but Whisper, the logos, and internet access for GitHub screenshots are still required.
python3 rtex.py fazer edicoes/YYYY-MM-DD-minha-edicao python3 rtex.py fazer edicoes/YYYY-MM-DD-minha-edicao --de seu-video.mp4 # without the studio
Review, revise, and deliver you
Read the contact sheet and qa.json; ask someone who did not write the script to review it. The hook promises nothing, so there is nothing to prepare for commenters. On Nei’s machine, enviar sends it to the bot and fila adds it to the channel queue (never direct upload).
python3 rtex.py enviar edicoes/YYYY-MM-DD-minha-edicao python3 rtex.py fila edicoes/YYYY-MM-DD-minha-edicao
The script format, at a glance
Excerpt from the sample script, shortened (the // lines are not valid JSON; the full file is in modelo/roteiro.json).
{
"versao": "rtex/1", "tema": "Para de criar agente: um agente só e uma pasta por tarefa",
"gancho": { "tipo": "contrario" },
"isca": { "tipo": "opiniao", "pergunta": "Um agente só ou um para cada tarefa?",
"opcoes": ["UM", "VÁRIOS"], "lado": "um agente só", "tensao": "agente" },
"fontes": [ { "id": "skills", "url": "https://docs.anthropic.com/en/docs/agents-and-tools/agent-skills", "valor": "uma pasta por tarefa", "verificado_em": "2026-10-28" } ],
"trocas": { "é cê cê": "ECC", "três peças": "3 peças" },
"blocos": [
{ "tipo": "tese", "fala": "Se você cria um agente para cada tarefa, eu tenho uma má notícia: o fio que liga todos eles vai arrebentar.",
"tela": { "linhas": ["PARA DE", "CRIAR AGENTE."], "destaque": "AGENTE" },
"objeto": { "comp": "tese", "params": { "metafora": "fio", "nos": ["✉️ e-mail", "📷 Instagram", "📄 propostas"] } } },
// ... authority (source: skills), problem ("not your fault"), turning point ...
{ "tipo": "metodo", "n": 1, "nome": "PROCESSO", "fonte": "skills",
"fala": "Um: o processo. Peça para a IA te entrevistar, uma pergunta por vez, até ela fazer sem você.",
"objeto": { "comp": "pasta", "params": { "titulo": "O processo" } } },
// ... method 2–3, evidence, caveat, takeaway ...
{ "tipo": "cta", "fala": "Eu já escolhi o meu lado: um agente só. E você? Um agente só ou um para cada tarefa? Comenta um ou vários.",
"objeto": { "comp": "isca", "params": { "em": "Comenta" } } }
],
"publicar": { "descricao": "... Um agente só ou um para cada tarefa?" }
}
Main fields
tipo (the order of the nine blocks) · fala (spelled out, no numerals or “!”) · tela (large text and highlight) · objeto.comp + objeto.params (what the stage draws) · n and nome in method items (matching the turn index) · fonte (an id in fontes). At the top level: trocas (how speech appears in captions), cores (colored words), ritmo, and publicar (title, description, queue channel). checar also requires: a valid gancho.tipo and a frame 0 headline of up to 6 uppercase words; objeto.params.metafora in the thesis; for the maxim, linha1 and linha2 with up to 7 words each; sources checked no more than 7 days ago; and in isca: a pergunta ending in “?” (up to 70 characters) and spoken in the CTA, 2 or 3 one-word uppercase opcoes spoken in the CTA (for an open-ended question: exemplo, the answer the hand types), lado, tensao (a word from the question that appears in frame 0 and returns at the end), and publicar.descricao ending with the question. The old fields isca.palavra and isca.entregavel cause an error.
Stage components (objeto.comp)
tese, contador, chat_riscado, indice (with progress pills), pasta, repo (real screenshot + stars), manchete, selo_prova, ressalva, maxima (typographic flash), and isca (the question, yellow pill with options, and comment box). The tese with metafora: "fio" draws the object that breaks in frame 0.
“Stop using skills”
The first edition in the current format: contrarian hook, one topic (delete CLAUDE.md, skills and hooks, and bring back only what the model gets wrong again), three steps and the opinion question at the end. The video is in Portuguese. Script in edicoes/2026-10-28-pare-de-usar-skills/roteiro.json.
What QA measured
| Length | 76.1 s |
| Speech pace | 188 words/min |
| Loudness | −14.3 LUFS |
| Screen changes | 38 per minute |
| Longest static stretch | 3.5 s |
| Silence before the maxim | 0.52 s |
| End card | 9.0 s |
| Independent reviewer | approved, 8/10 |
It goes live on the INEMA channel (lives3) through the publishing queue. Audit kit for the topic: audit-ablacaocc.
“5 AI releases this month: the most useful one is a folder”
The first edition, made entirely with the engine and published on YouTube. It uses the v1.0.0 format: a list hook, five topics, and “comment FOLDER” with links promised to commenters. v1.1.0 replaced that with a strong hook, one topic per video, and an opinion question; the current checar intentionally rejects this script. Script in edicoes/2026-10-28-cinco-pecas-ia/roteiro.json and proposed question and headline ideas for the next one in PROPOSTA-ISCA.md, in the same folder.
What QA measured
| Duration | 81.1 s |
| Resolution | 1080×1920 · 30 fps |
| Speech pace | 180 words/min |
| Volume | −14.0 LUFS |
| Screen changes | 36 per minute |
| Longest still segment | 3.5 s |
| Silence before maxim | 0.58 s |
| End card | 9.0 s |
| Yellow surfaces | 1 (the hook) |
Frame by frame (published edition, v1.0.0 format)












The contact sheet generated by QA

Where the project stands
What is in the repository today and what comes later.
/rtex skill, long mode (110–135 s), and a light version.