Files
gart/code/Engine/docs/01_ARCHITECTURE.md
T
João HenriqueandClaude Opus 5 dcdd73edb5 docs: varredura geral, documentação por função e regra de atualização
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>
2026-08-19 22:51:33 -04:00

8.7 KiB

01 — Arquitetura do Sistema (G-ART / fcp-mcp-server)

Escopo: Como o sistema é dividido em camadas e onde cada responsabilidade mora. Não cobre: Detalhe módulo a módulo (→ 02) · ferramentas MCP (→ 03) · app (→ 08)

Referência canônica de como o sistema está dividido. Leia antes de qualquer mudança de código. Se algo aqui divergir do código, o código está certo e este documento está velho — corrija-o no mesmo commit.

Última varredura: 2026-08-19 · 74 ferramentas MCP · 1.454 testes · versão 0.6.35


1. Visão de cima (camadas)

O sistema lê, analisa e reescreve FCPXML do Final Cut Pro. Ele opera fora do FCP: você exporta o XML, o programa processa como dados estruturados e devolve um XML para importar. Nada é patcheado, nenhuma API privada é usada.

São quatro camadas, e o ponto importante é que existem duas portas de entrada diferentes para o mesmo motor:

┌──────────────────────────┐     ┌──────────────────────────────┐
│  MacApp/  (SwiftUI)      │     │  Cliente MCP (Claude)        │
│  O app que o usuário usa │     │  Conversa, decide a edição   │
└───────────┬──────────────┘     └───────────────┬──────────────┘
            │ subprocesso + JSON-lines           │ JSON-RPC (stdio)
            ▼                                    ▼
┌──────────────────────────┐     ┌──────────────────────────────┐
│  admin/models_api.py     │     │  server.py + server_tools/   │
│  + admin/api/            │     │  74 tools, dispatch, schemas │
│  37 comandos da ponte    │     │  NÃO tem lógica de timeline  │
└───────────┬──────────────┘     └───────────────┬──────────────┘
            └───────────────┬────────────────────┘
                            ▼
            ┌───────────────────────────────────┐
            │  fcpxml/  — O ENGINE              │
            │  Núcleo puro Python, desacoplado. │
            │  Não conhece MCP nem o app.       │
            │  É onde quase tudo mora.          │
            └───────────────────────────────────┘

A regra que sustenta tudo: nem server.py nem admin/api/ implementam lógica de timeline. Os dois validam entrada, chamam o engine e formatam a saída. Toda regra de negócio é testável sem MCP e sem app.

Por que duas portas. O MCP existe para o julgamento editorial — qual tomada usar, onde dar zoom — que é conversa com uma IA. A ponte existe para o que o usuário faz sozinho no app — transcrever, configurar, processar. As duas caem no mesmo engine, então uma correção ali vale para as duas.


2. Regras transversais (valem em todo o código)

Conceito Regra
Tempo TimeValue, fração racional "600/2400s". Nunca float para tempo.
Tempo de decisão Ações de voz usam sempre segundos da mídia original, nunca pós-corte.
I/O paths Sempre via _validate_filepath / _validate_output_path (sandbox).
Nome de saída Nunca sobrescrever o original: generate_output_path() gera _suffix.
Segurança XML Sempre defusedxml via safe_xml.py. Nunca xml.etree direto para ler.
Deps opcionais librosa/ffmpeg/huggingface_hub importados lazy, degradam com None.
Idioma Comunicação com o usuário em português. Código e comentários em inglês.
Validação ./Engine/run_after_fix.sh sempre após cada correção.
App Alterou MacApp/? Compile e rode: ./MacApp/build_app.sh --run.

3. Fluxo de um request

Pela porta MCP (Claude decidindo a edição)

Cliente MCP ──JSON-RPC──► server.py
                            │ TOOL_HANDLERS[nome]
                            ▼
                          server_tools/<categoria>.py
                            │ _shared/: valida path, parseia projeto
                            ▼
                          fcpxml/  (parser → writer → safe_xml)
                            ▼
                          projeto_<suffix>.fcpxml   (original intocado)

