Auditoria do sistema de IA da v1.9.7¶
Data da auditoria: 2026-07-14. Base auditada: main em
7e309076cca6aa6def73fd9fbf99796319f9f859 (v1.9.6).
Estado inicial verificável¶
HEAD,origin/maine o commit apontado pela tag anotadav1.9.6resolviam para7e309076cca6aa6def73fd9fbf99796319f9f859.- A árvore estava limpa e a branch ativa era
main;v1.9.7ainda não existia localmente nem no remoto. - Os workflows CI, CodeQL e Docs estavam verdes no commit inicial.
- A extensão declarava
0.9.2embrowser-extension/manifest.json. python scripts/check_data_health.pyinformou schema SQLite 3 saudável, com um warning preexistente de oportunidade sem referência de origem. A auditoria foi somente leitura.- O scan inicial de padrões Gemini/OpenAI em arquivos rastreados não encontrou segredo.
modules/scraping/browser_session.pyemodules/scraping/connectors/authenticated_browser.pytiveram hashes SHA-256 registrados antes da implementação para conferência final.- As variáveis opt-in de teste Gemini e OpenAI estavam presentes. Somente a presença booleana foi verificada; nenhum valor foi impresso, persistido ou recuperado.
Superfície de IA encontrada¶
Chamadas estruturadas de provider estavam presentes em extração de currículo, extração de
vaga, classificação de domínio, Match, ATS, Tailor, análise de repositório GitHub, importação
de Lattes, importação de edital, extração de itens de Perfil, enriquecimento de fonte e duas
funções do Radar (wishlist e explicação). O fallback determinístico usa MockProvider,
parsers locais e regras dos módulos de domínio.
| Tarefa observada | Prompt em produção | Consumidor principal | Fallback local | Career Context/RAG |
|---|---|---|---|---|
| currículo | resume_extraction_v1 |
structured_resume_extractor.py |
sim | não no payload atual |
| vaga | job_extraction_multi_domain_v1 |
structured_job_extractor.py |
sim | não no payload atual |
| domínio | domain_classification_v1 |
domain_classification_service.py |
sim | contexto explícito opcional |
| Match | match_analysis_evidence_based_v1 |
structured_analysis.py |
sim | sim, compartilhamento opt-in |
| ATS | ats_analysis_v1 |
apps/api/services/analysis.py |
sim | somente confirmado no provider |
| Tailor | resume_tailor_v1 |
apps/api/services/analysis.py |
sim | somente confirmado no provider |
| GitHub/repositório | github_repo_analysis_v2 |
github_analyzer/analyzer_service.py |
sim | itens confirmados e não sensíveis |
| Lattes | profile_lattes_extractor_v1 |
academic/lattes_service.py |
sim | não |
| edital | public_exam_notice_extractor_v1 |
public_exams/service.py |
sim | Perfil é usado na elegibilidade local |
| Perfil | profile_items_extractor_v1 |
apps/api/services/profile.py |
sim | não altera Perfil sem aprovação |
| fonte | source_import_enrichment_v1 |
apps/api/services/sources.py |
sim | não |
| Radar/wishlist | job_wishlist_builder_v1 |
apps/api/services/radar.py |
sim | Perfil permitido e filtrado |
| Radar/explicação | job_radar_match_explanation_v1 |
apps/api/services/radar.py |
sim | via resultado local/wishlist |
| conselho de carreira | career_advice_v1 |
nenhum | não exercitado | não exercitado |
Registry e governança antes da mudança¶
O PromptRegistry tinha 14 prompts com versão, system prompt, template, schema, temperatura e
modo. Não declarava tarefa, providers suportados, política de contexto, suite de avaliação,
golden cases ou métricas. A busca de consumidores demonstrou um prompt registrado sem
consumidor (career_advice_v1). Três documentos de prompt não correspondiam a um contrato
ativo do registry: github-profile-analysis-v1.md, portfolio-gap-analysis-v1.md e
hidden-job-detection-v1.md. Os dois primeiros representam tarefas desejadas; o último fica
fora do registry de tarefas da v1.9.7 e deve permanecer apenas como proposta até existir
consumidor, schema e avaliação.
Não foi localizado consumidor de produção que criasse prompt ad hoc fora do loader. As
chamadas encontradas resolviam o prompt com default_prompt_registry().get(...) ou recebiam
um PromptRegistry injetado.
Outputs, warnings e fallbacks¶
- Resume e job validavam o output estruturado, mas a API devolvia o resultado do parser local; o output rico do provider era usado para confidence/warnings e depois descartado da resposta.
- ATS e Tailor aproveitavam apenas subconjuntos do output estruturado. Campos adicionais do schema não tinham armazenamento próprio.
- Erros de ATS e Tailor eram capturados por
except Exceptione convertidos em warning genérico; tipo de erro, latência e tentativa do provider não eram persistidos. - Lattes, edital, Perfil, Radar e enriquecimento tinham fallback e warning no domínio, mas não
gravavam
AiRunpelo caminho comum. - O fallback era visível nas respostas principais da API, porém inexistia um painel agregado para detectar taxa ou motivo de fallback.
analysis_snapshotspersistia resultados completos por desenho da v1.9.6;ai_runsera separado e guardava somente metadados. A v1.9.7 deve manter traces sem conteúdo integral.
AiRunStore antes da mudança¶
AiRunStore existia no schema 3 e era chamado apenas por _trace_metadata em cinco fluxos:
currículo, vaga, Match, ATS, Tailor e GitHub compartilham a função, mas não havia uso equivalente
nas demais chamadas estruturadas. O store tinha provider/modelo solicitado e usado, prompt,
modo, fallback, schema, token_usage, custo opcional, hash, fontes, refs, evidências, warnings e
revisão. Não tinha task_id, versões de schema, propósito/contagem de contexto, timestamps de
início/fim, tokens normalizados, erro sanitizado, benchmark/parent run, paginação por offset,
retenção nem política configurável de conteúdo.
Embora existissem campos para tokens, custo e latência, nenhum dos providers propagava essas
métricas até _trace_metadata; portanto os runs de produção ficavam sem esses valores. O
provider solicitado e o usado eram expostos nas respostas, mas falhas internas podiam registrar
modelo solicitado como modelo usado quando o fallback era local.
Evidência, contexto e confiança¶
O CareerContextEngine já era aplicado a Match, ATS, Tailor e GitHub. Para providers externos,
o envio de memória era opt-in; itens sensíveis eram omitidos e ATS/Tailor formatavam apenas
evidência confirmada. Esse comportamento é uma boa base de segurança. Não existia, porém,
benchmark A/B entre ausência de Perfil, Perfil confirmado, Perfil + RAG e contexto não
confirmado.
Confidence de currículo e vaga era uma soma heurística de presença de campos. Schemas
estruturados guardavam confidence por campo, mas não havia golden labels, reliability bins,
Brier score ou erro de calibração. Match possuía confidence_score, também sem calibração
medida. Afirmações sem evidence podiam atravessar schemas válidos, pois schema validation não
equivale a validação de suporte factual.
Riscos priorizados e correções da v1.9.7¶
- Criar
AiTaskRegistrycomum e ligar cada prompt de produção a exatamente uma tarefa. - Completar tracing secret-free em todos os fluxos e normalizar provider/modelo/fallback/erro.
- Criar golden datasets multiárea, métricas determinísticas e benchmark reproduzível.
- Tratar texto de currículo, vaga, edital e README como conteúdo não confiável delimitado.
- Validar claims proibidos e referências de evidência depois do schema.
- Capturar feedback humano apagável ligado ao
run_id. - Relacionar outcomes manuais do Tracker sem inferir causalidade ou alterar Perfil/pesos.
- Expor agregados com regras explícitas de amostra e sem texto pessoal integral.
- Testar local/mock sempre e providers externos somente pelas variáveis temporárias permitidas.
- Conservar fallback local, JSON/JSONL legado e toda a superfície authenticated-browser.
Limites desta auditoria¶
As métricas de qualidade não são declaradas aqui porque não existia dataset executável na base inicial. Valores de schema validity, evidence precision, unsupported claim rate, hallucination, calibração, latência, tokens e custo só podem ser publicados após a implementação e execução dos benchmarks. A presença das chaves opt-in não é evidência de uma chamada bem-sucedida.