Lendo o v5.12 completo antes de responder.O documento v5.12 chegou como texto no <documents>, não como arquivo separado. Vou trabalhar com o conteúdo que está no índice 2.
Após leitura completa do v5.12 cruzada com os 21 pontos que levantei na análise do v5.4, aqui está o balanço honesto:
O que foi resolvido de forma excelente
Dos críticos: os pontos 2 e 5 (schema formal de curate_runs ausente) foram integralmente resolvidos — o schema SQL completo com CHECK constraints, índices e comentários está presente e sem ambiguidade. O ponto 6 (pipeline_stage sem enum fechado) foi resolvido com CHECK constraint formal no schema de curate_run_items, incluindo 'dict_match' que eu havia sinalizado como estágio sem nome. O ponto 3 (race condition Fluxo B concorrente) foi resolvido com documentação explícita das 3 camadas de proteção: FOR UPDATE SKIP LOCKED, deduplicação por linkedin_id e curation_status = 'pending' como filtro.
Dos altos: o ponto 8 (is_active = false sem política) foi resolvido via curation_status como discriminador canônico, o que implicitamente resolve a ambiguidade. O ponto 9 (arquivos externos sem exemplos) foi resolvido — family_synonyms.json e domain_synonyms.json agora têm schema Zod formal e posição clara na Camada 2. O ponto 10 (usage_count sem definição) foi resolvido com campo formal em job_canonical_roles.
Melhorias além do que eu havia sinalizado: a quarentena (quarantined_llm_output) é uma adição arquitetural relevante que o v5.4 não tinha — resolve o caso de vagas com parse error recorrente sem jogar permanentemente em low_quality. O circuit_breaker_state com tabela persistida e transição atômica open → half_open é uma solução sofisticada e correta. A pré-rotina de hash com job_runs.metadata eliminando campos de versão desnormalizados é uma simplificação elegante.
O que ainda merece atenção
Residual crítico — ponto 1 da análise anterior (inflação de distinct_sources_count por grupos empresariais): o v5.12 documenta o algoritmo de normalização corretamente e menciona fuzzy matching como pós-produção. Mas ainda não define o gatilho objetivo para ativar a revisão. Sugestão concreta para adicionar na governança mensal: query que detecta canônicos com distinct_sources_count >= 5 onde >= 3 sources têm prefixo de nome em comum — sinaliza candidatos a inflação por grupo.
Novo ponto — quarantine_released_at e rate limit 200/24h: o PASSO 3 verifica SELECT COUNT(*) WHERE quarantine_released_at >= CURRENT_DATE antes de executar. Mas CURRENT_DATE é timezone-naive no PostgreSQL quando a sessão não tem timezone configurado. Com o Supabase em UTC e usuários em Brasília (UTC-3), o “dia atual” do banco pode ser diferente do dia percebido pelo operador. Considerar quarantine_released_at >= NOW()::date com timezone explícito ou AT TIME ZONE 'America/Sao_Paulo'.
Novo ponto — source = 'merge' em job_canonical_roles sem comportamento documentado: o CHECK constraint inclui 'merge' como valor válido de source, mas nenhuma seção do documento descreve quando e como um canônico recebe source = 'merge'. O fluxo de merge admin está no backlog mas sem spec — por ora o valor fica no enum sem comportamento definido, o que pode confundir o implementador.
Residual médio — ponto 12 da análise anterior (alerta de pending_review conta histórico): a query de alerta ainda faz COUNT(*) FROM curate_run_items WHERE status = 'pending_review' sem filtro temporal. Vai crescer indefinidamente. Sugestão: trocar para COUNT(*) FROM job_canonical_roles WHERE status = 'pending' — que reflete o estado atual da taxonomia, não o acúmulo histórico de itens de run.
Novo ponto — curation_status = 'retryable_error' sem transição documentada: o CHECK constraint inclui 'retryable_error' como estado válido em job_postings, mas o fluxo do pipeline nunca documenta quando uma vaga recebe esse status nem como sai dele. Está implícito que é para erros transitórios que voltam à fila, mas a distinção com 'pending' e com 'quarantined_llm_output' precisa estar explícita — especialmente porque o loop de busca de vagas pendentes usa curation_status = 'pending', o que significa que retryable_error não entra automaticamente na fila sem intervenção.
Ponto cosmético persistente — título do documento: o cabeçalho da tabela de mudanças referencia “v5.37” em vez de “v5.4” na coluna direita. Esse resíduo ainda está presente no documento v5.4 que foi a base — não sei se foi corrigido no v5.12 já que o v5.12 chegou como texto parcial.
Balanço geral
De 21 pontos levantados na análise do v5.4, o v5.12 resolveu aproximadamente 16 de forma completa e 3 parcialmente. Os 2 críticos que persistem são o gatilho objetivo para inflação de distinct_sources_count e o timezone do rate limit de quarentena. Os demais são refinamentos que não bloqueiam a implementação mas que valem registrar antes do Sprint 1 começar.
A evolução entre as versões é substancial. O v5.12 está em condição de ser entregue ao Antigravity para o Sprint 1 com confiança — os riscos remanescentes são todos documentáveis como notas de implementação, não como lacunas de arquitetura.