Pular para conteúdo

Auditoria de repositório e fluxo de produto — v1.9.8

Escopo e estado inicial

Auditoria executada em 2026-07-28 sobre os 1.133 arquivos encontrados em modules/, apps/api/, apps/web/, browser-extension/, config/, scripts/, tests/, docs/, examples/ e .github/, além dos arquivos de configuração e documentação na raiz.

  • branch: main;
  • árvore inicial: limpa;
  • HEAD, origin/main e v1.9.7: a09a85ee81ee831fa959686aa7f5f47cf9523fba;
  • release pública inicial: v1.9.7;
  • app: 1.9.7;
  • extensão: 0.9.3;
  • schema SQLite: 4, íntegro e com todas as migrations verificadas;
  • CI, CodeQL e Docs do commit inicial: concluídos com sucesso;
  • scan inicial: 1.729 arquivos, nenhum padrão de chave de provider;
  • v1.9.8: ausente local e remotamente.

O health check encontrou um registro pessoal preexistente de oportunidade sem referência de origem. A release não deve alterar esse dado automaticamente. O dry-run da migração encontrou stores legados preservados e 69 memórias duplicadas, sem apagar ou importar automaticamente.

Limites protegidos

Os endpoints de authenticated-browser vivem em apps/api/routes/sources.py; a sessão e o connector vivem nos dois módulos explicitamente protegidos. Eles são PUBLIC_API/ACTIVE e ficam fora do escopo de alteração da v1.9.8.

Arquivo SHA-256 inicial Classificação
apps/api/routes/sources.py 396957E3286618E2B1327DB681F66F6269690E2BFD907D8E97714B5D4C7024FF PUBLIC_API
modules/scraping/browser_session.py 4B7454A581C32D6E88777C408C9F1F8F928F3F56B579E0035F07028B4EB37B65 ACTIVE
modules/scraping/connectors/authenticated_browser.py 4F7E41BFF478873EF7D3E90AE67BCD6FF284FB4CBE36C70D217F3CD234264AB3 ACTIVE

Mapa ponta a ponta

