docs(skill): alinhar editar-por-voz com a revisão humana da etapa 5

A skill decidia a edição sem saber que o JSON dela agora passa por uma tela
de revisão antes de virar FCPXML. Isso não é detalhe de fluxo: a etapa 5
traduz cada ação para o vocabulário dela, e sem conhecer essa tradução a
intenção da IA se perde no caminho — que é exatamente como uma decisão vira
"arbitrária" aos olhos de quem revisa.

Novo criterios/10-revisao-humana.md, com o que o app faz com cada ação:

- cut cobrindo >=60% da frase remove a linha; tocando só uma borda vira trim
  encaixado na fronteira de palavra. Corte de meia frase é ambíguo — passa
  do limiar e apaga a linha toda quando a intenção era aparar a hesitação.
- zoom ou text sobre uma frase marca ênfase, e ênfase significa DUAS coisas:
  zoom mais legenda dinâmica; as demais frases ficam com legenda comum. A
  escala vira o nível (1.15→leve, 1.3→média, 1.5→forte).
- sem ação, o nível é derivado do peak_emphasis; a decisão da IA sempre ganha.
- reason é exibido ao lado da frase na tela — é o que o editor lê antes de
  manter ou desfazer. Deixou de ser campo de log.

Consequência prática que faltava em 05-zoom.md: não espalhar zoom "por
segurança", porque cada um promove a frase em duas dimensões ao mesmo tempo.
Na dúvida, deixar sem — promover custa uma tecla, despromover custa mais.

Cada arquivo de critério ganhou cabeçalho de escopo (o que cobre, em que
fase), no mesmo padrão dos docs do Engine, para ler só o necessário.

