A documentação descrevia um sistema que não existe mais: 62/73 ferramentas
(são 74), writer.py e models.py como arquivos (viraram pacotes), 1032 testes
(são 1454), models_api.py descrito como "API FastAPI" (é ponte JSON) e o app
SwiftUI ausente por completo — 5.500 linhas que o usuário opera todo dia sem
uma linha de documentação.
Cada arquivo passa a ter uma função específica, com cabeçalho de escopo
dizendo o que cobre e o que NÃO cobre (com a seta para quem cobre). O objetivo
é ler só o necessário: doc fora do assunto custa tempo e processamento sem
entregar nada.
01 arquitetura camadas, duas portas de entrada, regras transversais
02 módulos mapa do engine, incluindo o pipeline de voz
03 server/tools as 74 tools, helpers e como criar uma nova
08 app macOS NOVO — build por swiftc, telas, ponte, etapa 5
09 manutenção NOVO — por onde começar, o que está aberto, sintoma→arquivo
CLAUDE.md ganha a seção "Documentação (MANDATORY)": tabela de roteamento
(qual arquivo abrir para cada tarefa) e a regra de que toda alteração de
código atualiza a doc no mesmo commit, com o mapa de o-que-mexeu → o-que-
atualizar. Doc velha engana mais que doc ausente.
O índice do 05_EXPERIENCIAS subiu para o topo: consultar "isso já quebrou
antes?" custava carregar 1.281 linhas antes de chegar na tabela.
Dívidas levantadas na varredura e registradas em 09 §2: etapa 6 ainda ignora
o phrase_review.json, offset de ~400ms do Whisper, MacApp sem teste, admin/
fora do lint, confirmações visuais pendentes no FCP, submódulo WHISPERX sujo.
Também corrigidos dois links quebrados no Engine/README que apontavam um
nível acima do certo.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
7.6 KiB
09 — Manutenção: onde mexer, o que está aberto, o que dói
Escopo: Por onde começar cada tipo de tarefa, o que está aberto e onde dói. Não cobre: Como as coisas funcionam — este doc roteia para quem explica
Este é o documento de rota. Os outros descrevem o que é; este diz o que fazer e por onde começar quando chega uma implementação, uma melhoria ou uma correção.
Última varredura: 2026-08-19 · 1.454 testes · lint zerado
1. Chegou uma tarefa — por onde começo?
| A tarefa é… | Comece em | Não esqueça |
|---|---|---|
| Regra nova de edição (corte, zoom, legenda) | fcpxml/<módulo> + teste |
Expor na tool e na ponte, senão só metade dos usuários alcança |
| Corrigir XML que o FCP recusa | fcpxml/writer/ + dtd.py |
Validar contra o DTD real, não só o teste |
| Mudança visível na interface | MacApp/Sources/ |
Abrir a tela — compilar não prova nada (§4) |
| Comando novo para o app | admin/api/<assunto>.py |
Registrar na tabela de models_api.py |
| Ferramenta MCP nova | server_tools/<categoria>.py |
Schema Tool(...) + TOOL_HANDLERS |
| Ajuste de análise de voz | fcpxml/voice_*, emphasis.py |
Regerar os _voice_timeline.json de teste |
| "Está lento" / "está errado" e não sei onde | §5 (mapa de sintomas) | — |
A pergunta que resolve 90% das dúvidas de lugar: essa lógica precisa saber
o que é uma tool MCP ou uma tela? Se não precisa — e quase nunca precisa — ela
vai para fcpxml/.
2. O que está aberto agora
Ordenado por quanto atrapalha, não por esforço.
2.1 A etapa 6 ignora a revisão de ênfases
O usuário lapida as frases na etapa 5, o _phrase_review.json é gravado — e a
etapa 6 ainda processa como antes. Falta ligar: zoom e legenda dinâmica só
nas frases de ênfase, legenda comum no resto. É a continuação natural do
trabalho da etapa 5 e o item mais valioso da lista.
→ MacApp/Sources/WizardView.swift (finalizeProcessing), admin/api/subtitles.py,
fcpxml/phrase_review.py (emphasis_spans já é produzido e ninguém consome).
2.2 Offset de ~400 ms no timing por palavra
O faster-whisper sem alinhamento forçado erra o início de cada palavra em
~0,4 s. Isso desloca zoom, corte e gap_before de uma vez. Há paliativo
aplicado por projeto; a correção estrutural é ligar o WhisperX (ou
alinhamento equivalente) em transcribe.py, o que levaria o erro para ~30 ms.
Custo real: regerar todos os _transcript.json e _voice_timeline.json
existentes. → 05_EXPERIENCIAS.md #14, estado parcialmente resolvido.
2.3 MacApp/ não tem teste automatizado
5.500 linhas de Swift sem uma asserção. A rede hoje é o harness manual (§4) e o olho do usuário. Não é para sair criando suíte de UI — mas lógica pura que foi parar na camada de tela (cálculo de trim, mapeamento de tempo) deveria descer para o Python, onde já existe rede.
2.4 admin/ fica fora do lint
run_after_fix.sh roda o ruff de dentro de code/, então admin/ — 1.751
linhas de código que o app depende para funcionar — nunca é verificado.
Incluir mexe no gate, então é decisão consciente, não esquecimento.
2.5 Confirmações visuais pendentes no FCP
Várias entradas do 05_EXPERIENCIAS.md estão marcadas como resolvidas no XML
— testes verdes, DTD válido — mas pendentes de importação real no Final Cut.
XML válido não é o mesmo que XML que renderiza como o esperado. Ao mexer em
legenda, zoom ou keyframe, a confirmação final é abrir no FCP.
2.6 Submódulo WHISPERX com conteúdo modificado e não commitado
Está fora dos commits de propósito, porque ninguém verificou o que mudou lá dentro. Precisa ser olhado e resolvido — ou commitado, ou revertido.
3. Onde o código ainda é grande (e onde isso não é problema)
Quatro arquivos foram divididos (writer.py, models.py, models_api.py,
_shared.py): 6.685 linhas concentradas viraram 43 módulos.
O que sobrou grande, e o diagnóstico honesto de cada um:
| Arquivo | Linhas | Vale dividir? |
|---|---|---|
fcpxml/text_layout.py |
901 | Não. É diagramação — um assunto coeso. |
fcpxml/rough_cut.py |
798 | Não. É geração de timeline, um assunto. |
fcpxml/model_manager.py |
748 | Talvez: mistura catálogo, download e config. |
server_tools/voice.py |
754 | Talvez, se crescer mais. |
MacApp/TranscriptionView.swift |
843 | Sim, quando for mexer nela. |
MacApp/WizardView.swift |
808 | Sim: sete etapas num switch só. |
Critério, não número: divida quando o arquivo tiver assuntos que não se falam. Um arquivo grande de um assunto só é mais fácil de ler que seis arquivos pequenos que você precisa abrir juntos. Código picado sem motivo atrapalha tanto quanto arquivo gigante.
4. Checklist antes de dar algo por pronto
cd code && ./Engine/run_after_fix.sh # lint zerado + 1.454 testes
cd code && ./MacApp/build_app.sh --run # se mexeu no app
E, além do script:
- Mexeu na interface? Abriu a tela? Compilar não prova que roda —
VideoPlayercompilava e abortava (05_EXPERIENCIAS.md#22). - Mexeu em XML? Importou no FCP? DTD válido ≠ renderiza certo.
- Dividiu ou moveu módulo? Procure
patch('<módulo>.e imports relativos dentro de funções — é o que quebra em silêncio (#23). - Criou teste fora de
code/tests/? Confirme que a contagem total subiu. Teste fora detestpathsnão roda e dá falsa sensação de rede (#24). - Problema estrutural ou erro recorrente? Registre em
05_EXPERIENCIAS.mdcom o índice atualizado. - Documentação divergiu? Corrija no mesmo commit. Doc velha engana mais que doc ausente.
5. Mapa de sintomas → onde olhar
| Sintoma | Suspeite de | Arquivo |
|---|---|---|
| FCP recusa o arquivo ao importar | id inválido, ordem de filhos, timebase |
writer/validation.py, dtd.py |
| Título importa mas não aparece | Template/uid Motion que não resolve | writer/titles.py |
| Corte no lugar errado | Tempo pós-corte usado como se fosse original | voice_actions.py (shift_after_cuts) |
| Zoom no lugar errado | Idem, ou offset de timing do Whisper | §2.2 |
| Legenda sobrepondo | Layout ou conteúdo antigo no arquivo | collision.py, text_layout.py |
| "Ênfase" apontando para palavra à toa | Falta renormalizar após o corte | refine_voice_timeline |
| App diz que falta librosa/pyannote | uv run com cwd errado |
PythonBridge.swift (§3 do doc 08) |
| Tela do app fecha o programa | Componente de framework que só falha em runtime | 05_EXPERIENCIAS.md #22 |
| Comando existe no MCP mas não no app | Falta expor na ponte | admin/api/, #20 |
6. Convenções que não são negociáveis
Estão em 01_ARCHITECTURE.md §2 e valem repetir as três que mais custaram:
- Tempo é fração racional. Float para tempo produz drift que só aparece depois de dez operações encadeadas.
- Ação de voz é sempre em tempo da mídia original. Nunca pós-corte.
- Original nunca é sobrescrito. Toda saída ganha sufixo.
Documentos relacionados
- 01 Arquitetura — camadas e onde cada coisa mora
- 02 Módulos — mapa do engine, módulo a módulo
- 03 Server/Tools — as 74 ferramentas MCP
- 04 Testes & Workflow
- 05 Experiências — o que já quebrou e por quê
- 06 Boas Práticas
- 08 App macOS — o app e o Assistente