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/mainev1.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¶
FunnelConversionna camada de DTO eFunnelConversionMetricno 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.MemoryStoreexiste emmodules/memoryemodules/ragcom responsabilidades diferentes. O nome é ambíguo, mas renomeá-lo quebraria compatibilidade; documentar e convergir em versão com migration/import aliases.- 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.
- Metadados de fallback estão espalhados em
AiTraceMetadata, providers, tracing e benchmark. A correção deve nascer de um contrato comumProviderError/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_applicablequando 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 cincoServerErrore quatroClientError; - OpenAI
gpt-4.1-mini: 0/10 válido, todos reduzidos aProviderUnavailableError; - 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-repairefallbackainda 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;
ApplicationLabServicecomo 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-labe/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.