Todas as afirmações numéricas do novo critério foram verificadas contra
fcpxml/phrase_review.py rodando, não assumidas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
João Henrique
2026-08-19 22:54:51 -04:00
co-authored by Claude Opus 5
parent dcdd73edb5
commit cbd9297751
11 changed files with 191 additions and 7 deletions
+15 -2
View File
@@ -28,6 +28,12 @@ minutos.
`apply_voice_actions` aplica direto, mas é para **teste**. O produto do seu `apply_voice_actions` aplica direto, mas é para **teste**. O produto do seu
trabalho é a lista de decisões. trabalho é a lista de decisões.
**Para onde ela vai:** o usuário cola o seu JSON no app, e ele abre na etapa 5
do Assistente — uma tela onde cada frase do roteiro aparece com a sua decisão
já marcada, para ser revisada antes de gerar. Você é o **ponto de partida** da
edição, não a palavra final; escreva decisões defensáveis e motivos legíveis.
Como o app traduz cada ação sua: `criterios/10-revisao-humana.md`.
## Ordem de trabalho ## Ordem de trabalho
Siga nesta ordem. Pular a Fase 2 ou a 3 leva a decisões erradas. Siga nesta ordem. Pular a Fase 2 ou a 3 leva a decisões erradas.
@@ -44,6 +50,9 @@ Siga nesta ordem. Pular a Fase 2 ou a 3 leva a decisões erradas.
| **7** | Cortar a lista pelo ritmo | `criterios/07-ritmo.md` | | **7** | Cortar a lista pelo ritmo | `criterios/07-ritmo.md` |
| **8** | Montar o JSON de saída | `criterios/08-formato-de-saida.md` | | **8** | Montar o JSON de saída | `criterios/08-formato-de-saida.md` |
**Antes da Fase 5, leia `criterios/10-revisao-humana.md`.** Ele descreve o que
o app faz com o seu JSON — e muda *como* escrever cortes e zooms, não só quais.
## As três armadilhas ## As três armadilhas
Cada uma já causou erro silencioso em material real: Cada uma já causou erro silencioso em material real:
@@ -69,10 +78,14 @@ disso e o efeito cai no frame errado — sem erro visível.
``` ```
build_voice_timeline → [você decide] → refine_voice_timeline → [você corta build_voice_timeline → [você decide] → refine_voice_timeline → [você corta
pelo ritmo] → apply_voice_actions → remove_media_silence → pelo ritmo] → [revisão humana na etapa 5 do app] → apply_voice_actions →
generate_dynamic_subtitles remove_media_silence → generate_dynamic_subtitles
``` ```
A revisão humana entra entre a sua decisão e a aplicação. É por isso que o
`reason` importa tanto: ele é lido ali, na hora de decidir se a sua escolha
fica.
Vícios de linguagem e lacunas longas entram na **sua** lista, num ripple só Vícios de linguagem e lacunas longas entram na **sua** lista, num ripple só
(`06-texto-corte-marcador.md`). Silêncio fino e legendas vêm depois. (`06-texto-corte-marcador.md`). Silêncio fino e legendas vêm depois.
@@ -1,5 +1,8 @@
# 01 — Leitura do JSON # 01 — Leitura do JSON
> **Escopo:** Como ler o voice_timeline em camadas, sem recalcular o que já foi medido.
> **Quando:** Fase 1 — ver a ordem de trabalho em `../SKILL.md`.
O arquivo `<mídia>_voice_timeline.json` é a entrada de todo o trabalho. O arquivo `<mídia>_voice_timeline.json` é a entrada de todo o trabalho.
Leia em camadas, de cima para baixo, e só desça quando precisar. Leia em camadas, de cima para baixo, e só desça quando precisar.
@@ -1,5 +1,8 @@
# 02 — Triagem: roteiro vs. conversa de bastidor # 02 — Triagem: roteiro vs. conversa de bastidor
> **Escopo:** Separar o texto do roteiro da conversa de bastidor — tarefa de texto, nunca de limiar.
> **Quando:** Fase 2 — ver a ordem de trabalho em `../SKILL.md`.
**Primeira coisa a fazer, antes de qualquer decisão de efeito.** **Primeira coisa a fazer, antes de qualquer decisão de efeito.**
Material bruto de gravação quase nunca é uma tomada só. A pessoa lê o Material bruto de gravação quase nunca é uma tomada só. A pessoa lê o
@@ -1,5 +1,8 @@
# 03 — Escolha da melhor tomada # 03 — Escolha da melhor tomada
> **Escopo:** Qual tomada de cada frase sobrevive, e o que fazer em caso de empate.
> **Quando:** Fase 3 — ver a ordem de trabalho em `../SKILL.md`.
A mesma frase costuma aparecer 2, 3, 4 vezes. Seu trabalho é ficar com A mesma frase costuma aparecer 2, 3, 4 vezes. Seu trabalho é ficar com
**uma**. **uma**.
@@ -1,5 +1,8 @@
# 04 — Reanálise do material que sobrou # 04 — Reanálise do material que sobrou
> **Escopo:** Renormalizar a ênfase sobre o que sobrou, antes de escolher zooms.
> **Quando:** Fase 4 — ver a ordem de trabalho em `../SKILL.md`.
**Não escolha zooms com os números da análise bruta.** **Não escolha zooms com os números da análise bruta.**
## O problema ## O problema
@@ -1,5 +1,8 @@
# 05 — Zoom (punch-in) # 05 — Zoom (punch-in)
> **Escopo:** Onde dar punch-in, qual janela e qual escala — e o que a escala significa além do zoom.
> **Quando:** Fase 5 — ver a ordem de trabalho em `../SKILL.md`.
## Quando usar ## Quando usar
No momento em que o argumento vira. Um pico acústico só merece zoom se for No momento em que o argumento vira. Um pico acústico só merece zoom se for
@@ -46,14 +49,24 @@ automático acerta na quase totalidade dos casos.
## Escala ## Escala
| Valor | Uso | | Valor | Uso | Vira, na tela de revisão |
|---|---| |---|---|---|
| 1,15 | sutil | | 1,15 | sutil | ênfase **1 — Leve** |
| 1,18 – 1,3 | padrão | | 1,18 – 1,3 | padrão | ênfase **2 — Média** |
| 1,5 | forte | | 1,5 | forte | ênfase **3 — Forte** |
Em vídeo institucional, fique na faixa baixa. Acima de 3,0 é rejeitado. Em vídeo institucional, fique na faixa baixa. Acima de 3,0 é rejeitado.
**A escala tem um segundo efeito, e ele é maior que o zoom.** A frase que
recebe um zoom é marcada como **ênfase** na etapa 5, e frase de ênfase recebe
**legenda dinâmica**; as demais ficam com legenda comum. Ou seja: escolher onde
dar zoom é também escolher onde o texto ganha tratamento tipográfico.
Consequência prática: **não espalhe zoom "por segurança"**. Cada um promove uma
frase a destaque em duas dimensões ao mesmo tempo. Na dúvida, deixe sem — o
editor promove numa tecla, e despromover custa mais que promover.
Detalhe: `10-revisao-humana.md`.
O zoom é **relativo ao enquadramento existente**: se o clipe já tem escala O zoom é **relativo ao enquadramento existente**: se o clipe já tem escala
1,77 (material gravado de lado e reenquadrado), um zoom 1,18 anima de 1,77 1,77 (material gravado de lado e reenquadrado), um zoom 1,18 anima de 1,77
para 2,09 e preserva rotação e posição. para 2,09 e preserva rotação e posição.
@@ -1,5 +1,8 @@
# 06 — Texto, corte e marcador # 06 — Texto, corte e marcador
> **Escopo:** Texto na tela, o que cortar (inclui muletas e lacunas) e quando marcar.
> **Quando:** Fase 6 — ver a ordem de trabalho em `../SKILL.md`.
## Texto ## Texto
Para fixar um **conceito, número ou nome** que o espectador precisa reter. Para fixar um **conceito, número ou nome** que o espectador precisa reter.
@@ -1,5 +1,8 @@
# 07 — Ritmo # 07 — Ritmo
> **Escopo:** Quantos efeitos cabem: os tetos e como escolher o que fica.
> **Quando:** Fase 7 — ver a ordem de trabalho em `../SKILL.md`.
**O erro mais comum é efeito demais.** Cansa mais que efeito de menos, e **O erro mais comum é efeito demais.** Cansa mais que efeito de menos, e
denuncia edição automática. denuncia edição automática.
@@ -1,5 +1,8 @@
# 08 — Formato de saída # 08 — Formato de saída
> **Escopo:** O JSON de entrega: estrutura, regras e como o programa trata erros.
> **Quando:** Fase 8 — ver a ordem de trabalho em `../SKILL.md`.
O produto do seu trabalho é **este JSON**. É ele que vai para o programa O produto do seu trabalho é **este JSON**. É ele que vai para o programa
gerar o FCPXML. Você nunca escreve XML. gerar o FCPXML. Você nunca escreve XML.
@@ -53,6 +56,19 @@ uma. Um `reason` vazio é sinal de decisão sem critério.
Inclua o dado que embasou: *"abertura: 'Aquela mama' (ênfase 0.42)"* é útil; Inclua o dado que embasou: *"abertura: 'Aquela mama' (ênfase 0.42)"* é útil;
*"zoom"* não é. *"zoom"* não é.
Não é campo de log: o texto é **exibido na tela de revisão**, ao lado da frase,
e é o que o editor lê antes de manter ou desfazer o que você decidiu.
### 6. Corte: alinhe à intenção
A tela lê cada `cut` contra as frases da transcrição:
- cobre **≥ 60%** de uma frase → aquela frase é **removida**;
- toca só o **começo** ou só o **fim** → vira **trim** (a frase fica, aparada).
Então corte a frase **inteira** quando quiser removê-la, e corte **só da borda
até a palavra** quando quiser aparar uma hesitação. Um corte de meia frase é
ambíguo — passa de 60% e apaga a linha toda. Detalhe: `10-revisao-humana.md`.
## Como o programa trata erros ## Como o programa trata erros
- **Ação inválida** → rejeitada e reportada **individualmente**. Uma linha - **Ação inválida** → rejeitada e reportada **individualmente**. Uma linha
@@ -1,5 +1,8 @@
# 09 — Quando a análise veio incompleta # 09 — Quando a análise veio incompleta
> **Escopo:** O que fazer quando uma camada da análise não rodou.
> **Quando:** Fase 0 — ver a ordem de trabalho em `../SKILL.md`.
O bloco `layers` no topo do JSON diz **o que de fato rodou**. Leia antes de O bloco `layers` no topo do JSON diz **o que de fato rodou**. Leia antes de
qualquer outra coisa. qualquer outra coisa.
@@ -0,0 +1,121 @@
# 10 — A revisão humana: o que acontece com o seu JSON
> **Escopo:** O que o app faz com o seu JSON na etapa 5 — muda como escrever as ações.
> **Quando:** ler antes da Fase 5 — ver a ordem de trabalho em `../SKILL.md`.
> Leia antes de decidir cortes e zooms. Muda **como** escrever as ações, não
> apenas quais.
Seu JSON não vai direto para o FCPXML. Ele é colado no app e abre na **etapa 5
do Assistente**, uma tela onde o editor vê cada frase do roteiro com a sua
decisão já aplicada e lapida antes de gerar.
Isso tem duas consequências práticas:
1. **Suas decisões são lidas por uma pessoa, frase a frase.** Uma decisão sem
motivo explícito parece arbitrária — e será desfeita.
2. **A tela traduz suas ações para o vocabulário dela.** Se você não escrever
as ações do jeito que essa tradução espera, a intenção se perde no caminho.
---
## Como cada ação sua é lida
O app quebra a gravação em **frases** (os segmentos do voice timeline) e
projeta suas ações sobre elas.
### `cut`
| O corte cobre… | Vira | Na tela |
|---|---|---|
| **≥ 60%** da frase | frase **desativada** | apagada, riscada, reativável num clique |
| só o **começo** ou só o **fim** | **trim** da frase | a frase fica, aparada nas pontas |
| um pedaço no **meio** | nada em si | só conta para a regra dos 60% |
O trim é **encaixado na fronteira de palavra** mais próxima. Você não precisa
acertar o frame: mire na palavra onde a frase deve começar ou terminar.
**O que isso pede de você:** decida se está removendo *a linha* ou *aparando*
uma ponta, e escreva o corte de acordo.
- Removendo a linha → corte a frase inteira, de ponta a ponta.
- Aparando um falso começo → corte só da borda até a palavra onde a fala
engata. Um corte que cobre meia frase é ambíguo: passa de 60% e apaga a linha
toda, quando você só queria tirar a hesitação.
### `zoom` e `text`
Qualquer `zoom` ou `text` que toque uma frase marca aquela frase como
**ênfase** — e ênfase, nesta tela, significa **duas coisas**:
> **A frase de ênfase recebe zoom E legenda dinâmica. As demais recebem
> legenda comum.**
O nível vem da sua `scale`:
| `scale` | Nível na tela | |
|---|---|---|
| 1,15 | 1 — Leve | |
| 1,3 | 2 — Média | |
| 1,5 | 3 — Forte | |
| omitida, ou uma ação `text` | 2 — Média | padrão |
Sem nenhuma ação sua, a tela deriva o nível do `peak_emphasis` da frase
(< 0,25 → sem ênfase; < 0,45 → leve; < 0,65 → média; acima → forte). **A sua
decisão sempre ganha da derivação automática.**
**O que isso pede de você:** escolher a escala com intenção. Ela não é só
"quanto amplia" — é o peso que aquela frase terá no vídeo inteiro, incluindo o
tratamento da legenda. Um zoom leve numa frase de apoio não é neutro: promove
aquela frase a destaque tipográfico também.
### `marker`
Não altera a frase. Continua sendo o seu recado para o editor conferir uma
emenda — e é a ferramenta certa quando você está em dúvida (ver
`03-escolha-da-melhor-tomada.md`).
---
## `reason` aparece na tela
Não é campo de log. O texto que você escreve em `reason` é exibido para o
editor ao lado da frase selecionada, e é o que ele lê antes de manter ou
desfazer a sua decisão.
Escreva para quem está com pressa e vai decidir na hora:
- **Bom:** `"fecho, pico em 'devolver' (ênfase 0.34) — escala mais forte por ser o fechamento da peça"`
- **Ruim:** `"zoom"` · `"corte necessário"` · `"melhor tomada"`
A regra prática: se o `reason` não contém **o dado** que embasou (a palavra, o
número, a comparação entre tomadas), você provavelmente não tinha critério —
tinha impressão.
---
## O que a tela NÃO desfaz por você
- **Tempo errado continua errado.** A tela mostra suas ações no eixo da mídia
original; se você compensou para pós-corte, tudo aparece no lugar errado e o
editor não tem como adivinhar o que você quis dizer.
- **Excesso de zoom continua excesso.** A tela não impõe o teto de 2–4 por
minuto (`07-ritmo.md`) — ela mostra o que você mandou. Efeito demais chega
ao editor como trabalho de limpeza.
- **Frase promovida a ênfase sem querer.** Como zoom e legenda dinâmica andam
juntos, espalhar zooms "de segurança" enche o vídeo de legenda dinâmica. Na
dúvida, deixe sem — o editor promove; é mais barato que despromover.
---
## Depois da revisão
O editor pode, na tela: mudar o nível de ênfase (0–3), desativar ou reativar
frases, corrigir o texto, aparar as pontas por palavra, reclassificar entre
roteiro e bastidor e acrescentar zooms manuais em trechos arbitrários.
O resultado vira um `_phrase_review.json` e o `_phrase_actions.json` derivado —
e é esse que a geração usa. **Seu JSON é o ponto de partida da conversa, não a
palavra final.** Trabalhe para ser um bom ponto de partida: decisões
defensáveis, motivos legíveis e nenhuma escolha que o editor precise desfazer
antes de começar.