Releases: felipelmc/mapa-da-ciencia
Release list
mapa-da-ciencia 2.0.0
A versão 2.0.0 traz duas frentes novas e o resultado de uma revisão geral do projeto.
Júri de modelos locais e supervisor
Vários modelos locais classificam a amostra de validação, os que discordam deliberam uma vez vendo as respostas anônimas dos outros, e o que continua sem maioria vai a um supervisor, que escolhe entre os candidatos (por arquivos, sem rede, ou pela API da Anthropic, opcional, com consentimento e limite de gasto). Uma auditoria confere uma amostra das decisões unânimes. A validação marca como circulares as comparações entre codificadores da mesma família de modelo, e o número principal não passa pelo supervisor.
No piloto, a tecnica_principal sai de kappa 0,37 (um modelo) para 0,61 (júri de três; McNemar p < 0,001). O gemma4:12b sozinho chega a 0,65: o júri vale sobretudo quando não se sabe de antemão qual modelo é o melhor. Veja o ADR 0015.
Redes de coautoria, de instituições, de estados e de citação
mapa redes e a vista Redes do painel e da demo: pessoas identificadas por id do OpenAlex e ORCID conferido pelo nome, com revisão manual dos homônimos; pesos fracionários, comunidades rotuladas pelos tópicos (sem nomes de pessoas), o recorte comum que esmaece sem mover o desenho; citações dentro do corpus, o fluxo entre macrotemas e o cânone das obras mais citadas de fora dele. O site não publica ORCIDs.
No piloto, os artigos com mais de um autor passaram de 29% (2010–2014) para 57% (2021–2025). Veja o ADR 0014.
Revisão geral
Sete revisores independentes, um por dimensão (backend, frontend, metodologia, segurança e privacidade, documentação, dados do piloto, experiência de uso), com evidência reproduzível e verificação adversarial de cada achado: 79 achados confirmados e corrigidos com testes, ou registrados como recomendação. Veja a página Revisão geral.
A lista completa está no CHANGELOG. O contrato de dados vai para a versão 1.5 (só acréscimos).
A demo do piloto (piloto-publicado.zip) foi regerada com a 2.0.0: redes, júri na validação, rótulos de tópicos e siglas de instituições corrigidos.
v1.0.1: primeira versão com DOI
A versão 1.0.1 é a primeira com DOI: o repositório passa a ser arquivado no Zenodo a cada release. E o pacote fica pronto para o PyPI.
Adicionado
- arquivamento no Zenodo: cada release ganha um DOI, com o ORCID e a afiliação do autor no
.zenodo.jsone noCITATION.cff(a licença usa o identificador do vocabulário do Zenodo,mit).
Mudado
- o pacote fica pronto para o PyPI: endereços do site, da documentação, da demo e das mudanças nos metadados, classificadores de uma versão estável, imagens e links do README com endereço completo (o PyPI não resolve caminhos relativos) e um sdist só com o código do pacote (antes levava os spikes e o frontend); o CI e o workflow Release conferem os metadados com
twine check.
A demo do piloto (piloto-publicado.zip) é a mesma da 1.0.0.
1.0.0: Céu que se forma
A versão 1.0.0 fecha o plano do projeto. A abertura do site, "Céu que se forma", mostra os 4.275 artigos do piloto acendendo ano a ano e se juntando nas constelações dos seus assuntos, com as histórias que os dados contam: a polarização em alta, as redes sociais depois de 2018, SP, RJ e DF com 61% da produção brasileira, as revistas de relações internacionais só em inglês desde 2016, os ensaios teóricos caindo de 49% para 26% dos artigos. E a exportação passa a funcionar em pastas sincronizadas pelo iCloud Drive.
Corrigido
- o
mapa publicar --destinosó escreve numa pasta vazia, numa que ainda não existe ou num site publicado antes (marcado com.mapa-site), e nunca na pasta do projeto ou numa que a contenha: como a publicação troca todo o conteúdo do destino,--destino .apagava o projeto; - a exportação (
saida/dados) e omapa publicartrocam o conteúdo da pasta arquivo por arquivo, e não a pasta inteira: numa pasta sincronizada pelo iCloud Drive (a Mesa ou os Documentos do macOS), trocar a pasta de nome fazia o serviço guardar a nova como "dados 2" e deixava o projeto semsaida/dados(pastas.substituir_conteudo; guia de problemas);
Adicionado
- Abertura do site, "Céu que se forma": a página inicial da documentação vira uma abertura própria (
overrides/home.html). Os 4.275 artigos do piloto acendem como estrelas, ano a ano, e se juntam nas constelações dos macrotemas (a árvore geradora mínima entre os tópicos de cada um), com os rótulos levando à demo; os números do piloto, seis histórias com mini-gráficos tirados dos dados (o tópico em alta, o mais recente, a concentração em SP, RJ e DF, o inglês nas revistas de RI, a abordagem das pesquisas e o kappa por variável), os seis passos do método e uma busca nos tópicos. Em português e inglês, nos temas Observatório e Prancha, com movimento reduzido e no celular. Os dados vêm descripts/gerar_pagina.py; os testes, do Playwright sobre o site montado (no CI) e do pytest. A página inicial antiga vira "Documentação";
0.7.0: publicação, figuras e oficina
A publicação, as figuras e a oficina: o projeto vira um site estático, com os resumos só de licença Creative Commons e nenhum e-mail; cada gráfico do painel sai em SVG, PNG ou CSV no tamanho de um artigo ou de um slide; e um caderno do Colab monta um mapa do zero numa GPU gratuita. O piloto inteiro está publicado na demo: os 4.247 resumos classificados pelo qwen3.5:9b num notebook, em cerca de 10 horas (9,6 s por resumo), com 100% de JSON válido na primeira tentativa e 93,4% das evidências copiadas literalmente do resumo.
Adicionado
- Marco M7 (publicação, figuras e oficina):
- Exportar figuras (
lib/exportar/): cada gráfico do painel baixa em SVG (com título, recorte, fonte, n e data, as cores do tema resolvidas e as fontes embutidas), PNG (rasterizado na resolução do tamanho) ou CSV (os dados da tabela); tamanhos Artigo (85 ou 174 mm, 300 ou 600 dpi, tema Prancha), Slide (1.920 px) e Telão (3.840 px, Observatório); guia "Exportar figuras"; - modo apresentação (tecla ++p++, em todas as vistas menos a codificação): esconde o trilho e as barras e aumenta a letra, para projetar; ++esc++ sai; atalho na Ajuda;
mapa publicar [--destino] [--sem-resumos]eapi.publicar(): o site estático do projeto, com a interface e o contrato,api: false, resumos (e o texto das evidências) só com licença Creative Commons, sem e-mails (varredura final), montado numa pasta nova e trocado de uma vez; contrato 1.4 (Manifesto.publicacao); guia "Publicar o site";- Metodologia no site publicado: sem API, a seção Projeto vira a página Metodologia, tirada do manifesto (fontes, recorte, contagens, modelos com o digest, hash do codebook, sementes, durações, licenças e o que a publicação retirou), com os links para as explicações;
- o GitHub Pages do projeto publica a documentação em
/e, a partir do assetpiloto-publicado.zipda última release, a demo do piloto em/demo/(sem o asset, sai só a documentação, com um aviso); - oficina no Colab: o caderno
notebooks/oficina_colab.ipynb(GPU T4, Ollama com o perfil padrão, Opinião Pública de 2020 a 2024, tópicos, geografia, uma amostra de 30 classificada e o painel), gerado porscripts/gerar_notebook.pypara instalar sempre o wheel da release da versão, com os comandos rodados no CI;api.painel()abre o painel de dentro de um notebook, com o servidor numa thread, e no Colab pelo proxy do Google (só nesse modo a API aceita pedidos de outro endereço); - explicações "Metodologia em uma página" (o método inteiro com os parâmetros e os números do piloto, um rascunho da seção de métodos, e como citar) e "Limitações e vieses" (corpus, resumos, tópicos, geografia, classificação e reprodutibilidade); o guia de instalação ensina a instalar pelo wheel da release, com a interface já compilada;
- README bilíngue (português e inglês), com o GIF do painel do piloto (
frontend/scripts/gif-readme.ts), a demo, a oficina no Colab e a instalação pelo wheel da release;.zenodo.jsone oCITATION.cffcompletos para o DOI; o workflow Release constrói o wheel com a interface, testa-o sem Node, anexa-o à release, atualiza a demo e, depois de configurado, publica no PyPI por trusted publishing; o passo a passo de uma release no guia de desenvolvimento; - o teste do tutorial por uma pessoa de fora (um subagente, num clone limpo, sem ajuda) virou correções: "Explorar o exemplo" com dois caminhos de instalação (o wheel da release ou o código, com a interface compilada como passo, não como dica, e o Node.js 22.18), a página "interface não compilada" diz para reabrir o painel, os tutoriais explicam
uv runantes das dicas da CLI, o.enva partir do.env.exemplo, tempos e memória iguais entre os tutoriais, textos de marcos antigos removidos, os comandos sem o marcador# fora do CI(a lista do que o teste pula fica no teste), o caderno do Colab instala ozstde volta para/content, e o glossário ganha ARI, codificador de referência, release, trilho e wheel; contrato/exemplo-publicado/: o exemplo sintético passado pelas regras domapa publicar, gerado e conferido peloscripts/gerar_contrato.py; os testes e2e ganham o site publicado (sem API, a Metodologia com a publicação, o cartão de um artigo sem licença aberta com os valores da classificação e sem os trechos);
- Exportar figuras (
0.6.0: painel completo
O painel completo: quem não usa o terminal cria e configura o projeto e roda o pipeline pela interface, com o progresso ao vivo. As etapas rodam no servidor local, uma por vez, e o acompanhamento sobrevive a um reload ou a uma queda de conexão. Pela interface, o projeto do tutorial (396 artigos da Opinião Pública) teve a coleta refeita do cache, 13 tópicos em 5 minutos, 94,4% dos vínculos de autoria ligados a uma instituição e uma amostra de 20 resumos classificada.
Adicionado
- Marco M6 (painel completo):
- jobs do painel (
servidor/jobs.py): as etapas rodam em segundo plano, uma por vez, guardadas noestado.sqlitecom o progresso como eventos numerados;POST /api/etapas/{etapa}(coleta, tópicos, geografia, classificação, com as opções validadas),GET /api/jobs,GET /api/jobs/{id},DELETE /api/jobs/{id}(cancela na próxima atualização de progresso) eGET /api/jobs/{id}/eventos, em Server-Sent Events com retomada peloLast-Event-ID; um job que ficou rodando numa sessão anterior aparece como interrompido; as rotas de escrita conferemHosteOrigin(servidor/origem.py); - rotas do projeto no painel (
servidor/rotas_projeto.py):GET /api/projeto/etapas(cada etapa pendente, em dia ou desatualizada, com a última execução),GET /api/modelos(memória, perfis, modelos instalados e os do projeto),POST /api/modelos/baixar(ollama pullcomo job, com o progresso por camada;Ollama.baixar),GET /api/estimativa/classificacao,GET/PATCH /api/configuracaoeGET/PUT /api/codebook, gravados sem perder os comentários do YAML (edicao.py, comruamel.yaml), validados antes de ir para o disco e recusados enquanto uma etapa roda; - a
FonteApido painel fala com a API: estado das etapas, rodar e cancelar uma etapa, acompanhá-la ao vivo (EventSource, que reconecta sozinho pedindo só o que perdeu; o estado ignora eventos repetidos), modelos, download, estimativa, configuração e codebook; - a vista Projeto no painel local: as etapas numa linha de metrô (pendente, em dia, incompleta, desatualizada ou rodando, com a última execução; a linha deita ou fica de pé conforme o espaço da vista), rodar cada uma (com piloto de 20 documentos, estimativa ou só a amostra, onde cabe), o job ao vivo com cancelar, que retoma o acompanhamento depois de um reload, a estimativa da classificação, os modelos do projeto com o download do que falta e as últimas execuções; e2e contra uma API falsa cuja primeira conexão SSE cai de propósito;
- o assistente do projeto no painel, em 5 passos (fontes com a busca nas revistas do SciELO, recorte, modelos com o perfil sugerido pela memória e o que falta baixar, codebook num formulário e revisão com o que muda e o que isso refaz); salvar grava o
mapa.yamle ocodebook.yamlsem perder os comentários, e "Salvar e rodar um piloto" coleta 20 documentos;GET /api/revistas; - documentação do painel: referência da API HTTP gerada do OpenAPI (
docs/referencia/api-http.md, conferida no CI com as outras referências), tutorial "Seu primeiro mapa pela interface", guia do painel (rodar as etapas e configurar o projeto) e ADR 0013 (jobs, progresso por SSE e edição do projeto); - sortear a amostra de validação pelo painel:
POST /api/validacao/amostrae, na estação Validação da linha de metrô, o tamanho e o botão "Sortear a amostra";
- jobs do painel (
0.5.0: classificação por codebook e validação
A classificação por codebook e a validação: um modelo local lê o resumo de cada artigo e responde às perguntas do codebook, com o trecho do resumo que justifica cada resposta, e a concordância com uma leitura cuidadosa de uma amostra é medida por variável. Na amostra de 200 artigos do piloto, o qwen3.5:9b deu JSON válido em 100% das respostas, copiou literalmente 94,8% das evidências, levou 10,8 s por resumo, e o kappa contra um codificador de referência (Claude, às cegas) vai de 0,37 na técnica a 0,93 em "Brasil como caso".
Adicionado
- Marco M5 (classificação por codebook e validação):
- o codebook vira o JSON Schema da resposta do modelo, com a evidência (até 200 caracteres) antes do valor em cada variável, e as respostas são validadas contra ele; a mensagem de sistema é fixa (o Ollama reaproveita o prefixo) e traz as regras da evidência curta;
- conferência da evidência:
literal(a menos de maiúsculas, espaços, aspas e travessões),aproximada(90% dos caracteres casando em blocos com um pedaço do texto de tamanho parecido, ou cada pedaço de um trecho cortado com reticências presente no texto),ausenteoudispensada(vazia numa resposta "sem informação"), com os offsets do trecho no resumo exibido; - executor da classificação retomável: cada resposta válida vai para o cache do
estado.sqlite(chave com o texto, a assinatura do que o modelo lê, o modelo com o digest, a versão do prompt e os parâmetros; mudar só a versão ou os rótulos das categorias reaproveita as respostas), uma nova tentativa quando a resposta foge do codebook ou a evidência não está no texto, guarda de memória entre documentos, concorrência configurável e o modelo descarregado no fim; mapa classificar [--estimar] [--limite N] [--modelo X]eapi.classificar(): a etapa gravadados/classificacao/(um resultado por modelo e codebook, para comparar modelos), registra o manifesto com o hash do codebook e aparece nomapa status, com aviso quando está incompleta ou é de outro codebook; a viewclassificacoesemconectar(); o resultado é regravado a cada 50 documentos novos e numa interrupção, para a rodada longa aparecer enquanto corre; ADR 0011 (proposta);- amostra de validação (
mapa validar amostra [--n N] [--refazer],api.amostra_de_validacao()): sorteada uma vez entre os documentos com resumo, estratificada por tópico (ou ano, ou revista) com alocação proporcional e ao menos um por estrato, guardada noestado.sqlitee exportada emvalidacao/amostra.jsonlsó com id, título, resumo e idioma; a fila da classificação começa pela amostra, emapa classificar --somente-amostraclassifica só ela; - codificações (
mapa validar importar ARQUIVO --codificador NOME [--tipo humano|referencia],api.importar_codificacoes(),api.codificacoes()): JSONL validado contra o codebook, com evidência, incerteza e nota por variável; guias "Classificar os resumos" e "Codificar a amostra"; - na saída de
mapa validar amostra, os estratos com o rótulo do tópico; na demapa classificar, as categorias com o rótulo do codebook; - métricas de concordância (
mapa validar metricas,api.validacao()), por variável e por par de participantes (codificador × modelo, codificador × codificador, modelo × modelo): concordância, kappa de Cohen (igual ao do scikit-learn) com IC 95% por bootstrap, PABAK, alfa de Krippendorff nominal (conferido com o exemplo publicado), matriz de confusão e precisão, revocação e F1 por classe; McNemar exato entre modelos contra a mesma referência; divergências com o modelo principal; múltipla escolha medida por categoria; guia "Ler kappa e PABAK"; - relatório da validação (
mapa validar relatorio,api.relatorio_de_validacao()) emvalidacao/: Markdown com participantes, concordância, P/R/F1 e matrizes por classe, McNemar, evidência literal e as divergências com a evidência do modelo; tabelas LaTeX (booktabs, vírgula decimal);metricas.json. O.gitignorede um projeto novo deixavalidacao/(os resumos da amostra e as respostas de cada pessoa) fora do git; ADR 0012 (proposta); - tutorial "Seu primeiro mapa, parte 4: classificação e validação" (com os comandos rodados no CI) e ADRs 0011 e 0012 aceitos, com a evidência do piloto: 100% de JSON válido na primeira tentativa, 94,8% de evidência literal, 10,8 s por resumo, retomada depois de
kill -9sem refazer nada, e o kappaclaude-opus×qwen3.5:9bpor variável (de 0,37 na técnica a 0,93 em "Brasil como caso"); - contrato de dados 1.3 (só acréscimos):
codebook.jsonsempre;classificacoes.jsoncom cobertura, classificação parcial, JSON válido e evidência por variável; colunasclsemdocumentos.json(múltipla escolha como combinações) e as evidências nos detalhes, com o campo onde o trecho está e o statusdispensada;validacao.jsoncom os participantes e o tipo de cada um, P/R/F1 por classe, McNemar entre modelos e as divergências só de codificadores de referência (as de pessoas ficam fora do contrato);hash_codebook, classificados e validados no manifesto; a importação de codificações e a rodada da classificação atualizam o painel; - a vista Classificação do painel, no filtro cruzado: uma variável do codebook por vez, com o selo de kappa da validação (hachura abaixo de 0,6; borda tracejada contra um codificador de referência), barras 100% por ano e o cruzamento com macrotemas, tópicos ou revistas; uma célula lista os documentos com a evidência marcada no resumo; a variável e o cruzamento vão na URL (
variavel=,cruzar=); guia "Ler a classificação"; - rótulos com acento nas categorias do codebook de exemplo (o
rotulo, só de exibição); - a vista Codificar (Validação › Codificar a amostra, só no painel local): uma ficha por vez, cega, com o título, o resumo e o codebook; tudo pelo teclado (
1–9,Tab,Enter,←/→,Sincerto,Nnota,Eevidência do trecho selecionado,Ddefinições,?ajuda); gravação automática com fila de pendências no navegador, retomada na primeira ficha incompleta; e2e com 20 fichas pelo teclado que sobrevivem a um reload, contra uma API falsa que espelha a do Python; - o cartão do documento no Mapa marca no resumo as evidências da classificação e lista as respostas do modelo; passar o mouse (ou clicar) numa resposta acende só o trecho dela;
- a vista Validação › Concordância: os participantes com o tipo (aviso quando há codificador de referência), o par escolhido com concordância, kappa (barra com hachura abaixo de 0,6) e IC 95%, PABAK e alfa por variável; a variável escolhida com a matriz de confusão, P/R/F1 por categoria e as divergências com a evidência do modelo; McNemar entre modelos e evidência literal. No painel local, as métricas vêm da API, calculadas na hora;
- API local da codificação no painel:
GET /api/validacao/fila(a amostra embaralhada por codificador, cega, com o codebook e as respostas já dadas),PUT /api/validacao/codificacoes/{doc}(gravação parcial ou completa; a escrita confere também oOrigin) eGET /api/validacao/metricas(concordância na hora, com as divergências de todos os codificadores); toda a API do painel responde só a umHostlocal;