Skip to content

feat(startup): a primeira execução era muda, incompleta e sem rumo - #566

Merged
MarkSant merged 2 commits into
mainfrom
claude/startup-feedback-improvements-5c260d
Sep 8, 2026
Merged

MarkSant merged 2 commits into
mainfrom
claude/startup-feedback-improvements-5c260d

Conversation

@MarkSant

@MarkSant MarkSant commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Três lacunas no intervalo entre o duplo-clique e a primeira análise. A
investigação corrigiu a premissa de duas delas.

1. O ícone parecia morto por ~4 s

Não era o benchmark. De logs/analysis.log de uma execução real:

Instante Evento
22:42:12 application.starting
22:42:15 benchmark.running_first_time
22:42:15 benchmark.completed — duration_s: 0.2

O vão está antes do benchmark. O splash era criado na linha 138 de
app_runner, depois do bloco de imports das linhas 122–135. Dois custos
com cara de import comum estavam na frente dele:

  • from zebtrack.utils import set_seed — zebtrack.utils importa torch em
    corpo de módulo, ~1,1 s (medido com python -X importtime).
  • o bloco di_registrations — puxa ultralytics, cv2 e matplotlib por cima do
    torch, ~3 s.

O splash agora é construído logo após i18n.install(), antes dos dois.
tests/core/test_app_runner_splash_ordering.py fixa a ordem, não a
duração: uma asserção de tempo seria instável e não diria por que regrediu.

2. O benchmark não media nada — e cacheava isso

As etapas 3–5 são guardadas por if video_path and model_path and profile.openvino_available. Numa instalação nova openvino_model_cache/ não
existe, então _find_openvino_model() devolvia None e todas eram
puladas: 0,2 s no total, recomendando CPU a 0.0 FPS — resultado que ia para
o cache e nunca mais era recalculado.

Agora converte um modelo para OpenVINO antes de medir (nova etapa 2 de 7). Não
é sobrecarga: é trabalho que a aplicação pagaria de qualquer forma no primeiro
uso real do OpenVINO. Um resultado que ainda assim não mediu nada é marcado
inconclusivo e não vai para o cache.

As 7 etapas também ganharam tempo mínimo em tela. Elas sempre foram enviadas
ao splash — a fiação estava certa — mas várias terminam em milissegundos e eram
pintadas e sobrescritas dentro do mesmo quadro, então a sequência só existia no
log.

Ancorei também em repo_root() os três caminhos que eram relativos ao CWD
(get_benchmark_cache_path, _find_test_video, _find_openvino_model): pelo
atalho concordavam por sorte — o .lnk fixa WorkingDirectory — mas de outro
diretório --reset apagava um arquivo e o app escrevia outro.

3. A instalação trazia 4 dos 6 pesos

A razão registrada no código era circular: os generalistas ficavam de fora do
download porque WeightManager não sabia descobri-los — a varredura pegava
só best_*_lateral.pt e best_*_topdown.pt, então eles caíam em weights/ e
nunca apareciam no catálogo. O defeito real era a lacuna de descoberta;
corrigida (discover_weights() varre best_*.pt), o download deixou de
precisar modelá-la. --all continua aceito e agora não muda nada.

Um generalista nunca toma um slot padrão — os especialistas são treinados
para um ângulo de câmera específico, e um modelo lateral numa cena de topo não
devolve nada.

4. Nenhuma orientação inicial

O painel de configuração de modelos não tinha entrada de menu nenhuma: era
alcançável só por um botão dentro da visão de projeto. A única tela que o
operador precisa antes da primeira análise era a que ele não conseguia achar.

Nova janela de primeiros passos depois da principal, que lê o hardware
detectado
em vez de dar conselho genérico ("use OpenVINO se não tiver NVIDIA"
é verdade e inútil para quem não sabe o que tem). Mais Configurações →
Definições de modelo...
e Ajuda → Primeiros passos....

A caixa "não mostrar novamente" grava apenas ui.show_welcome via
write_local_override() — nunca save_settings, que congelaria a árvore
inteira de defaults em config.local.yaml.

Release