Capacidade Produz Persiste Consome Identidade e dedupe Snapshot/source ref Warning e continuidade
Perfil Universal API e UniversalCareerProfileService store JSON legado gradual e tabelas profiles/profile_items ProfileContextOrchestrator, Career Context, análises profile_id, item_id, conteúdo normalizado e confirmação item mantém source_ref; ainda não há snapshot de perfil dedicado candidatos inferidos permanecem revisáveis; UI segue para currículo/análise
Career Context CareerContextEngine não cria fonte nova; monta visão em memória Match, ATS, Tailor, Radar, Tracker, IA dedupe por kind + source_ref ou título/conteúdo normalizado preserva CareerContextEvidence.source_ref filtra sensíveis e emite warnings por propósito
Document Ingestion LocalDocumentIngestionPipeline resultado transitório extração de currículo e fontes hash/conteúdo e provenance por página/seção DocumentProvenance.source_ref arquivo inválido/tamanho/MIME bloqueiam continuação
Currículo atual parser e endpoint /resume/extract store legado de análise e snapshot quando salvo no Tracker Match, ATS, Tailor conteúdo normalizado; não existe master_resume_id ResumeSnapshot só é criado em fluxos específicos UI fragmentada; não existe currículo mestre retomável
Vaga parser, captura pública, extensão e /job/extract oportunidade/captura e job_snapshots Match, ATS, Radar, Tracker URL normalizada, capture_id, opportunity_id, content hash JobSnapshot imutável com source_refs warning de origem/confiança; usuário navega manualmente entre páginas
Match motor determinístico e revisão opcional de IA analysis store, AiRunStore, snapshot quando salvo ATS, Tailor, Tracker, Outcome run_id e hashes de inputs; regras distribuídas AnalysisSnapshot guarda evidence/source refs fallback existe, mas metadados de erro externo são pobres
ATS regras locais e task opcional trace e snapshot quando salvo Tailor e Tracker run_id, keywords normalizadas evidence refs no trace separa keyword segura de claim sem evidência
Tailor regras de resume_tailor e IA opcional trace e snapshot quando salvo export/Tracker run_id; sugestão não tem entidade própria source/evidence refs no trace saída é sugestão, mas falta aceitar/editar/rejeitar por item
Application Lab inexistente no estado inicial inexistente principal lacuna de orquestração
Resume Studio inexistente no estado inicial inexistente ResumeSnapshot já oferece fundação principal lacuna de currículo mestre/variantes/diff
Tracker TrackerService/JobTracker JSON legado e applications SQLite Dashboard, Intelligence, Outcome record/application ID, URL e snapshots suporta job/resume/match/ATS snapshots não conhece sessão, readiness, kit ou plano
Snapshots SnapshotStore tabelas imutáveis com triggers Tracker, backup e Outcome content hash + IDs da fonte job, resume, analysis e edital cobertura boa; faltam kit/plano e vínculos do Lab
Feedback API de qualidade de IA ai_feedback dashboard de qualidade feedback_id, run_id referencia trace, não conteúdo integral revisão humana explícita
Outcome Learning OutcomeStore outcome_events/outcome_metrics painel de qualidade event/application ID e agrupamentos referencia aplicação/variante quando informado mostra n; não altera pesos automaticamente
AI Quality benchmark, traces e feedback ai_runs, benchmarks e resultados /ai-quality run/benchmark/result IDs apenas metadados seguros não diagnosticava categoria, request ID ou Retry-After
Extensão captura pública e ações explícitas chrome.storage/fila offline; companion ao sincronizar Source/Tracker/GitHub capture_id, URL e chave idempotente companion cria snapshots não há ação “Preparar candidatura” no estado inicial
Radar JobRadarService e fontes permitidas wishlists/runs/results/notifications Tracker e Dashboard identity key/URL/cooldown source refs, sem snapshot em todo resultado ação segura é salvar/revisar, nunca candidatar automaticamente
Lattes LattesService Perfil após confirmação e snapshots de edital quando aplicável Context, Match e Perfil item/source ref e confirmação provenance da importação conteúdo inferido entra como candidato
Editais PublicExamService tabelas e PublicExamSnapshot plano de estudo, Tracker notice/role/content hash snapshot imutável requisitos devem ser confirmados pelo usuário
GitHub/Portfólio analisador de repositório público projetos, traces e perfil candidato Context, Match e portfólio URL/repo/commit/evidence IDs source refs públicos not_applicable fora de domínios pertinentes
Notificações Radar/scheduler local notifications Dashboard/Radar source/result/cooldown referência, não cópia completa somente lembrete local; sem calendário externo automático

Código morto e compatibilidade

Classificação baseada em imports, rotas, testes e documentação; baixa contagem de referências isoladamente não foi considerada prova de código morto.

