Diário — Semana 10 (13/10/2026)
Período: 07/10 a 13/10/2026 — escrito em 11/10 e completado em 12/10; a semana fecha na entrega da E2, em 13/10
Quem trabalhou: Luis (@Luidooo), Iago (@iagorrr), Luiza (@LuizaMaluf), Moura (@thegm445)
Pauta: levar a matéria do DOU até o OLTP, tornar a ingestão reexecutável e organizar o que falta para a E2. Em 12/10, com o login automático do INLABS barrado, trocar a fonte da ingestão automática.
O que foi feito
- Revisão do PR #22 aplicada (08/10): três dos quatro comentários do Iago viraram mudança. O PR foi aprovado e mergeado em 10/10, e a #18 foi fechada.
- Persistência de uma matéria no OLTP (PR #23, do Luis, aberto em 10/10 e mergeado em 11/10, fecha a #19): o pacote
oltpgrava a matéria ematocomorigem = 'DOU', sob o órgão que oartCategorynomeia. - Revisão do PR #23 pela Luiza (11/10), com dois ajustes aplicados na própria branch.
- A E2 foi reorganizada em 11 issues (#24 a #34, criadas pela Luiza em 11/10). A #6 e a #20 foram fechadas e divididas em fatias menores: #24, #27 e #28.
make ingest(PR #35, do Luis, aberto em 11/10 e mergeado em 12/10, fecha a #24 e a #27): encadeiafetchepersist, e pode rodar de novo sem duplicar. A Luiza revisou e aplicou seis ajustes na própria branch.- CI (PR #38, do Luis, mergeado em 12/10):
make testemake vet-gorodam em todo PR. - Registro do dia no bronze (PR #41, da Luiza, mergeado em 12/10, fecha a #28): no lugar do ZIP que não veio, o
fetchdeixaAAAA-MM-DD-DO1.sem-edicaoouAAAA-MM-DD-DO1.falhou, e omake persistdiz qual dos três casos é. - Janela de reprocessamento e correções da revisão do #23 (PRs #39 e #40, do Luis, abertos em 11 e 12/10).
- Primeira tentativa de baixar dias reais do INLABS (12/10), com credencial: o login automático foi recusado (ver "O que surpreendeu").
- Ingestão mensal pelos dados abertos da Imprensa Nacional (issue #42 e PR #43, da Luiza, mergeado em 12/10):
make ingest-mensal MES=AAAA-MMbaixa a Seção 1 de um mês inteiro, sem login, e grava com o mesmopersist. - Tabela Delta, CDC e semântica de entrega comprovada com injeção de caos (PRs #48 e #49, e issue #30, do Moura): camada analítica Delta Lake em Parquet/ZSTD particionada por ano, CDC incremental via slot lógico do Postgres (
conselhos_lake, plugintest_decoding), e demonstração empírica de tolerância a falhas (make cdc-chaos/tests/lake/test_cdc.sh). Derrubando o consumidor intencionalmente após o MERGE no Delta e antes de confirmar o LSN (--falhar-apos-gravar, exit code 42), o reprocessamento subsequente absorve o evento sem duplicar linhas, mantendo a contagem rigorosamente idêntica. - Estes diários (issue #26).
O que foi medido
| Medida | Valor | Onde conferir |
|---|---|---|
| PR #23 (persistência) | 11 arquivos, +614 −7, 2 commits | PR #23 |
Contagens de ato, orgao, orgao_nome e orgao_alias antes e depois dos testes do pacote oltp | iguais: 215, 82, 85, 125 (cada teste roda numa transação desfeita) | AI-USAGE.md, 10/10 |
| Chave do órgão portada de Python para Go, conferida contra os aliases que a carga gravou | bateu nos 125 | AI-USAGE.md, 10/10 |
Testes do pacote oltp depois dos ajustes da revisão | 9 verdes | AI-USAGE.md, 11/10 |
PR #35 (make ingest), como foi aberto | 9 arquivos, +587 −40, 2 commits | PR #35 |
| Testes em Go na branch do PR #35 | 87 de primeiro nível; 11 deles só rodam com o banco no ar | make test-go e make test-db-go, em 11/10 |
Mesmo id em duas entradas do ZIP, com conteúdo diferente, sem a deduplicação | 1 versão nova na primeira execução, 2 na segunda | PR #35 |
| O mesmo caso, com a deduplicação | 1 gravada e 1 repetida; na segunda execução, nada | PR #35 |
| Issues da E2 abertas em 11/10 | 11 (#24 a #34); 4 com o Moura (#25, #29, #30 e #32) | GitHub |
PR #35 (make ingest), como foi mergeado | 9 arquivos, +655 −40 | PR #35 |
| Login automático no INLABS (12/10), com credencial válida, pelo nosso cliente e pelo script oficial do INLABS | 502 nos dois; pelo navegador, a mesma conta entra | AI-USAGE.md, 12/10 |
| Dias reais de DO1 baixados do INLABS e gravados | 0: o login automático não passa | — |
Download de www.in.gov.br sem cabeçalho Accept / com Accept: */* | 403 / 200 | PR #43 |
| API do dados.gov.br, fora do navegador | 401: exige chave do gov.br | PR #43 |
| Histórico nos dados abertos | ZIPs listados desde janeiro de 2002, o que cobre todo o período da planilha (2003–2020) | página da base de dados, 12/10 |
| Seção 1 de agosto de 2026 nos dados abertos | 52,6 MB, ~9 s para baixar; 8.590 matérias (8.176 DO1 e 414 DO1E) de 24 dias de publicação, 120 imagens, 0 falhas de leitura com o extract sem mudança | PR #43 |
id repetido no ZIP de agosto, entre DO1 e DO1E | 0 em 8.590 matérias | PR #43 |
make ingest-mensal MES=2026-08 num banco limpo | 96 atos de conselho gravados; 8.494 matérias de órgão desconhecido fora de ato | PR #43 |
| A mesma gravação, de novo | 0 gravadas, 96 inalteradas; ato, orgao_alias e classificacao idênticos linha a linha (96, 751 e 215 linhas, comparadas por md5) | PR #43 |
Nomes novos na fila do orgao_alias depois de um mês | 626 (de 125 para 751) | PR #43 |
Simulação de queda do consumidor CDC pós-gravação no Delta Lake (--falhar-apos-gravar, exit code 42) | Slot reteve 6 eventos pendentes no WAL; Delta Lake já atualizado com tipologia IP e total de 215 atos | make cdc-chaos, 13/10 |
Reprocessamento após queda (make cdc) | pendentes=1 atos_afetados=1 inseridas=0 atualizadas=0 inalteradas=1 total_lake=215 | make cdc-chaos, 13/10 |
Chaves duplicadas no Delta Lake pós-queda e pós-reprocessamento (HAVING count(*) > 1) | 0 duplicatas; contagem final = 215 (idêntica ao início) | make cdc-chaos, 13/10 |
O que surpreendeu
- Uma matéria repetida derrubaria o resto do ZIP. Dentro de uma transação, um
INSERTrecusado pelauq_ato_dou_versaodeixa a transação abortada, e todoSaveseguinte falha, não só o repetido. Foi a revisão do PR #23 que apontou. - Corrigir isso criou outro problema. Comparar a matéria com a última versão resolve a reexecução, mas com o mesmo
idduas vezes no mesmo ZIP cada execução passava a criar versões novas. O teste mostrou antes de qualquer dado real. - O
btrimdo Postgres, sem argumento, só remove espaços. A primeira tentativa de tratar ementa em branco no SQL continuou falhando com\ne\t; ficoustrings.TrimSpaceno Go. E o achado era mais fraco do que a revisão dizia: a extração já apara a ementa. - Gravar o DOU no OLTP contradiz o texto do ADR 0001, que diz que copiar o DOU para o Postgres "não o torna nosso OLTP". A decisão mudou e foi formalizada no ADR 0005 (#32).
- O pacote de persistência entrou sem nenhum comando que o chamasse. O Iago perguntou no PR #23 se aquilo fechava a #6; não fechava, e a pergunta virou a #24.
- Nomes que a planilha deixou como ambíguos ou indefinidos voltam para a fila como "não reconhecido" quando aparecem no DOU, com status e motivo diferentes dos que a planilha registrou.
- O INLABS recusa login de quem não é navegador. Com a credencial correta, o
logar.phpresponde502ao nosso cliente e também ao script oficial do próprio INLABS; pelo navegador, a mesma conta entra. Antes disso, a IA atribuiu o502a instabilidade do serviço, e só depois se viu que era a resposta a todo login automático. Contornar imitando um navegador foi descartado. - O mesmo XML existe sem login. Os dados abertos da Imprensa Nacional publicam um ZIP por mês com o mesmo
<article>do INLABS, DO1E incluído, e oextractleu agosto inteiro sem nenhuma mudança. O que barrava o download era só a falta do cabeçalhoAccept. - Um teste antigo dependia do banco nunca ter visto o DOU real. O
TestPersistSavesTheEditionesperava que um órgão da Polícia Federal entrasse na fila doorgao_alias, mas agosto já o tinha posto lá. Foi corrigido no PR #43. - Em 11/10 o INLABS estava em manutenção, e nada do que dependia dele pôde ser conferido nesse dia.
- O
gh pr mergefalhou sem mensagem no PR #22. O motivo só apareceu com depuração ligada: o repositório não aceita mais merge commit.
O que foi decidido
id_doué oiddo<article>, e não oidMateria: é o que a extração já exige em todo XML. Sem medição em dado real.- Matéria de órgão desconhecido não entra em
ato. O nome do órgão entra uma vez emorgao_alias, comfonte = 'DOU'estatus = 'INDEFINIDO': é a fila de decisão do ADR 0004. Chave que casa com mais de um órgão não escolhe nenhum e entra comoAMBIGUO. ato.conteudorecebe o HTML cru do<Texto>, e matéria com<Texto>vazio é recusada.- Reexecução por comparação, não por
ON CONFLICT(PR #35): a matéria é comparada com todas as versões dela em data, ementa e conteúdo. Igual a alguma, nada é gravado; diferente de todas, entra a versão seguinte e as anteriores ficam. A primeira versão do PR comparava só com a última e incluía o órgão; a revisão mostrou que isso criava versões novas a cada execução quando o mesmoidvem com dois textos, e que resolver o nome de um órgão não é republicação. - Do
idrepetido no mesmo ZIP, vale a primeira entrada (PR #35). - O registro do dia é um arquivo vazio no bronze, e não uma tabela no OLTP (PR #41, decidido pelo Luis): assim o
fetchcontinua sem falar com o banco. O custo é que o registro não é consultável por SQL. O ZIP em disco vence os marcadores. - A ingestão automática passa a ser mensal, pelos dados abertos (#42): só a Seção 1, com o nome publicado (
S01MMAAAA.zip) emdata/bronze/dados-abertos/, e mês já em disco não é pedido de novo. O mês sai cerca de duas semanas depois de acabar; para o dia corrente, a fonte continua sendo o INLABS, baixado à mão. - Um ZIP por execução, uma transação por ZIP: a edição entra inteira ou não entra.
- O
extractlê um ZIP por execução, uma pasta dentro do ZIP é logada como ignorada, e oparseficou privado (revisão do Iago). Centralizar o logger ficou para quando ele tiver configuração de verdade. - Divisão da E2: o Moura fica com a tabela Delta, o CDC e o ADR 0005 (#25, #29, #30 e #32); o Luis com a ingestão (#24 e #27).
- Semântica de entrega e tolerância a falhas do CDC (#30, decidido pelo Moura): protocolo de confirmação tardia (peek no slot lógico -> escrita atômica e idempotente por MERGE na chave
ato_idcom base em checksum no Delta Lake -> avanço do cursor LSN com get_changes). Uma queda forçada no intervalo pós-gravação e pré-confirmação (--falhar-apos-gravar, exit code 42) prova a semântica na prática: o slot retém o WAL, a reexecução relê o mesmo evento (at-least-once) e o Delta absorve a escrita sem duplicatas (effectively-once), mantendo a contagem rigorosamente idêntica (demonstrado emmake cdc-chaose nomake test).
O que ficou em aberto até 13/10
- Dias reais do INLABS: o critério de "três dias de DO1, duas vezes" que vem da #6 foi cumprido com um mês inteiro dos dados abertos (24 dias de publicação), mas não com o INLABS, cujo login automático é recusado.
- O valor de N da janela de reprocessamento (#31). Os PRs #39 e #40 apontam para branches que já foram mergeadas e precisam ser reapontados para o
main. - O ADR 0005 (#32) foi concluído, formalizando a justificativa de o DOU entrar no OLTP, a fonte de dados abertos mensais contra o INLABS e a comparação de 3 alternativas (Opção Nula, CDC e Debezium+Kafka) com medições de containers, RAM e latência.
- A tabela Delta, o CDC e a semântica de entrega (#25, #29 e #30) foram concluídos e validados em 13/10 (PRs #48 e #49 e issue #30), com testes automatizados no
make teste demonstração de caos viamake cdc-chaos. - A fila do
orgao_alias: um mês põe ~600 nomes na fila, e ninguém ainda decidiu quem a esvazia nem com que ritmo. - Validar a classificação contra a planilha: com o histórico dos dados abertos desde 2002, os 215 atos rotulados (2003–2020) passam a estar ao alcance da ingestão, e não só os 4 do período do INLABS.
Nota sobre uso de IA
A persistência (PR #23), o make ingest (PR #35) e a aplicação da revisão do PR #22 foram feitos pelo Luis com auxílio de Claude Code; a revisão do PR #23 e os ajustes dela, pela Luiza, também com Claude Code. Cada uso está no AI-USAGE.md (entradas de 08/10 a 11/10). Este diário foi redigido com Claude Code em 11/10, a partir dessas entradas, dos PRs #22, #23 e #35 e das issues #24 a #34; os números da tabela foram conferidos na API do GitHub, no texto dos PRs e, no caso da contagem de testes, rodando-os. A lista de quem trabalhou saiu dos autores dos PRs, das revisões e das issues, e não de uma ata de reunião. Em 12/10, a Luiza completou o diário com Claude Code, a partir dos PRs #35, #38, #41 e #43, da issue #42 e das entradas do AI-USAGE.md de 11 e 12/10; as datas vieram da API do GitHub e os números de agosto, das execuções registradas no PR #43. O que acontecer em 13/10 ainda precisa ser acrescentado.