Pela porta do app (usuário operando)

MacApp ──Process + argv JSON──► admin/models_api.py
                                  │ handlers[comando]
                                  ▼
                                admin/api/<assunto>.py
                                  │ shared.emit() devolve JSON-lines
                                  ▼
                                fcpxml/  (ou chama um handler do server)
                                  ▼
                                arquivo gerado + caminho de volta ao app

A saída da ponte é JSON-lines: um documento JSON por linha, para que comandos longos transmitam progresso enquanto rodam. Toda escrita passa por admin/api/shared.py::emit, que serializa o acesso a stdout — dois comandos escrevendo ao mesmo tempo entrelaçariam documentos.


4. Dual-mode: XML + Live

  • Modo XML (principal): exporta FCPXML, processa como dados, reimporta.
  • Modo Live (fcpxml/live.py): push do FCPXML direto para o FCP em execução via Apple events oficiais (Open Document). Leitura de bibliotecas via AppleScript read-only.

Assimetria estrutural: import é scriptable, mas a Apple não oferece export programático. Round-trips sempre voltam pelas ferramentas XML.


5. Onde está cada responsabilidade

Responsabilidade Fica em
Modelos de dados (tempo, clips, markers, QC, legendas) fcpxml/models/
Parse FCPXML → objetos fcpxml/parser.py
Edição e escrita de FCPXML fcpxml/writer/
Geração de timeline nova fcpxml/rough_cut.py
Comparação de timelines fcpxml/diff.py
Export cross-NLE (Resolve, FCP7) fcpxml/export.py
Silêncio e beats fcpxml/media_intel.py
Transcrição Whisper fcpxml/transcribe.py
Diarização (quem falou) fcpxml/diarize.py
Ênfase acústica fcpxml/emphasis.py, fcpxml/voice_features.py
Timeline de voz (o JSON que a IA lê) fcpxml/voice_timeline.py
Decisões de edição (cut/zoom/text/marker) fcpxml/voice_actions.py
Revisão de frases da etapa 5 fcpxml/phrase_review.py
Layout de legendas e métricas de fonte fcpxml/text_layout.py, font_metrics.py, collision.py
Gestão de modelos Whisper fcpxml/model_manager.py
Controle Live do FCP fcpxml/live.py
Segurança XML fcpxml/safe_xml.py
Validação contra DTDs da Apple fcpxml/dtd.py
Transporte MCP (74 tools) server.py + server_tools/
Ponte com o app (37 comandos) admin/models_api.py + admin/api/
Interface do usuário MacApp/Sources/

6. Mapa de dependências

MacApp/            ──► admin/models_api.py  (subprocesso, por caminho)
admin/api/         ──► fcpxml/*  e, para algumas operações, server.py
server.py          ──► server_tools/*
server_tools/*     ──► server_tools/_shared/  ──► fcpxml/*
fcpxml/writer/     ──► fcpxml/models/, safe_xml, dtd, text_layout, collision
fcpxml/models/     ──► fcpxml/text_layout  (só o pacote subtitles)
fcpxml/__init__.py ──► reexporta a API pública

A seta que não existe, e não deve existir: fcpxml/ nunca importa de server_tools/, de admin/ ou de qualquer coisa que saiba o que é uma tool. Se você precisar disso, a lógica está no lugar errado.


7. Criando algo novo — por onde começar

Você quer… Comece por
Uma ferramenta MCP nova Função pura em fcpxml/ + teste. O handler em server_tools/ fica fino.
Um comando do app novo Mesmo caminho, e exponha em admin/api/<assunto>.py + tabela em models_api.py.
Uma tela nova MacApp/Sources/, consumindo comandos que já existem na ponte.
Uma regra de edição nova fcpxml/ sempre. Se você está escrevendo if sobre timeline fora de fcpxml/, pare.

O trabalho principal é sempre no engine. As camadas de cima são finas de propósito: é o que permite testar 1.454 casos sem abrir o app nem subir o MCP.