Candidato Classificação Evidência/decisão
modules/profile/career_profile.py e modules/profile/schemas.py COMPATIBILITY fallback do ProfileContextOrchestrator e testes legados; manter até migração explícita
modules/ui/** Streamlit PUBLIC_API/COMPATIBILITY interface ainda documentada e testada; não remover
modules/rag/memory_store.py ACTIVE memória ranqueada usada pelo Career Context
modules/memory/memory_store.py COMPATIBILITY store de memória de carreira, contrato distinto apesar do nome repetido
scripts de captura/package/health DEV_TOOL consumidos por QA, CI ou release
mocks do frontend DEV_TOOL necessários ao modo demo explicitamente identificado
aliases antigos de provider COMPATIBILITY migração de configuração testada; manter com plano de remoção posterior

Nenhum símbolo foi classificado como DEAD com evidência suficiente no estado inicial. Logo, nenhum código deve ser removido apenas para reduzir contagem. A remoção futura dos contratos legados exige telemetria local ou uma migration explícita e está fora desta release.

Duplicações confirmadas

  1. FunnelConversion na camada de DTO e FunnelConversionMetric no domínio repetem o mesmo contrato. A fronteira API/domínio justifica dois modelos, mas a transformação precisa ficar centralizada; não é seguro apagar um deles nesta release.
  2. MemoryStore existe em modules/memory e modules/rag com responsabilidades diferentes. O nome é ambíguo, mas renomeá-lo quebraria compatibilidade; documentar e convergir em versão com migration/import aliases.
  3. Parsing/normalização de JSON aparece em stores SQLite distintos. A v1.9.8 deve reutilizar um repositório específico do novo domínio e não criar mais uma camada genérica prematura.
  4. Metadados de fallback estão espalhados em AiTraceMetadata, providers, tracing e benchmark. A correção deve nascer de um contrato comum ProviderError/ProviderExecutionMetadata.

Regras de negócio encontradas

  • score de Match/ATS já é determinístico; IA explica, não decide o score;
  • evidência confirmada prevalece sobre candidata/inferida;
  • GitHub é evidência opcional e deve ser not_applicable quando não fizer sentido;
  • snapshots são imutáveis e deduplicados por hash e identidade da fonte;
  • candidatura muda somente por ação humana; outcomes não provam causalidade;
  • fallback local existe, porém não era sempre distinguível de erro externo na UI;
  • sugestões de Tailor não são aplicadas automaticamente, mas faltava estado revisável por item;
  • não há definição central de readiness, pesos, bloqueadores obrigatórios ou confidence;
  • listas novas devem ser paginadas e dependências invalidadas quando vaga/currículo mudar.

A v1.9.8 centralizará readiness em regras determinísticas próprias, manterá explicação de IA separada e exigirá evidência/source refs para qualquer sugestão aceita.

Auditoria de providers — antes das correções

As chaves temporárias foram lidas somente das variáveis opt-in. O teste externo inicial teve 2 passes Gemini e 2 xfail OpenAI; esse xfail genérico é um defeito, não aprovação.

No smoke real 20260728T070103Z-release-smoke-197:

  • local: 12/12 schemas válidos;
  • Gemini gemini-2.5-flash: 1/10 válido, com cinco ServerError e quatro ClientError;
  • OpenAI gpt-4.1-mini: 0/10 válido, todos reduzidos a ProviderUnavailableError;
  • o runner limitava o release-smoke a dez chamadas externas, embora o dataset tenha 12 casos;
  • request ID, categoria, Retry-After, finish reason, safety, shape e schema error não eram preservados no resultado público;
  • as suites provider-diagnostic, provider-structured-output, schema-repair e fallback ainda não existiam.

Essas métricas são amostra diagnóstica, não ranking de provider nem baseline válido.

Lacunas priorizadas e plano de fechamento

P0 — confiabilidade e segurança de IA

  • taxonomia sanitizada de erro e classificação precisa de 429;
  • retry pequeno com jitter e respeito a Retry-After somente quando retryable;
  • schema nativo compatível, detecção de truncamento/safety/empty e um único repair controlado;
  • fallback explícito em API/UI/trace/benchmark;
  • suites externas diagnóstica, structured output e release-smoke com 12 casos.

P0 — jornada e persistência

  • migration 5 idempotente com sessões, reports, sugestões, currículo mestre/variantes, exports, kit e plano;
  • ApplicationLabService como orquestrador dos motores existentes;
  • invalidar somente dependências de vaga/currículo que mudaram;
  • snapshots e vínculo completo no Tracker sem auto-apply.

P1 — experiência web e extensão

  • rotas /application-lab e /resume-studio, responsivas e acessíveis;
  • estados reais de loading/empty/error/retry/partial/fallback/offline/cancelled;
  • editor/diff/preview/JSON Resume; PDF/DOCX permanecem honestamente pendentes se não houver validação visual suficiente;
  • extensão 0.9.4 com ação “Preparar candidatura” enviando somente IDs seguros.

P1 — QA, docs e release

  • unit/integration/component/E2E, export e migration health;
  • screenshots/GIF com dados fictícios;
  • capability/matriz/catálogo, README, roadmap e arquitetura sincronizados;
  • scan final, hashes protegidos, CI/CodeQL/Docs verdes, tag e release pública.