Versão para 7.1.0, CHANGELOG e docs/releases/RELEASE_NOTES_v7.1.0.md.
weights_manifest.json continua apontando para v7.0.0 de propósito: esse
release está publicado e já carrega os seis pesos com os tamanhos exatos do
manifesto, então fetch-weights funciona no instante do merge, sem depender de
publicar o v7.1.0.

Verificação

  • pytest -q — 6751 passed, 4 skipped
  • pytest -m gui -n0 — 1224 passed
  • ruff check . e mypy . — limpos (907 arquivos)
  • mutation_check --changed-since origin/main — 8/8 (100%), sem sobreviventes
  • pre-commit run --all-files — verde
  • Traduções pt_BR anexadas à mão (26 entradas) e verificadas em runtime, não só compiladas

🤖 Generated with Claude Code

Três lacunas no intervalo entre o duplo-clique e a primeira análise.

O splash era criado DEPOIS do bloco de imports que monta o grafo de
coordinators, então a janela só aparecia com o carregamento pesado já
terminado. Sob o atalho (pythonw.exe, sem console) isso é indistinguível
de um ícone morto. Dois custos estavam na frente dele, ambos com cara de
import comum: `zebtrack.utils` importa torch em corpo de módulo (~1,1 s) e
`di_registrations` puxa ultralytics, cv2 e matplotlib por cima (~3 s) —
medido em logs/analysis.log entre application.starting e
benchmark.running_first_time. O splash agora vem antes dos dois.

O benchmark não era o gargalo que parecia: ele levava 0,2 s porque não
media NADA. As etapas 3-5 são guardadas por `model_path`, e numa
instalação nova openvino_model_cache/ não existe, então todas eram
puladas. Recomendava CPU a 0.0 FPS, cacheava isso e nunca mais
recalculava. Agora converte um modelo antes de medir — trabalho que a
aplicação pagaria de qualquer forma na primeira análise — e um resultado
que ainda assim não mediu nada é marcado inconclusivo e não vai para o
cache. As 7 etapas também ganharam tempo mínimo em tela: elas sempre
foram enviadas ao splash, mas várias terminam em milissegundos e eram
sobrescritas dentro do mesmo quadro.

A instalação trazia 4 dos 6 pesos. A razão registrada era circular: os
generalistas ficavam de fora do download PORQUE o catálogo não sabia
descobri-los — a varredura pegava só best_*_lateral.pt e best_*_topdown.pt.
O defeito real era a lacuna de descoberta. Corrigida, o download deixou de
precisar modelá-la. Um generalista é registrado mas nunca toma um slot
padrão: os especialistas são treinados para um ângulo específico.

E o painel de configuração de modelos não tinha entrada de menu nenhuma —
a única tela que o operador precisa antes da primeira análise era a que
ele não conseguia achar. Agora há uma janela de primeiros passos depois da
principal, que lê o hardware detectado em vez de dar conselho genérico
sobre OpenVINO, mais Configurações -> Definições de modelo e Ajuda ->
Primeiros passos.

Também ancora em repo_root() os três caminhos do benchmark que eram
relativos ao CWD: pelo atalho concordavam por sorte, de outro diretório
--reset apagava um arquivo e o app escrevia outro.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

O CI do Windows reprovou test_get_weight_path_by_method. A descoberta agora
é quem registra best_seg.pt/best_oi.pt (antes as settings do teste é que
registravam, com a string exata), e o caminho passa a vir da listagem do
diretório: no runner o tempfile devolve o nome longo do usuário enquanto a
listagem devolve a forma curta 8.3 (RUNNER~1). Mesmo arquivo, duas grafias
— a asserção estava fixando ortografia de caminho, não identidade.

Compara resolvidos dos dois lados. Não é defeito de produção: nada lá
compara o path armazenado como string, `validate_weight_files` usa
os.path.exists e `_maybe_relocate_path` já resolve antes de comparar.

Os testes de dual_init escapam porque neles as settings registram os pesos
primeiro e a descoberta pula o que já está no catálogo; só o caso que zera
as settings dependia da descoberta. Guard novo em
test_weight_manager_discovery.py fixa o contrato de identidade.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@MarkSant
MarkSant merged commit 457a27e into main Sep 8, 2026
6 checks passed
@MarkSant
MarkSant deleted the claude/startup-feedback-improvements-5c260d branch September 8, 2026 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant