Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 2.5.0 · 2026-07-25 21:27 UTC

okfn-brasil / querido-diario-data-processing

Text processing repository to free brazilian municipal gazettes from closed file formats for the Querido Diário project.

PythonMIT★ 29 estrellas⑂ 21 forksdesde oct 2020Ver en GitHub ↗

okfn-brasil/querido-diario-data-processing tiene un índice de salud de 69 sobre 100, lo que lo sitúa en la banda Bueno. Su puntuación más alta es Engineering Quality (90/100) y la más baja, Security (41/100). Se actualizó por última vez hace 6 días. 2 personas concentran la mayor parte del trabajo reciente.

69
global / 100
Bueno

Índice de salud del software

Las métricas se agrupan en categorías ponderadas sobre una escala estandarizada de 1 a 100. El resultado global parte de su media ponderada, calibrada contra la distribución del registro público para que las bandas tengan significado percentil; cuando la evidencia pública activa la Política de Jurisdicciones de Alto Riesgo, la calificación se ajusta y recibe un límite «En riesgo» de 34.

69
Excepcional93-100El nivel más alto del registro (≈ el 5% superior); cumple prácticamente todos los criterios evaluados
Excelente80-92Sólido en todos los frentes; carencias menores
Bueno65-79Saludable; carencias limitadas y manejables
Moderado50-64Aceptable con carencias notables; se recomienda revisión
Débil35-49Debilidades sustanciales en varias áreas
En riesgo20-34Debilidades significativas; su adopción exige cautela
Crítico1-19Problemas graves (proyecto abandonado, un solo mantenedor, sin higiene)
VitalidadComunidad yAdopciónSostenibilidady GobernanzaCalidad deIngenieríaSeguridadPreparaciónpara IA

Perfil de puntuación

Cada eje es una categoría. La forma importa más que la media: un proyecto sano llena toda la figura, mientras que un perfil de picos y cráteres indica que la fortaleza en una dimensión enmascara el riesgo en otra.

El resultado global ponderado 62 se calibra a 69 en la escala publicada del índice (calibración del registro 2026-08-02).

Titularidad

546 seguidores119 repositorios públicosdesde abr 2012

Este repositorio está respaldado por una organización: una custodia compartida y responsable que puede sobrevivir a cualquier mantenedor individual.

Métricas por categoría

Vitalidad

¿Está vivo el proyecto: se escribe código y se publican versiones?

56Moderado · 21% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 6 días
7.6/36Cadencia de commits — 11/52 semanas con commits
18/18Volumen de commits — 135 commits en el último año
0/10OpenSSF Scorecard: Maintained — 1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Datos de entrada utilizados
commits_last_year135
human_commit_share1
days_since_last_push6
active_weeks_last_year11
Cómo se puntúa
16.2/27Publica versiones — 20 etiquetas de versión (sin releases de GitHub)
7.2/36Recencia de las versiones — última versión hace 642 días
19.8/27Cadencia de publicación — una versión cada ~47 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count20
latest_release_tagv0.13.3
releases_from_tags
days_since_latest_release642
mean_days_between_releases47
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Signed-Releases. Los pesos restantes se han renormalizado.

Comunidad y Adopción

¿Tiene el proyecto usuarios, descargas, atención y unas condiciones acogedoras para quienes contribuyen?

61Moderado · 17% del índice global
Cómo se puntúa
23.5/60Estrellas — 29 estrellas
10.8/25Forks — 21 forks
5.3/15Observadores — 10 observadores
Datos de entrada utilizados
forks21
stars29
watchers10
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (MIT)
18/18Guía CONTRIBUTING
13.5/13.5Código de conducta
0/7.2Plantilla de issues
0/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
readme_badges
has_contributing
has_issue_templateno
has_code_of_conduct
readme_badge_services
has_pull_request_templateno

Sostenibilidad y Gobernanza

¿Sobrevivirá el proyecto a sus personas: factor bus, capacidad de respuesta, quién lo respalda y mantenimiento del paquete?

59Moderado · 23% del índice global
Cómo se puntúa
25.2/54Factor bus — la mitad de los commits recae en 2 contribuyente(s)
11.8/22.5Distribución de commits — el principal contribuyente firma el 47% de los commits
13.5/13.5Amplitud de contribuyentes — 12 contribuyentes
10/10OpenSSF Scorecard: Contributors — project has 17 contributing companies or organizations
Datos de entrada utilizados
bus_factor2
contributors_sampled12
top_contributor_share0,474
Cómo se puntúa
9.5/42Resolución de issues — 23% de issues cerradas
27.7/30Aceptación de PR — 49/53 PR decididos fusionados
0/13Newcomer PR acceptance — ningún PR de un contribuyente primerizo decidido en 30 d
0/15OpenSSF Scorecard: Code-Review — Found 0/9 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs49
open_issues48
closed_issues14
prs_merged_7d
prs_decided_7d
prs_merged_30d
prs_decided_30d
issue_closed_ratio0,226
closed_unmerged_prs4
first_time_authors_30d
first_time_prs_merged_30d
first_time_prs_decided_30d
Excluidos de la puntuación (sin datos o no aplicable): newcomer_pr_acceptance. Los pesos restantes se han renormalizado.
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
19.7/25Alcance del propietario — 546 seguidores de okfn-brasil
25/25Trayectoria — 119 repos públicos, cuenta de ~14 años
Datos de entrada utilizados
followers546
owner_typeOrganization
is_verified
owner_loginokfn-brasil
public_repos119
account_age_days5208

Calidad de Ingeniería

¿Existen unas prácticas mínimas de ingeniería y documentación?

90Excelente · 19% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 4 flujo(s) de trabajo
24/24Pruebas presentes
16/16Configuración de linter
9.6/9.6Hooks de pre-commit
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 5 out of 5 merged PRs checked by a CI test -- score normalized to 10
Datos de entrada utilizados
has_ci
has_tests
has_editorconfigno
has_linter_config
has_precommit_config

Documentación

85Excelente
Cómo se puntúa
30/30README
25/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
10/10Descripción del repositorio
10/10Topics — 6 topics
10/10Wiki
Datos de entrada utilizados
topicspython, sql, data-processing, pipelines, hacktoberfest, opensearch
has_wiki
homepage
has_readme
has_docs_dir
has_description

Seguridad

¿Son sólidas las prácticas visibles de seguridad y de cadena de suministro, sin exposición jurisdiccional de alto riesgo sin resolver?

41Débil · 16% del índice global
Cómo se puntúa
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.5/2.5CI-Tests — 5 out of 5 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/9 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 17 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Licencia — license file detected
0/7.5Maintained — 1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
5/5Packaging — packaging workflow detected
2.5/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 5
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — sin datos
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate4,1
Excluidos de la puntuación (sin datos o no aplicable): signed_releases. Los pesos restantes se han renormalizado.

Preparación para IA

¿Hasta qué punto está el repositorio preparado para desarrollarse y mantenerse con agentes de codificación de IA? Tiene un peso deliberadamente pequeño (4%): las herramientas para agentes son una señal real de mantenimiento, pero un repositorio sin ninguna puede alcanzar igualmente 100/100.

60Moderado · 4% del índice global
Cómo se puntúa
0/45Instrucciones para agentes — sin CLAUDE.md / AGENTS.md / reglas de editor
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 90 de 100 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,9
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
18/18Arranque con un solo comando — Makefile
22/22Pruebas automatizadas
11/11Configuración de lint / formato
0/11Verificación estática de tipos
10/10Entorno reproducible — Dockerfile
10/10Práctica demostrada con agentes — 24 de los últimos 100 commits con autoría o crédito de agente
0/8Mantenimiento automatizado — no se observan actualizaciones automáticas de dependencias
5/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 5
Datos de entrada utilizados
has_nixno
has_tests
lockfiles
has_dockerfile
typed_languageno
bootstrap_filesMakefile
has_devcontainerno
has_linter_config
typecheck_configs
agent_commit_share0,24
toolchain_manifests
dependency_bot_commit_share0
Cómo se puntúa
0/45Código verificable por tipos — Python sin configuración de verificación de tipos
55/55Tamaños de archivo manejables — 0/53 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languagePython
largest_source_bytes16.063
source_files_sampled53
oversized_source_files0

Datos clave

29estrellas de GitHub
12contribuidores
135commits en los últimos 12 meses
6días desde el último push
20versiones publicadas
2factor bus
48issues abiertas
PyPIecosistemas de paquetes

Advertencias de recopilación de datos

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Más detalle

Historial de estrellas y forks 0 ★ / 21 ⇿
0Estrellas
21Forks
20Versiones

Cuándo se añadió cada estrella y fork, recopilado de GitHub y agrupado por día. El crecimiento acumulado se sitúa justo encima de las adiciones diarias que lo componen, de modo que ambos se leen en conjunto: la acumulación orgánica sostenida no se parece en nada a un pico abrupto y efímero. Cuando esa diferencia es medible, se informa como autenticidad del crecimiento.

048121620242122020-102023-082026-07
Mayor 0Menor 5Parche 15

Cada punto abarca 6 días.

OpenSSF Scorecard 4.1 / 10
4.1agregado

Evaluación de seguridad independiente y agnóstica en cuanto a herramientas, procedente del proyecto de código abierto OpenSSF Scorecard. Cada comprobación premia una práctica de seguridad, no la herramienta de un proveedor concreto. Las comprobaciones que Scorecard no pudo determinar se marcan como n/d y se excluyen de la puntuación de seguridad (nunca se cuentan como cero).Scorecard v5.5.0 · 2026-07-25 21:27 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests5 out of 5 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/9 approved changesets -- score normalized to 0
10Contributorsproject has 17 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintained1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
10Packagingpackaging workflow detected
5Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 5
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
Todas las dependencias no recopilado

No fue posible recopilar el conjunto de dependencias resuelto para este informe: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [
        "python",
        "sql",
        "data-processing",
        "pipelines",
        "hacktoberfest",
        "opensearch"
      ],
      "is_fork": false,
      "size_kb": 17863,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Shell": 16523,
        "Python": 200702,
        "Makefile": 13027,
        "Dockerfile": 816
      },
      "pushed_at": "2026-07-19T03:07:37Z",
      "created_at": "2020-10-01T10:54:22Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-19T03:07:41Z",
      "description": "Text processing repository to free brazilian municipal gazettes from closed file formats for the Querido Diário project.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": "http://ok.org.br",
      "name": "Open Knowledge Brasil - Rede pelo Conhecimento Livre",
      "type": "Organization",
      "login": "okfn-brasil",
      "company": null,
      "location": "Brasil",
      "followers": 546,
      "avatar_url": "https://avatars.githubusercontent.com/u/1666382?v=4",
      "created_at": "2012-04-21T18:48:59Z",
      "is_verified": null,
      "public_repos": 119,
      "account_age_days": 5208
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.13.3",
          "kind": "patch",
          "published_at": "2024-10-20T22:04:41Z"
        },
        {
          "tag": "v0.13.2",
          "kind": "patch",
          "published_at": "2024-09-14T14:09:23Z"
        },
        {
          "tag": "v0.13.1",
          "kind": "patch",
          "published_at": "2024-08-24T12:03:35Z"
        },
        {
          "tag": "v0.13.0",
          "kind": "minor",
          "published_at": "2024-08-23T14:41:15Z"
        },
        {
          "tag": "v0.12.1",
          "kind": "patch",
          "published_at": "2024-08-16T21:46:44Z"
        },
        {
          "tag": "v0.12.0",
          "kind": "minor",
          "published_at": "2024-08-16T13:26:27Z"
        },
        {
          "tag": "v0.11.1",
          "kind": "patch",
          "published_at": "2023-12-14T21:33:19Z"
        },
        {
          "tag": "v0.11.0",
          "kind": "minor",
          "published_at": "2023-12-13T20:41:07Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2023-11-30T15:40:43Z"
        },
        {
          "tag": "v0.9.10",
          "kind": "patch",
          "published_at": "2023-08-24T12:10:28Z"
        },
        {
          "tag": "v0.9.9",
          "kind": "patch",
          "published_at": "2023-08-24T11:04:34Z"
        },
        {
          "tag": "v0.9.8",
          "kind": "patch",
          "published_at": "2023-07-31T22:27:48Z"
        },
        {
          "tag": "v0.9.7",
          "kind": "patch",
          "published_at": "2023-05-18T13:58:19Z"
        },
        {
          "tag": "v0.9.6",
          "kind": "patch",
          "published_at": "2023-03-16T01:19:25Z"
        },
        {
          "tag": "v0.9.5",
          "kind": "patch",
          "published_at": "2022-11-29T13:52:18Z"
        },
        {
          "tag": "v0.9.4",
          "kind": "patch",
          "published_at": "2022-07-27T13:12:55Z"
        },
        {
          "tag": "v0.9.3",
          "kind": "patch",
          "published_at": "2022-05-22T04:21:34Z"
        },
        {
          "tag": "v0.9.2",
          "kind": "patch",
          "published_at": "2021-10-18T01:03:48Z"
        },
        {
          "tag": "v0.9.1",
          "kind": "patch",
          "published_at": "2021-07-08T11:57:01Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2021-07-03T21:18:12Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "c3069787ef4c5c3b5a7469d2d531f3f871b4aa7a",
          "body": "setup_memory_controls() tinha soft/hard RLIMIT_AS hardcoded em\n1.5GB/1.9GB, sincronizado manualmente com um limits.memory de 2048Mi\nque já não é mais o valor real (deployment subiu pra 6Gi por causa do\nimport de sentence-transformers/transformers/torch, que sozinho já\npassa de 2GB antes de qualquer \n[…]\n, refletindo resources.limits.memory) e\ncalcula hard=90%/soft=75% desse valor. Fallback de 2GB quando a env\nvar não está setada (ex: rodando fora do k8s), mantendo o\ncomportamento anterior nesse caso.",
          "is_bot": false,
          "headline": "fix: RLIMIT_AS dinâmico via MEMORY_LIMIT_BYTES em vez de hardcoded",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-07-18T23:21:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "db9a515559a1b138f3039740b5355df7593b0fa2",
          "body": "Permite reprocessar excertos temáticos que não possuem excerpt_embedding_score\nsem precisar reprocessar todos os diários desde o início.\n\nUso: python main -p embedding_rerank\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: adiciona pipeline embedding_rerank para re-execução ad-hoc do BERT",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-14T04:26:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6376c1f01db3e542cf4387f12d6d4c06146fe0b5",
          "body": "## Summary\n\n- Altera o `ORDER BY gazettes.id` de `ASC` para `DESC` nos três modos de\nexecução (`DAILY`, `ALL`, `UNPROCESSED`)\n- Garante que os diários inseridos mais recentemente no banco sejam\nprocessados primeiro\n- A paginação por `LIMIT/OFFSET` continua funcionando normalmente com a\nnova ordenaçã\n[…]\n `DAILY` mantém comportamento correto de\npaginação\n- [ ] Verificar que o modo `ALL` percorre todos os registros sem\nduplicatas ou saltos\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)",
          "is_bot": false,
          "headline": "fix: processa diários em ordem decrescente de inserção no banco (#125)",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-14T03:45:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4b7f3bbafe9be78fb34985e345cef778fe1098b0",
          "body": "Altera o ORDER BY de ASC para DESC nos três modos de execução (DAILY,\nALL, UNPROCESSED), garantindo que os diários mais recentes sejam\nprocessados primeiro.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: processa diários em ordem decrescente de inserção no banco",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-14T03:43:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "95c34c21f3184330fee6cf056627e0f0cd6c3ac6",
          "body": null,
          "is_bot": false,
          "headline": "fix: atualiza como disparar o build da imagem principal",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T03:55:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8143f82a070f44a593fa80a20389c75a64467956",
          "body": null,
          "is_bot": false,
          "headline": "fix: Corrige nome da imagem do apache tika",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T03:49:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "24741a4e271f39af6da7c63c13bbba0bc382e614",
          "body": "## Summary\n\n- Substitui o envio do arquivo ao Tika via file object pelo uso de um\ngenerator que lê em blocos (`_chunk_file_generator`)\n- Ao passar um generator para `requests.put(data=...)`, a biblioteca usa\nautomaticamente `Transfer-Encoding: chunked` (sem `Content-Length`),\npermitindo que o Tika p\n[…]\ncar que `data` é um `GeneratorType`\n- [ ] Teste de integração com Tika real (coberto pelos testes de\nextração: pdf, doc, docx, odt, txt)\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)",
          "is_bot": false,
          "headline": "feat: envia PDFs ao Apache Tika via chunked transfer encoding (#124)",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T03:28:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8389a4a1dac57c50c2ea8e5d1ac8632effebf1c7",
          "body": "Substitui o envio direto do file object por um generator que lê o\narquivo em blocos, forçando Transfer-Encoding: chunked na requisição\nHTTP. Assim o Tika recebe os dados incrementalmente, evitando\nbufferizar o arquivo inteiro em memória antes de parsear e reduzindo\no risco de OOM.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: envia PDFs ao Apache Tika via chunked transfer encoding",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T03:27:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "672a2c0b46d6597940a900fe5642434c2d1dd742",
          "body": "## Resumo\n\n- Adiciona `ca-certificates` no stage `downloader` do\n`Dockerfile_apache_tika`: `curl` falhava com exit code 77 (error setting\ncertificate file) quando `ca-certificates` não estava disponível\n- Atualiza Apache Tika de `3.2.2` para `3.3.0`: a versão anterior não\nestava mais disponível no C\n[…]\nria quebras futuras a cada novo release do Tika\n\n## Plano de testes\n\n- [ ] Verificar que o build do `Dockerfile_apache_tika` passa na CI\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)",
          "is_bot": false,
          "headline": "fix: corrige build do Dockerfile_apache_tika (#123)",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T03:06:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e0b79e45cc10cee45e4ff3c7d48e0c0a67b5fe1f",
          "body": "A action docker/build-push-action com load:true e platforms definido\nnão exportava a imagem para o daemon local no runner arm64, causando\nfalha 125 no docker run. Usando docker buildx build diretamente sem\n--platform (o runner já é o arch correto), o --load funciona de forma\nconfiável em ambas as arquiteturas, mantendo o cache GHA.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: substitui action por docker buildx build no step de teste do Tika",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:55:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e1329792a84c179ee343ebb76f8c159fa181fcde",
          "body": "A imagem arm64 não era carregada no daemon Docker local (load: false),\ncausando falha no passo de teste com erro 125. Como cada arquitetura\nroda em runner nativo próprio, load: true funciona para ambas.\nAtualiza também o TIKA_VERSION padrão do workflow para 3.3.0.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: corrige build/teste do Tika para arm64 e atualiza versão padrão",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:47:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "adbef68631a780ebff12957800f52c1c25fab340",
          "body": "Versão 3.2.2 não estava mais disponível no CDN (dlcdn.apache.org),\nque só hospeda a versão mais recente. Atualiza para 3.3.0 e migra\npara archive.apache.org/dist/ para evitar quebras futuras quando\nnovas versões forem lançadas.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: atualiza Apache Tika para 3.3.0 e usa URL do arquivo",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:40:07Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ad0d30b268e6248c155ca75998ffc1d2e1706681",
          "body": "…_tika\n\ncurl falha com exit code 77 (error setting certificate file) quando\nca-certificates não está disponível. Adicionado ao mesmo apt-get do curl.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: instala ca-certificates no stage downloader do Dockerfile_apache…",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:32:37Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "de2be06cc769c7b3c90a3b2f2e4cf43b8dbd9aed",
          "body": "Adiciona ignore-error=true em todos os cache-to para evitar que\nindisponibilidade temporária do serviço de cache do GHA quebre o build.",
          "is_bot": false,
          "headline": "ci: ignora erros de exportação do cache do GitHub Actions (#122)",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:29:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6c658c48199395e569e50edce7ca932906589132",
          "body": null,
          "is_bot": false,
          "headline": "Merge branch 'main' into feature/relative-file-paths",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:29:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7e027e7d4495766672dec27e34bd6ac9fd558ae7",
          "body": "Adiciona ignore-error=true em todos os cache-to para evitar que\nindisponibilidade temporária do serviço de cache do GHA quebre o build.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: ignora erros de exportação do cache do GitHub Actions",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:28:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6c2502b1264638413eea67bc73cd4b5945930cc5",
          "body": "…endências (#121)\n\n## Resumo\n\n- **Observabilidade**: implementa `JsonFormatter` para logs estruturados\nem JSON, elimina duplicação de entradas de log e consolida tracebacks em\ncampo único (compatível com Grafana Loki)\n- **Docker**: otimiza imagens (torch CPU-only, separação de deps de dev,\nremoção d\n[…]\n ls` após build\n- [ ] Testar extração de texto com Tika: `make retest-tika`\n- [ ] Verificar que `make help-build` exibe REGISTRY correto\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)",
          "is_bot": false,
          "headline": "Melhorias de observabilidade, otimizações Docker e atualização de dep…",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:22:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "247dbd42cc3ae13dea258c6bd693604d8c2732a8",
          "body": "O wrapper em extract_text() que envolvia exceptions com\n\"Could not extract file content\" foi removido (evitava double-logging).\nO teste agora verifica apenas que uma Exception é lançada quando\no Tika falha, sem depender do texto da mensagem.\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: atualiza teste para refletir propagação direta de exception do Tika",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:16:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c541c6ab577ddeeb49d936a218ee5b3b552a6b40",
          "body": "Substitui tags flutuantes (v4, v5, v3) por hashes imutáveis para\nevitar execução involuntária de código alterado nas actions.\n\n  actions/checkout          v4   -> v4.3.1  (34e11487)\n  actions/setup-python      v5   -> v5.6.0  (a26af69b)\n  docker/setup-buildx-action v3  -> v3.12.0 (8d2750c6)\n  docker/login-action       v3   -> v3.7.0  (c94ce9fb)\n  docker/build-push-action  v5   -> v5.4.0  (ca052bb5)\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: pina actions do GitHub Actions em hashes de commit específicos",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:14:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "85cda98cb41c79a8ce8d63c13b5b135741672eb6",
          "body": null,
          "is_bot": false,
          "headline": "fix: linter",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T02:05:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e30ee9ba3266810f01f6dc5c52bf4ecfe8b21d6c",
          "body": "- Passa BUILD_DATE, VCS_REF e VERSION como build-args em todos os workflows\n- Passa TIKA_VERSION como build-arg no build_apache_tika.yaml\n- Adiciona trigger issue_comment com filtro 'cicd/build' para acionar\n  builds manualmente via comentário em PRs\n- Adiciona trigger push.branches=main com paths n\n[…]\ned em build_apache_tika.yaml para usar\n  github.repository_owner\n- Adiciona input tika_version no workflow_dispatch do build_apache_tika.yaml\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: adiciona build-args de metadados e trigger cicd/build nos workflows",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-12T01:55:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "868dc804cd0a49b413efdc6a38ad0582942915d8",
          "body": "- Adiciona prefixo r\"...\" em regex com \\s em al_associacao_municipios.py\n- Atualiza ruff de v0.6.2 para v0.15.10 no .pre-commit-config.yaml\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: corrige SyntaxWarning em regex e atualiza ruff no pre-commit",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-11T21:37:39Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e0721f2260eb00e85285c68a3632f10d8c9a55e2",
          "body": "Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: atualiza documentação de build Docker para estado atual",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-11T20:33:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "df3576bf9c2f4696865931a35ba95d6af6d35b70",
          "body": "Quando REGISTRY não é passado explicitamente, o valor é inferido da\nURL do remote `origin`:\n  - Extrai owner e host via sed (suporta SSH e HTTPS)\n  - Mapeia git host → container registry:\n      github.com  → ghcr.io\n      gitlab.com  → registry.gitlab.com\n      outros      → host original\n  - Fallba\n[…]\nistir\n\nExemplo: git@github.com:okfn-brasil/repo.git → ghcr.io/okfn-brasil\nOverride manual ainda funciona: make build REGISTRY=my.registry/org\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: deriva REGISTRY automaticamente a partir do remote git",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-11T20:33:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d7319b86a7ebf70c0a4bb06cb4ee49e168bcf3f1",
          "body": "- Instala torch CPU-only antes dos demais pacotes (economia ~1.5 GB)\n- Separa dependências de dev em requirements-dev.txt\n- Remove curl do builder stage (desnecessário após remoção do git-lfs)\n- Move OCI labels exclusivamente para o runtime stage\n- Remove diretórios de teste bundled nos pacotes Python\n- Parametriza TIKA_VERSION no Dockerfile_apache_tika\n- Adiciona suporte a multiarch (amd64+arm64) com cache remoto no Makefile\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf: otimiza Dockerfiles para reduzir tamanho e tempo de build",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-11T20:33:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e6512dddf979edf6a795c08af437c1d0662f7fc8",
          "body": "…entes\n\n- Atualiza .python-version para usar o venv qd-data-processing-3-14-4\n- Atualiza Dockerfiles (Dockerfile e Dockerfile.base) de python:3.11-slim\n  para python:3.14-slim\n- Atualiza todas as dependências para suas versões estáveis mais recentes:\n  - black: 24.10.0 → 26.3.1\n  - coverage: 7.6.9 →\n[…]\n.33.1\n  - scikit-learn: 1.5.2 → 1.8.0\n  - sentence-transformers: 3.3.1 → 5.4.0\n  - huggingface-hub: 0.26.5 → 1.10.1\n  - numpy: 1.26.4 → 2.4.4\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: atualiza Python para 3.14 e dependências para versões mais rec…",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-11T19:26:33Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9122ff0fc0887cc566c2fcd63db2437dc9beebbc",
          "body": "- Adiciona JsonFormatter que serializa cada entrada como uma única linha\n  JSON, preservando todos os campos extra={} e consolidando tracebacks\n  num único campo 'traceback' (evita fragmentação no Grafana Loki)\n- Silencia loggers de opensearchpy e urllib3 em WARNING para eliminar\n  spam de requisiçõ\n[…]\nto\n- Substitui logging.exception(e) por exc_info=True no logging.error()\n  existente, consolidando erro e traceback em uma única entrada JSON\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: melhora observabilidade e elimina duplicação de logs",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-11T16:02:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "545a61f00849eb7bdcef5dba669c9e06813535e3",
          "body": "…eline\n\n- Carrega modelo com low_cpu_mem_usage=True para reduzir pico de memória\n  durante inicialização (evita mmap de ~415 MB de uma só vez)\n- Adiciona cache do modelo a nível de módulo para evitar recarregamentos\n  desnecessários entre chamadas consecutivas de embedding_rerank_excerpts\n- Documenta as etapas do pipeline gazette_texts no README\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: reduz consumo de memória ao carregar modelo BERT e documenta pip…",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-04-11T15:26:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b0b7d6ab619aff8ee7d2d55c5353d673cacd7430",
          "body": "- Aumenta tentativas de retry de 3 para 5 com backoff exponencial melhorado\n- Adiciona jitter de 10% no backoff para prevenir thundering herd\n- Implementa connection pooling com requests.Session para reutilizar conexões\n- Adiciona configuração via variáveis de ambiente:\n  * TIKA_MAX_RETRIES (padrão:\n[…]\ntas mudanças reduzem significativamente erros de conexão durante\ninicialização do Tika e melhoram performance com keep-alive HTTP.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
          "is_bot": false,
          "headline": "Melhora confiabilidade de conexão com Apache Tika",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-02-19T03:20:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "002af4dfae26caf8a6cca1c4584574221c4e7462",
          "body": "O código Python espera o modelo em $HOME/models/bert-base-portuguese-cased\nmas o Dockerfile.base estava salvando em /tmp/bert-model, causando o erro:\nValueError: Path /home/gazette/models/bert-base-portuguese-cased not found\n\nMudanças:\n- Cria diretório /home/gazette/models no builder stage\n- Salva m\n[…]\nelo para o user home com permissões adequadas\n- Remove variável SENTENCE_TRANSFORMERS_HOME (não mais necessária)\n\nFixes: #produção\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>",
          "is_bot": false,
          "headline": "fix: corrige caminho do modelo BERT na imagem Docker",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-02-17T13:35:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b4774b567e4df92da59c84b38ac3bb8f1d9bbc8a",
          "body": "…(#113)\n\n## Descrição\n\nEsta PR adiciona suporte para armazenar apenas caminhos relativos de\narquivos no OpenSearch ao invés de URLs completas, permitindo migração\nde storage providers e uso de CDN/CloudFront sem necessidade de\nreprocessamento de dados.\n\n## Problema\n\nAtualmente, o sistema armazena UR\n[…]\ns Passos\n\n1. ✅ Merge desta PR (data-processing)\n2. ⏳ Merge da PR da API\n3. ⏳ Deploy em staging\n4. ⏳ Validação com dados reais\n5. ⏳ Habilitação de `USE_RELATIVE_FILE_PATHS=true`\n6. ⏳ Deploy em produção",
          "is_bot": false,
          "headline": "feat: adiciona suporte para armazenar caminhos relativos de arquivos …",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-01-13T13:56:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "edecfd27affb4c0bc77f908b3ad275fef493fa3a",
          "body": "- Adiciona stream=False e timeout=(30,300) ao assert do test_request_is_sent_to_apache_tika_server\n- Adiciona método close() aos mocks de response\n- Corrige test_storage_call_to_get_file para usar string direta ao invés de self.data[0]\n  (que é limpo durante o processamento)",
          "is_bot": false,
          "headline": "fix: corrige testes adicionais que estavam falhando",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-01-13T13:20:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "784970377bc52306f143f601199ddc9f4f29026d",
          "body": "- Corrige problema de referência em mocks ao copiar gazette antes de indexar\n- Corrige leitura dinâmica de QUERY_PAGE_SIZE para permitir mocking em testes\n- Adiciona status_code=200 aos mocks de requests.put nos testes\n- Garante que index_document recebe dados completos antes do clear()\n\nFixes #113",
          "is_bot": false,
          "headline": "fix: corrige testes quebrados na branch",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-01-13T13:06:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "97abe678865f810ddf0f050607984c80692f803a",
          "body": null,
          "is_bot": false,
          "headline": "(fix) ruff format",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-01-11T21:44:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cc0549958435b71c4c91050f82e8bb3696371134",
          "body": "- Adiciona feature flag USE_RELATIVE_FILE_PATHS (padrão: false)\n- Quando habilitado, armazena apenas caminhos relativos no OpenSearch ao invés de URLs completas\n- Mantém 100% de retrocompatibilidade com comportamento existente\n- Deprecia funções define_file_url() e get_file_endpoint()\n- Permite uso \n[…]\ncessamento de dados\n- Possibilita migração de storage provider sem reprocessamento\n\nDocumentação relacionada:\n- IMPLEMENTATION_SUMMARY.md\n- FILE_URL_MIGRATION_GUIDE.md\n- REFACTORING_PLAN_FILE_PATHS.md",
          "is_bot": false,
          "headline": "feat: adiciona suporte para armazenar caminhos relativos de arquivos",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2026-01-11T21:07:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "56806b530fc37565f9633c39aee157736a15b67f",
          "body": "## Problema\n\nAo tentar fazer upload de arquivos para S3, ocorria o erro:\n```\nAn error occurred (AccessControlListNotSupported) when calling the PutObject operation: \nThe bucket does not allow ACLs\n```\n\nIsso acontece porque buckets S3 modernos frequentemente têm a\nconfiguração 'Object Ownership' defi\n[…]\ns\nS3-compatíveis\n\n## Nota\n\nEste não era um problema de permissão IAM faltante, mas sim uma\nincompatibilidade entre o código (que tentava definir ACLs) e a\nconfiguração do bucket (que desabilita ACLs).",
          "is_bot": false,
          "headline": "fix: Remove uso de ACL nos uploads para S3 (#111)",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-12-29T21:27:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "103aeb6acbeb424460a70c4fe277dcf5ab34ab7f",
          "body": "Buckets S3 modernos frequentemente têm 'Object Ownership' configurado como\n'Bucket owner enforced', o que desabilita ACLs completamente. Isso causava\nerros 'AccessControlListNotSupported' ao tentar fazer upload de arquivos.\n\nEsta mudança remove todos os parâmetros ACL das operações de upload:\n- uplo\n[…]\nlico agora deve ser controlado via políticas de bucket ao invés\nde ACLs em nível de objeto, seguindo as melhores práticas da AWS.\n\nCorrige o erro AccessControlListNotSupported ao fazer upload para S3.",
          "is_bot": false,
          "headline": "fix: Remove uso de ACL nos uploads para S3",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-12-29T21:26:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "191ed489d398c3e45524539a7db0f3a1a5a53faa",
          "body": "## Descrição\n\nEste PR adapta o cliente S3 para tornar o `STORAGE_ENDPOINT` opcional,\npermitindo compatibilidade tanto com **Digital Ocean Spaces/Minio** (que\nrequerem endpoint customizado) quanto com **AWS S3 nativo** (que usa\nendpoint padrão baseado na região).\n\n## Motivação\n\nAtualmente o código ex\n[…]\ndo\n\n## Checklist\n\n- [x] Código testado localmente\n- [x] Testes unitários adicionados\n- [x] Documentação atualizada (docstrings)\n- [x] Compatibilidade retroativa mantida\n- [x] Pre-commit hooks passando",
          "is_bot": false,
          "headline": "Torna STORAGE_ENDPOINT opcional para suportar AWS S3 (#110)",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-12-29T20:52:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "519ee25dfb905771f6fbecc4704b0dc69a153d9a",
          "body": "Modifica a configuração do cliente S3 para tornar o endpoint_url opcional,\npermitindo compatibilidade tanto com Digital Ocean Spaces/Minio (que requerem\nendpoint customizado) quanto com AWS S3 (que usa endpoint padrão baseado na região).\n\nMudanças:\n- get_storage_endpoint() agora usa os.environ.get()\n[…]\nbilidade com múltiplos provedores\n- Adiciona teste para validar criação do cliente sem endpoint (cenário AWS S3)\n\nPara usar com AWS S3, basta não definir a variável STORAGE_ENDPOINT ou deixá-la vazia.",
          "is_bot": false,
          "headline": "Torna STORAGE_ENDPOINT opcional para suportar AWS S3",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-12-29T20:41:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b32000355767fcd4a7f2e151cbc11e731a8b75ee",
          "body": "Documenta:\n- Bug de serialização JSON com casos reais dos logs\n- Melhorias de observabilidade e resiliência\n- Testes de validação com dados reais\n- Guia de reprocessamento de diários afetados\n- Checklist de próximos passos\n\nReferências: commits d8c8dda e 3cb2be9",
          "is_bot": false,
          "headline": "Adiciona documentação completa das correções implementadas",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-12-01T00:11:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3cb2be96a69e0490ed254aa4b97ead06a1e7fd05",
          "body": "Problema:\n- Logs genéricos 'Could not extract file content' sem contexto\n- Impossível diagnosticar causa raiz (conexão, timeout, HTTP error)\n- Sem informações sobre arquivo, tamanho, tipo MIME ou diário\n- Falhas transitórias causavam perda de processamento\n\nMelhorias de Observabilidade:\n- Logs espec\n[…]\no da causa raiz via logs estruturados\n- Menos falhas por problemas transitórios de rede\n- Rastreabilidade completa: erro → arquivo → diário\n- Monitoramento aprimorado para identificar padrões de falha",
          "is_bot": false,
          "headline": "Melhora observabilidade e resiliência na extração de texto",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-30T20:44:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d8c8dda03cba423ae0c102df032fc6cae610219b",
          "body": "Problema:\n- TypeError: Object of type date is not JSON serializable\n- Ocorria na linha 119 de index/opensearch.py durante a indexação\n- Objetos date/datetime do PostgreSQL eram passados diretamente para json.dumps()\n\nSolução:\n- Adiciona função date_serializer() em index/opensearch.py\n- Adiciona funç\n[…]\nto:\n- Corrige TypeError sistemático na extração de texto de diários\n- Mudanças mínimas e cirúrgicas\n- Retrocompatível - não altera formato de dados\n- Usa formato ISO padrão já esperado pelo OpenSearch",
          "is_bot": false,
          "headline": "Corrige erro de serialização JSON com objetos date",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-30T20:21:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d5edbe1f7ca2a03aafaf782dcde6a06e656e49a9",
          "body": "…rita do OpenSearch\n\n- Implementa decorator retry_with_exponential_backoff com 3 tentativas\n- Aplica lógica de retry aos métodos create_index() e refresh_index()\n- Adiciona lógica de retry inline ao index_document() preservando logging existente\n- Usa backoff exponencial: delays de 1s, 2s, 4s entre tentativas\n- Total de 4 tentativas (1 inicial + 3 retries) antes de falhar\n- Melhora resiliência contra problemas transitórios de rede e conexão",
          "is_bot": false,
          "headline": "Adiciona lógica de retry com backoff exponencial nas operações de esc…",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-29T21:56:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a839f5840748700e9333aa8c62e71c586bd741ba",
          "body": "Documentação completa sobre como usar o sistema de logging estruturado\npara diagnosticar problemas de conexão com Tika e OpenSearch.",
          "is_bot": false,
          "headline": "Adiciona guia de uso do sistema de monitoramento",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-29T21:02:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fc0990d3b353a41d76af0776968e27b18ad07da7",
          "body": "Implementa sistema de monitoramento e logging estruturado para facilitar\ndiagnóstico de problemas de conexão com Apache Tika e OpenSearch, incluindo\no erro ChunkedEncodingError reportado.\n\nFuncionalidades Adicionadas:\n\nMódulo de Monitoramento (monitoring/):\n- Logging estruturado com eventos nomeados\n[…]\nida de gargalos de performance\n- Diagnóstico facilitado de ChunkedEncodingError e outros erros de conexão\n- Estatísticas agregadas para análise de tendências\n- Nenhuma dependência adicional necessária",
          "is_bot": false,
          "headline": "Adiciona logging estruturado para monitorar conexões Tika e OpenSearch",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-29T21:01:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "da9290690c0fd2ef107fad379bb00f040ccbaee9",
          "body": "Corrige problema onde o processamento crashava ao tentar baixar\narquivos de diários que não existem no bucket de armazenamento.\n\nMudanças:\n- Adiciona tratamento específico para ClientError com código 404\n- Registra informações detalhadas sobre arquivos ausentes (file_path, ID, checksum)\n- Pula diári\n[…]\nde outros erros de storage\n\nBenefícios:\n- Processamento continua mesmo com arquivos ausentes\n- Melhor rastreabilidade de problemas de qualidade de dados\n- Não afeta fluxo de processamento bem-sucedido",
          "is_bot": false,
          "headline": "Adiciona tratamento para arquivos ausentes no storage (erro 404)",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-29T17:26:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c8624d7e20707a4a8608e4b1588b357c92419343",
          "body": null,
          "is_bot": false,
          "headline": "Ignora diretório de debug",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-29T14:43:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "be9d68897fdf55d10ef708e73ccac94a9235bbd5",
          "body": "- Configura max_retries=3 para tentar até 3 vezes em caso de falha\n- Ativa retry_on_timeout=True para retentar quando houver timeout\n- Melhora a resiliência em ambientes com latência ou instabilidade de rede",
          "is_bot": false,
          "headline": "Adiciona retry automático nas requisições ao OpenSearch",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T22:10:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23acf8f8369d35369240494a481b52c73f65ffd6",
          "body": "- Adiciona parâmetro timeout na criação do cliente opensearchpy.OpenSearch\n- Resolve problema de timeout de 10s (padrão) em produção\n- Garante que todas as operações (conexão, leitura, escrita) respeitem o timeout de 60s configurado",
          "is_bot": false,
          "headline": "Corrige timeout do cliente OpenSearch para usar valor configurado",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T22:09:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fbb58a37c18e19cea541beeb74455a1e3172d519",
          "body": "- Altera timeout padrão no construtor de 30 para 60 segundos\n- Adiciona request_timeout ao método index_document para respeitar o timeout configurado\n- Melhora a confiabilidade ao indexar documentos grandes ou em ambientes com maior latência",
          "is_bot": false,
          "headline": "Aumenta timeout padrão do OpenSearch de 30 para 60 segundos",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T22:07:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f52027c1e26e931d41e2cbb75eed809b4b1499b8",
          "body": "- Adiciona cláusula WHERE para excluir arquivos terminados em .zip nas três funções de listagem de diários\n- Previne downloads e processamento desnecessários de arquivos ZIP não suportados\n- Mais eficiente do que verificar o tipo de arquivo após o download",
          "is_bot": false,
          "headline": "Filtra arquivos .zip diretamente nas queries SQL",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T21:32:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "374c5e80afc29b220044600792b82af81054bc27",
          "body": "- Reduz batch size de 500 para 250 na extração de excertos temáticos\n- Reduz query size de 100 para 50 em consultas de documentos por IDs\n- Reduz query size de 10 para 5 em consultas de diários com queries temáticas\n- Reduz query size de 100 para 50 em marcação de entidades em excertos\n\nObjetivo: Reduzir carga e estresse no OpenSearch durante processamento",
          "is_bot": false,
          "headline": "Reduz tamanho dos batches enviados ao OpenSearch em 50%",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T21:11:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c39f6bf4410ae865904ae5dbcea9a5c3dbf5081c",
          "body": "## 🎯 Objetivo\n\nReduzir a verbosidade dos logs para arquivos com tipos não suportados\n(especialmente ZIP) e melhorar a eficiência evitando tentativas de\nprocessamento desnecessárias.\n\n## 📋 Problema\n\nArquivos ZIP e outros tipos não suportados geravam logs extremamente\nverbosos:\n- WARNING com o caminho\n[…]\nção\n- `tasks/gazette_text_extraction.py` - Detecção antecipada e tratamento\nde erros\n\n## 🧪 Testes\n\n- Sintaxe Python validada com `py_compile`\n- Imports verificados\n- Lógica de fluxo mantida inalterada",
          "is_bot": false,
          "headline": "Melhora tratamento de erros para tipos de arquivo não suportados (#109)",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T21:10:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7762d217b4ac99acc75b995e78d27c25c9d566b3",
          "body": null,
          "is_bot": false,
          "headline": "Fix linter",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T21:09:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a456b29ab28d3a7933d91f1f05050ee2be069f0",
          "body": "- Cria exceção customizada UnsupportedFileTypeError para tipos não suportados\n- Adiciona detecção antecipada de arquivos ZIP (não suportados)\n- Reduz verbosidade de logs para tipos não suportados (sem stack trace)\n- Mantém logs completos apenas para erros inesperados\n- Melhora eficiência evitando processamento de arquivos ZIP\n\nResolve problema de logs verbosos com arquivos ZIP e outros tipos não suportados.",
          "is_bot": false,
          "headline": "Melhora tratamento de erros para tipos de arquivo não suportados",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T17:28:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cc88b36af452d818b6aa3a26607d0e705832024a",
          "body": "…orrige problemas críticos (#108)\n\n## Descrição\n\nEsta PR reorganiza a documentação de otimização de performance e\nimplementa correções críticas para melhorar a estabilidade e eficiência\ndo sistema.\n\n## Mudanças Principais\n\n### Documentação\n- Move relatório de otimização de performance para \n- Adicio\n[…]\nte_text_extraction.py`\n- `tasks/list_gazettes_to_be_processed.py`\n- `tests/__init__.py`\n\n## Arquivos Criados\n- Documentação em `iniciativas/performance_optimization/`\n- Testes de paginação em `tests/`",
          "is_bot": false,
          "headline": "Refatoração: Reorganiza documentação de otimização de performance e c…",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T17:21:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e381c6d5c4a7ef8c7c256c40306850e3a3deb86c",
          "body": "…orrige problemas críticos\n\n- Move relatório de otimização de performance para iniciativas/performance_optimization/\n- Adiciona documentação abrangente para hotfixes, implementação e próximos passos\n- Corrige parâmetros de conexão PostgreSQL para limpeza adequada\n- Melhora paginação de listagem de diários com uso otimizado de memória\n- Adiciona melhorias de processamento em lote e pool de conexões\n- Inclui testes de regressão para funcionalidade de paginação",
          "is_bot": false,
          "headline": "Refatoração: Reorganiza documentação de otimização de performance e c…",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T17:19:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "abd5ab9c412aa9330ea0a443c64364588a5252da",
          "body": "…mo de memória",
          "is_bot": false,
          "headline": "Ajusta o plano de otimização de performance com foco em reduzir consu…",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T14:06:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "88e80859fb95bcd55f6f15a9ab6c6dc375027765",
          "body": null,
          "is_bot": false,
          "headline": "Primeira versão do plano de refatoração",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T12:59:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "20a8ebf2be57add7b8f79161689de4079bdf06ee",
          "body": "Atualiza o script de build para garantir que temos as versões mais recentes\ndas imagens antes de iniciar cada fase de build, melhorando o reuso de cache\ne reduzindo o tempo de build.\n\nMudanças:\n1. Pull da imagem base antes de buildar (linha 1-2):\n   - Garante que temos as últimas layers em cache\n   \n[…]\n\n   - Permite reuso máximo de layers entre builds\n\nBenefícios:\n- Builds mais rápidos com melhor reuso de cache\n- Consistência garantida entre builds sucessivos\n- Redução de tempo em pipelines de CI/CD",
          "is_bot": false,
          "headline": "feat: adiciona pull de imagens antes dos builds para cache otimizado",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T04:48:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "02f817b67044b0170710fcb32ab8cf7e5720d722",
          "body": "Implementa coleta de lixo (garbage collection) após extração de texto e\nprocessamento de cada diário oficial para liberar memória e prevenir\nacúmulo de cache.\n\nMelhorias implementadas:\n\n1. data_extraction/text_extraction.py:\n   - Adiciona gc.collect() após cada chamada ao Apache Tika\n   - Remove exp\n[…]\nento em lote\n\nEstas mudanças complementam os controles de memória implementados no\nstartup da aplicação, garantindo que a memória seja liberada de forma\nproativa durante o processamento de documentos.",
          "is_bot": false,
          "headline": "feat: adiciona limpeza de cache do Tika após processar documentos",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T04:41:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1726ca7c2798d736ce5635cd5643dd64fc2ab513",
          "body": "Adiciona configuração de limites de memória e garbage collection agressivo\nno processo de startup da aplicação para resolver problemas de out-of-memory\nem produção.\n\nImplementação:\n- Limite suave de memória: 1.5 GB\n- Limite rígido de memória: 1.9 GB (para containers de 2GB)\n- Garbage collection mais\n[…]\nndo que os controles sejam aplicados antes de qualquer processamento\npesado de dados.\n\nIsso deve prevenir crashes por estouro de memória e melhorar a estabilidade\nda aplicação em ambiente de produção.",
          "is_bot": false,
          "headline": "feat: implementa controles de memória para prevenir estouro em produção",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T04:37:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b95346f84fb302d96145020ca257b08a2b1cbf6b",
          "body": null,
          "is_bot": false,
          "headline": "Script auxiliar para fazer build e push das imagens localmente",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T04:32:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ea8a3ff4ad6e714733895af81ae1752c32030f9",
          "body": "Como a imagem \"final\" usará um usuário específico, e não o root user do\ncontainer, precisamos copiar os pacotes para outro local.",
          "is_bot": false,
          "headline": "Atualiza o Dockerfile.base ajustando paths",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-28T04:31:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "acdd581f5e1c8d0f721ddda864d8a4cb2822f1ff",
          "body": null,
          "is_bot": false,
          "headline": "Testando novo approach",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-26T02:51:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0cb6d02e3bb689924187f43e2a27aed4ac8e6f06",
          "body": null,
          "is_bot": false,
          "headline": "Adiciona dependência faltante",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-26T02:44:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e7099b9efd645c21d6148fb2b5edd4eff75a036d",
          "body": "Created scripts/build_app_image_local.sh for building the main application\nimage locally and pushing to the registry.\n\nFeatures:\n- Builds for both amd64 and arm64 architectures\n- Verifies base image exists before building\n- Checks Docker buildx configuration\n- Validates registry login\n- Interactive \n[…]\nge is available\n2. Check Docker buildx setup\n3. Confirm you're logged in to ghcr.io\n4. Ask for tag choice (latest or version)\n5. Build and push multi-arch image\n6. Show success message with image URLs",
          "is_bot": false,
          "headline": "Add script to build and push main application image",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T14:32:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "51e3ad35be23d140f29267baa83649f5b4f4883f",
          "body": "Created comprehensive tooling for building the base image locally:\n\n1. scripts/build_base_image_local.sh\n   - Interactive script to build base image locally\n   - Supports both amd64 and arm64 platforms\n   - Two modes:\n     * Push to registry (builds both platforms)\n     * Load locally (builds curren\n[…]\n\n   - Testing and verification steps\n\nUsage:\n  ./scripts/build_base_image_local.sh\n\nThis allows developers to build and test the base image locally\nbefore pushing changes that would trigger CI builds.",
          "is_bot": false,
          "headline": "Add local base image build script and documentation",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T12:36:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fd95cf9e675d83ce4189e1cf3faaf1c2c5b0aa97",
          "body": "Changed schedule from daily (2 AM UTC every day) to monthly (2 AM UTC on 1st of month).\n\nReasons:\n- Daily builds are excessive for validation purposes\n- Monthly builds are sufficient to catch issues\n- Reduces CI minutes usage by ~97% (30 builds/month → 1 build/month)\n- Images are built on-demand for\n[…]\nmages build correctly\n✅ Up-to-date monthly snapshot images\n✅ Immediate builds when tags are pushed\n✅ Manual builds via workflow_dispatch\n\nCI minutes saved: ~29 builds/month × 3 min = ~87 minutes/month",
          "is_bot": false,
          "headline": "Change scheduled builds from daily to monthly",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T12:18:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4677a48e6a151ffbe3aa2147f63a425d6e9500cf",
          "body": "MAJOR REFACTOR to solve disk space issues and improve CI efficiency.\n\n## Changes Overview:\n\n### 1. Created Base Image System\n- **Dockerfile.base**: Contains all dependencies (Python packages + ML models)\n- **build_base_image.yaml**: Workflow to build base image\n  - Triggers: requirements.txt changes\n[…]\nmage (requirements.txt present)\n2. Wait for base image to complete (~15-20 min)\n3. Then build_container_image can use it\n\nTotal implementation: ~20-25 minutes for first build, then 1-2 min thereafter.",
          "is_bot": false,
          "headline": "Implement hybrid CI approach: base image + split workflows",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T12:16:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3ba9257b675f7dc930d1d5d545dbd9f226be9404",
          "body": "Added comprehensive analysis and additional cleanup targets:\n\nDiscovery Features (for future optimization):\n- List top 20 largest installed packages with sizes\n- Scan /usr for large directories (>500MB)\n- Scan /opt for large directories\n- Scan /usr/local for large directories\n- This helps identify n\n[…]\n\n- Previous: ~30GB\n- Now: ~35-40GB (additional 5-10GB from new targets)\n\nThe discovery output will help identify if GitHub adds new large\npackages/tools to their runners that we should add to cleanup.",
          "is_bot": false,
          "headline": "Enhance disk cleanup script with discovery and additional cleanup",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T11:41:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bcfe8a15c44378964b65aa8ceaf3392fe21cf04f",
          "body": "Created .github/scripts/free_disk_space.sh based on Apache Flink's cleanup\nstrategy, which is more aggressive and comprehensive than our inline approach.\n\nThe script includes all our existing cleanup PLUS additional removals:\n\nExisting cleanup (preserved):\n- apt-get autoremove & autoclean\n- Remove /\n[…]\nintainable script (DRY principle)\n- Better error handling (|| true on all operations)\n- Cleaner workflow files (-27 lines)\n- More aggressive package removal\n- Proven strategy from Apache Flink project",
          "is_bot": false,
          "headline": "Improve disk cleanup with comprehensive script based on Apache Flink",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T11:24:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9e8631520a5a12aab89a4cacbc543352f5983df4",
          "body": "The test-multi-arch job was causing CI failures due to:\n1. Disk space exhaustion when building large Docker images with ML dependencies\n2. GitHub Actions Cache service intermittent failures (400 errors)\n3. Redundancy - it only tests imports, which lint_and_unit already covers\n\nReasons for removal:\n-\n[…]\nld time per push\n- Reduces disk space usage in CI\n- Avoids GitHub Actions Cache failures\n- Simpler workflow: build → publish (no redundant test build)\n- Tests are still comprehensive via lint_and_unit",
          "is_bot": false,
          "headline": "Remove redundant test-multi-arch job from build_container_image",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T10:12:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d0a76e77fb2b1632495df1b42a883a23e29bed3f",
          "body": "CI was failing on main branch with 'No space left on device' errors.\n\nThe disk cleanup steps are essential for workflows that build Docker images:\n- build_container_image.yaml: Builds multi-arch data processing images\n- build_apache_tika.yaml: Builds multi-arch Apache Tika images\n\nThese workflows ne\n[…]\n building)\n- Main: Both lint_and_unit AND build_container_image run (builds images)\n\nNote: lint_and_unit.yaml does NOT need disk cleanup since it runs\ntests on the host without building Docker images.",
          "is_bot": false,
          "headline": "Restore disk cleanup for Docker image build workflows",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T10:00:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b5a0eab21e1714be7baf31b116448a32486d48bb",
          "body": "The test-python-unit job was running full integration tests inside Docker\ncontainers, but these tests are already covered by lint_and_unit.yaml which:\n- Runs on both PRs and pushes to main\n- Tests on both amd64 and arm64 architectures\n- Uses the same services (Postgres, OpenSearch, MinIO, Apache Tik\n[…]\nSaves ~10-15 minutes per push to main\n- Clearer workflow purpose: build_container_image focuses on building\n  and publishing images, not comprehensive testing\n- lint_and_unit handles all test coverage",
          "is_bot": false,
          "headline": "Remove redundant test-python-unit job from build_container_image",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T03:42:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "50311acf278d1db18d3495047691061ad2289ba9",
          "body": "Removed 'Free up disk space' and 'Monitor disk usage' steps from:\n- build_apache_tika.yaml (2 instances)\n- build_container_image.yaml (3 cleanup + 2 monitoring steps)\n\nReasons for removal:\n1. GitHub Actions runners have sufficient disk space for our builds\n2. Docker buildx with cache management hand\n[…]\nly\n3. These steps add ~20-30 seconds to each job without clear benefit\n4. If disk space becomes an issue, it will fail clearly and can be addressed then\n\nThis simplifies workflows and reduces CI time.",
          "is_bot": false,
          "headline": "Remove disk cleanup and monitoring steps from workflows",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T03:23:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ba3ebca7ae8a0689f553ad9ec687453234cc0680",
          "body": "The test_pull_request.yml workflow is redundant with lint_and_unit.yaml:\n- Both run on pull requests\n- Both have identical service setup (Postgres, OpenSearch, MinIO, Apache Tika)\n- Both run the same tests with the same environment variables\n- Both test on amd64 and arm64 architectures\n- Both use in\n[…]\ner.py\n\nlint_and_unit.yaml already runs on both 'pull_request' and 'push to main'\nevents, so it covers all the same scenarios.\n\nThis eliminates duplicate test runs on every PR, improving CI efficiency.",
          "is_bot": false,
          "headline": "Remove redundant test_pull_request.yml workflow",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T03:06:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "52ff9c504c6e039b6e4cae28aa643fa7e24bcfec",
          "body": "Created new build_apache_tika.yaml workflow that:\n- Runs only when Dockerfile_apache_tika or its workflow changes\n- Tests Apache Tika on both amd64 and arm64\n- Builds and pushes multi-arch images to GHCR\n- Creates multi-arch manifests\n\nRemoved from build_container_image.yaml:\n- Apache Tika build and\n[…]\nrkflow)\n- create-apache-tika-manifest job (moved to dedicated workflow)\n\nThis separation reduces unnecessary builds and improves CI efficiency\nby only building Apache Tika when its Dockerfile changes.",
          "is_bot": false,
          "headline": "Separate Apache Tika build into dedicated workflow",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T03:02:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1db31c35aceb3beb4aae92c1b33e742fe02a3714",
          "body": "Aligned test-python-unit job with lint_and_unit and test_pull_request:\n- Added plugins.security.disabled and OPENSEARCH_INITIAL_ADMIN_PASSWORD to OpenSearch\n- Replaced MinIO service with manual docker run for better control\n- Added apache-tika service\n- Added Python setup and dependency installation\n[…]\n\n- Added timeout to test execution\n- Added MinIO container cleanup\n\nThese changes ensure tests run with proper service configuration\nand all required environment variables are passed to the container.",
          "is_bot": false,
          "headline": "Improve build_container_image workflow to match other workflows",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-16T01:31:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3a4e74acf2ef637db9661234def1656a9c196568",
          "body": "- Use simpler health check (curl root endpoint instead of _cluster/health)\n- Increase timeout from 5s to 10s\n- Increase retries from 5 to 20\n- Increase interval from 10s to 15s\n- Gives OpenSearch up to ~310 seconds to become healthy\n\nThe _cluster/health endpoint may return non-200 status during startup\neven when OpenSearch is responding. Using root endpoint is more reliable.",
          "is_bot": false,
          "headline": "Fix CI: Update OpenSearch health check in all workflows",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T22:07:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d5c6abdd9cbbfd063f6874f58caadc2fb7de13a0",
          "body": "OpenSearch 2.9.0 takes longer than 75 seconds to start up in CI,\ncausing health check failures. Increased timeout from 5s to 10s\nand retries from 5 to 10, giving it ~110 seconds to become healthy.",
          "is_bot": false,
          "headline": "Fix CI: Increase OpenSearch health check timeout and retries",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T21:38:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "689497d73c72ad41d0192deae1870296879f941b",
          "body": "Update tests to use database.update() instead of the deprecated\ndatabase.set_gazette_as_processed() method, matching the current\nimplementation that uses database.update(command, data).",
          "is_bot": false,
          "headline": "Fix set_gazette_as_processed mock calls",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T20:27:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e280fa373454b82eba0a1f858b771dfcda005ddd",
          "body": "- Update test_upload_gazette_raw_text to match new function signature\n- Fix test_run_with_debug_not_defined to properly clear environment\n- Update index_document assertions to include document_id parameter",
          "is_bot": false,
          "headline": "Fix failing tests to match current function signatures",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T19:55:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "559752e75c81dbea17a0d2ad5f17bbe2b46daa9e",
          "body": null,
          "is_bot": false,
          "headline": "Apply ruff formatting to instrumented_test_runner.py",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T18:39:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4821bfc1b28d0d7170f554e2e76be1a9ad84f6c2",
          "body": "Change pattern from '*.py' to '*_tests.py' to avoid running\nhelper modules (postgresql.py, opensearch.py, etc.) as tests.\nThis fixes test discovery to find only actual test files.",
          "is_bot": false,
          "headline": "Fix test discovery pattern to match only test files",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T18:33:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a8de6e37d1152fda30a6304afd030adb605ac366",
          "body": "Created a custom test runner that provides real-time visibility into test execution:\n\nFeatures:\n- Logs each test start/finish with timestamps\n- Shows duration for every test\n- Displays success/failure/error status immediately\n- Provides timing summary showing slowest tests\n- Forces output flushing (\n[…]\nSearch index creation diagnostics (timeout + connectivity test)\n- Better structured output in test steps\n\nAll output is explicitly flushed to ensure we see it in CI logs\neven if tests timeout or fail.",
          "is_bot": false,
          "headline": "Add instrumented test runner for detailed CI debugging",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T18:21:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fae770799bc90904a1242189483d55013c6bac9f",
          "body": "Tests timing out without ANY output suggests something fundamental is wrong.\n\nStripped down to bare minimum:\n- Single echo at start\n- Direct python unittest command (no timeout, no stdbuf, no set +e)\n- Single echo at end\n- Let step timeout-minutes handle the timeout\n\nIf we see 'SCRIPT STARTED', the \n[…]\nomething is preventing the step from executing at all.\n\nThis is the simplest possible test to see if:\n1. Shell script executes\n2. Python command runs (even if it hangs)\n3. We get ANY output whatsoever",
          "is_bot": false,
          "headline": "Simplify test run to absolute minimum",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T18:01:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "afa2aa761ae44096efb1dcf66e3a6226c856c938",
          "body": "Tests are timing out without showing any diagnostic output.\nSimplified to help debug:\n\n1. Removed coverage from test run\n   - coverage initialization might be hanging\n   - Tests now run with plain unittest\n\n2. Added prominent '=====' markers\n   - Makes it crystal clear if test step even starts\n   - \n[…]\nc checks\n   - Service health checks\n   - Python version\n   - Timestamps\n\nIf we see '===== TEST STEP STARTED =====' we know the step is executing.\nIf we don't, the issue is before our script even runs.",
          "is_bot": false,
          "headline": "Remove coverage and add prominent test start marker",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T17:46:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f406e1da93ca3ec9773b4ac25c35f211940bcc9c",
          "body": "Tests are timing out without any output, suggesting the hang happens\nduring import/discovery phase before any test runs.\n\nAdded diagnostic output:\n- Python version\n- Service availability checks (OpenSearch, Tika, MinIO)\n- Explicit 'Starting test discovery...' message\n\nThis will help identify:\n1. If \n[…]\ntarts\n3. Any connectivity issues between runner and services\n\nIf we see 'Starting test discovery...' but no test output, the issue\nis in test module imports. If we don't see it, services aren't ready.",
          "is_bot": false,
          "headline": "Add service health checks before running tests",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T17:33:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c0d529b36ab3cbbf011d3f9611b314211201ea19",
          "body": "The timeout was catching failures but not propagating them, causing\nCI to appear successful even when tests timed out or failed.\n\nChanges:\n- Capture exit code from timeout command (124 = timeout, others = test failure)\n- Use set +e/set -e to allow capturing exit code without immediate failure\n- Expl\n[…]\nlure\n\nNow:\n- Timeout after 3 minutes → exit 1 with clear error message\n- Test failures → propagate actual exit code\n- Success → continue to coverage report\n\nThis restores proper CI failure visibility.",
          "is_bot": false,
          "headline": "Fix: Make test timeout actually fail the CI",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T17:23:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7c8bdddde8afd4e9ac1243bdbbec2ff5d4a8aee4",
          "body": "The Apache Tika multi-arch build workflow has been moved to branch\ndro/add_multiarch_tika to be merged to main first.\n\nThis allows the Tika images to be built and published before the CI\nworkflows try to use them.",
          "is_bot": false,
          "headline": "Remove Apache Tika build workflow (moved to separate branch)",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T17:03:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bb7df3499c82cc91d115150215aa4a9ccb345c1d",
          "body": "Created workflow to build and publish multi-arch Apache Tika images:\n\n1. New workflow: build_apache_tika.yaml\n   - Builds Apache Tika for linux/amd64 and linux/arm64\n   - Uses QEMU for cross-platform builds\n   - Pushes to ghcr.io (GitHub Container Registry)\n   - Includes caching for faster builds\n  \n[…]\n Apache Tika failed with 'exec format error'\nsince the official apache/tika image only supports AMD64.\n\nThe workflow must be run first to build and publish the images before\nthe CI tests can use them.",
          "is_bot": false,
          "headline": "Add multi-arch Apache Tika build workflow and update CI",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T16:37:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "52ac03e4ff3df2986470defdc36c3ebc0ff57c84",
          "body": "Tests are still hanging. Making changes to get better visibility:\n\n1. Reduced timeout-minutes from 10 to 5\n2. Reduced shell timeout from 300s to 180s (3 minutes)\n3. Added PYTHONUNBUFFERED=1 to force immediate output\n4. Added stdbuf -oL -eL to unbuffer stdout/stderr\n5. Added timestamp logging before/\n[…]\ne\n\nThis should show us EXACTLY where the hang is happening by forcing\nall output to be flushed immediately. If tests still hang, we'll see\nthe last test that was attempted before the 3-minute timeout.",
          "is_bot": false,
          "headline": "Reduce timeout to 3 minutes and add unbuffered output",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T16:17:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bcb901eb8ef72b3afc28c1fab3fcb8ed3b4ab54d",
          "body": "Tests are hanging indefinitely. Adding safeguards to prevent model downloads:\n\n1. Set HF_HUB_OFFLINE=1 and TRANSFORMERS_OFFLINE=1\n   - Prevents HuggingFace/Transformers from downloading models\n   - Forces libraries to work with local files only\n\n2. Set SENTENCE_TRANSFORMERS_HOME=/tmp/sentence_transf\n[…]\ner feedback with '|| echo' to show timeout occurred\n\nThis should prevent tests from hanging while trying to download ML models\nthat may be referenced in the codebase but not actually needed for tests.",
          "is_bot": false,
          "headline": "Add offline mode and timeout for ML libraries",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T16:11:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c28332ddc1bd47eded1bc63dc900497174f2d921",
          "body": "Tests were hanging indefinitely in CI. Added improvements:\n\n1. Added 'timeout-minutes: 10' to test steps\n   - Prevents jobs from running for hours if stuck\n   - Tests should complete in under 5 minutes normally\n\n2. Added '-v' (verbose) flag to test_pull_request.yml tests\n   - Helps identify which test is running when timeout occurs\n   - Matches the verbosity in lint_and_unit.yaml\n\nThis will help identify where tests are getting stuck and prevent\nresource waste from indefinitely running jobs.",
          "is_bot": false,
          "headline": "Add timeout and verbose output to test steps",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T16:01:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d4c92de39ea4a6ea109a14124014a89fd76123b1",
          "body": "The CI was failing on ARM64 runners with 'Exec format error' because\nwe were downloading the amd64 MinIO client binary on all platforms.\n\nSolution:\n- Detect the system architecture using 'uname -m'\n- Download linux-arm64/mc for aarch64/arm64 systems\n- Download linux-amd64/mc for x86_64 systems\n- Added logging to show which architecture is being used\n\nThis fixes the error:\n'/tmp/mc: cannot execute binary file: Exec format error'",
          "is_bot": false,
          "headline": "Fix: Download correct MinIO client for ARM64 architecture",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T15:51:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "026c7813d98208186bcad7c78331a2b3b00eca23",
          "body": "Enhanced the manual MinIO container startup:\n- Added Docker healthcheck options for better reliability\n- Used timeout with bash until loop for cleaner wait logic\n- Added --console-address :9001 to avoid port conflicts\n- Improved logging messages\n\nNote: Running docker in GitHub Actions is the correct\n[…]\nd starting service\ncontainers manually is a documented pattern when you need to override\nthe container command. The 'options' field in services only supports\ndocker run options, not command arguments.",
          "is_bot": false,
          "headline": "Improve MinIO startup with healthcheck and timeout",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T15:36:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4d08ff352e8e3a2df89d3baa5067e3f852e6b64e",
          "body": "GitHub Actions services don't support overriding the container command,\nwhich caused MinIO to show help text instead of starting the server.\n\nSolution:\n- Removed MinIO from services section\n- Added 'Start MinIO' step that runs the container with explicit command\n- Uses 'server /data --address :9000'\n[…]\nUSER/MINIO_ROOT_PASSWORD (current env vars)\n- Includes health check loop to wait for MinIO to be ready\n\nThis matches the docker-compose setup where MinIO is started with\n'command: minio server /data'.",
          "is_bot": false,
          "headline": "Fix: Start MinIO manually instead of as a service",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T15:28:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e601f9e8f9b09c94290e856bc99e8d1673490701",
          "body": "Added initialization steps to both CI workflows to match the bootstrap\nprocess from docker-compose:\n\n1. MinIO bucket creation:\n   - Wait for MinIO to be ready using health check endpoint\n   - Install MinIO client (mc)\n   - Configure client with credentials\n   - Create 'queridodiariobucket' if it doe\n[…]\nACHE_TIKA_SERVER vars\n   - Ensures tests have all required configuration\n\nThese steps ensure the test environment is fully initialized before\nrunning tests, matching the local docker-compose behavior.",
          "is_bot": false,
          "headline": "Add bootstrap steps for MinIO and OpenSearch in CI",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T15:12:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4ee65365834dfb50881f0fc1305e3a8e2cb9cbd8",
          "body": "Changed from 'unittest tests' to 'unittest discover -s tests -p \"*.py\"'\nto avoid importing tests/__init__.py which triggers all module imports\nand can cause the test run to hang if dependencies fail to load.\n\nThis matches the pattern used in lint_and_unit.yaml which works correctly.",
          "is_bot": false,
          "headline": "Fix: Use unittest discover instead of importing tests package",
          "author_name": "Diego Rabatone Oliveira",
          "author_login": "diraol",
          "committed_at": "2025-11-15T15:09:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 20,
      "commits_last_year": 135,
      "latest_release_at": "2024-10-20T22:04:41Z",
      "latest_release_tag": "v0.13.3",
      "releases_from_tags": true,
      "days_since_last_push": 6,
      "active_weeks_last_year": 11,
      "days_since_latest_release": 642,
      "mean_days_between_releases": 47
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 75,
      "has_issue_template": false,
      "has_code_of_conduct": true,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 21,
      "stars": 29,
      "watchers": 10,
      "fork_history": {
        "days": [
          {
            "date": "2020-10-08",
            "count": 1
          },
          {
            "date": "2020-10-21",
            "count": 1
          },
          {
            "date": "2021-03-05",
            "count": 1
          },
          {
            "date": "2021-04-14",
            "count": 1
          },
          {
            "date": "2021-09-14",
            "count": 1
          },
          {
            "date": "2022-08-26",
            "count": 1
          },
          {
            "date": "2022-11-03",
            "count": 1
          },
          {
            "date": "2023-05-25",
            "count": 1
          },
          {
            "date": "2023-09-17",
            "count": 1
          },
          {
            "date": "2023-09-18",
            "count": 1
          },
          {
            "date": "2023-10-09",
            "count": 1
          },
          {
            "date": "2023-11-11",
            "count": 1
          },
          {
            "date": "2023-12-01",
            "count": 1
          },
          {
            "date": "2023-12-12",
            "count": 1
          },
          {
            "date": "2024-03-18",
            "count": 1
          },
          {
            "date": "2024-03-20",
            "count": 1
          },
          {
            "date": "2024-05-24",
            "count": 1
          },
          {
            "date": "2025-07-27",
            "count": 1
          },
          {
            "date": "2026-04-19",
            "count": 1
          },
          {
            "date": "2026-06-29",
            "count": 1
          },
          {
            "date": "2026-07-12",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 21,
        "total_forks": 21
      },
      "star_history": null,
      "open_issues_and_prs": 56
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "Makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 16063,
      "source_files_sampled": 53,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "requirements-dev.txt",
        "requirements.txt"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 8,
        "merged_prs": 49,
        "open_issues": 48,
        "closed_ratio": 0.226,
        "closed_issues": 14,
        "closed_unmerged_prs": 4
      },
      "bus_factor": 2,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "diraol",
          "commits": 127,
          "avatar_url": "https://avatars.githubusercontent.com/u/192702?v=4"
        },
        {
          "type": "User",
          "login": "ogecece",
          "commits": 64,
          "avatar_url": "https://avatars.githubusercontent.com/u/26327506?v=4"
        },
        {
          "type": "User",
          "login": "jvanz",
          "commits": 40,
          "avatar_url": "https://avatars.githubusercontent.com/u/1514798?v=4"
        },
        {
          "type": "User",
          "login": "csafurtado",
          "commits": 10,
          "avatar_url": "https://avatars.githubusercontent.com/u/77639735?v=4"
        },
        {
          "type": "User",
          "login": "retpolanne",
          "commits": 8,
          "avatar_url": "https://avatars.githubusercontent.com/u/7549205?v=4"
        },
        {
          "type": "User",
          "login": "Jefersonalves",
          "commits": 4,
          "avatar_url": "https://avatars.githubusercontent.com/u/12171286?v=4"
        },
        {
          "type": "User",
          "login": "wildemberg-sales",
          "commits": 4,
          "avatar_url": "https://avatars.githubusercontent.com/u/92035272?v=4"
        },
        {
          "type": "User",
          "login": "andreformento",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/5116933?v=4"
        },
        {
          "type": "User",
          "login": "trevineju",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/44185775?v=4"
        },
        {
          "type": "User",
          "login": "ArthurFerreiraRodrigues",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/69909375?v=4"
        }
      ],
      "contributors_sampled": 12,
      "top_contributor_share": 0.474
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "build_apache_tika.yaml",
        "build_base_image.yaml",
        "build_container_image.yaml",
        "lint_and_unit.yaml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": true
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "5 out of 5 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/9 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 17 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 5,
            "reason": "dependency not pinned by hash detected -- score normalized to 5",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "c3069787ef4c5c3b5a7469d2d531f3f871b4aa7a",
        "ran_at": "2026-07-25T21:27:17Z",
        "aggregate_score": 4.1,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-19T03:13:30Z",
      "oldest_open_prs": [
        {
          "number": 29,
          "created_at": "2022-08-26T15:58:56Z",
          "last_comment_at": "2023-03-13T22:35:32Z",
          "last_comment_author": "trevineju"
        },
        {
          "number": 31,
          "created_at": "2023-02-21T19:01:21Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 39,
          "created_at": "2023-09-13T20:02:33Z",
          "last_comment_at": "2023-11-30T19:29:41Z",
          "last_comment_author": "Luisa-Coelho"
        },
        {
          "number": 49,
          "created_at": "2023-10-14T12:23:35Z",
          "last_comment_at": "2023-10-20T21:24:05Z",
          "last_comment_author": "Luisa-Coelho"
        },
        {
          "number": 68,
          "created_at": "2023-12-30T03:14:30Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 69,
          "created_at": "2023-12-30T03:35:43Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 70,
          "created_at": "2024-03-15T02:08:35Z",
          "last_comment_at": "2024-04-15T21:17:15Z",
          "last_comment_author": "jvanz"
        },
        {
          "number": 126,
          "created_at": "2026-07-12T20:12:33Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-04-14T03:45:42Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 1,
          "created_at": "2020-10-05T22:26:36Z",
          "last_comment_at": "2020-10-11T04:34:19Z",
          "last_comment_author": "ogecece"
        },
        {
          "number": 2,
          "created_at": "2020-10-10T15:48:02Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 7,
          "created_at": "2020-11-21T23:32:25Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 10,
          "created_at": "2020-12-03T02:09:57Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 11,
          "created_at": "2020-12-07T21:31:40Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 21,
          "created_at": "2021-05-07T18:24:38Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 24,
          "created_at": "2021-07-08T03:02:04Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 25,
          "created_at": "2021-09-14T20:24:40Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 35,
          "created_at": "2023-08-19T16:07:28Z",
          "last_comment_at": "2023-08-22T16:42:52Z",
          "last_comment_author": "ogecece"
        },
        {
          "number": 36,
          "created_at": "2023-09-01T18:21:16Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 37,
          "created_at": "2023-09-01T18:23:17Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 38,
          "created_at": "2023-09-01T18:23:20Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 41,
          "created_at": "2023-09-17T14:58:30Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 42,
          "created_at": "2023-09-17T15:04:36Z",
          "last_comment_at": "2023-10-14T12:24:44Z",
          "last_comment_author": "Luisa-Coelho"
        },
        {
          "number": 45,
          "created_at": "2023-10-01T15:58:16Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 46,
          "created_at": "2023-10-01T16:02:48Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 47,
          "created_at": "2023-10-03T23:31:25Z",
          "last_comment_at": "2023-10-04T14:51:15Z",
          "last_comment_author": "ogecece"
        },
        {
          "number": 50,
          "created_at": "2023-10-14T19:29:21Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 51,
          "created_at": "2023-10-14T19:32:48Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 52,
          "created_at": "2023-10-14T19:46:17Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/okfn-brasil/querido-diario-data-processing",
    "host": "github.com",
    "name": "querido-diario-data-processing",
    "owner": "okfn-brasil"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "good",
      "name": "Overall health",
      "note": "The weighted overall 62 is calibrated to 69 on the published index scale (record calibration 2026-08-02).",
      "notes": [
        {
          "code": "overall_calibration",
          "params": {
            "raw": 62,
            "calibrated": 69,
            "calibration": "2026-08-02"
          }
        }
      ],
      "value": 69,
      "inputs": {
        "security": 41,
        "vitality": 56,
        "community": 61,
        "governance": 59,
        "calibration": "2026-08-02",
        "engineering": 90,
        "ai_readiness": 60,
        "weighted_overall_raw": 62
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "moderate",
        "name": "Vitality",
        "value": 56,
        "weight": 0.21,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 62,
            "inputs": {
              "commits_last_year": 135,
              "human_commit_share": 1,
              "days_since_last_push": 6,
              "active_weeks_last_year": 11
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 6 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "11/52 weeks with commits",
                "points": 7.6,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 11
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "135 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 135
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "weak",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 48,
            "inputs": {
              "releases_count": 20,
              "latest_release_tag": "v0.13.3",
              "releases_from_tags": true,
              "days_since_latest_release": 642,
              "mean_days_between_releases": 47
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "20 version tags (no GitHub releases)",
                "points": 16.2,
                "status": "partial",
                "details": [
                  {
                    "code": "version_tags_no_releases",
                    "params": {
                      "count": 20
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 642 days ago",
                "points": 7.2,
                "status": "partial",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 642
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~47 days",
                "points": 19.8,
                "status": "partial",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 47
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "exceptional",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 16,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 16 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 16
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "moderate",
        "name": "Community & Adoption",
        "value": 61,
        "weight": 0.17,
        "metrics": [
          {
            "key": "popularity",
            "band": "weak",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "forks": 21,
              "stars": 29,
              "watchers": 10,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "29 stars",
                "points": 23.5,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 29
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "21 forks",
                "points": 10.8,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 21
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "10 watchers",
                "points": 5.3,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 10
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "excellent",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "readme_badges": null,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": true,
              "readme_badge_services": [],
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 13.5,
                "status": "met",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 59,
        "weight": 0.23,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "moderate",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 60,
            "inputs": {
              "bus_factor": 2,
              "contributors_sampled": 12,
              "top_contributor_share": 0.474
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "2 contributor(s) cover half of all commits",
                "points": 25.2,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 47% of commits",
                "points": 11.8,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 47
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "12 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 12
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 17 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "weak",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Newcomer PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "newcomer_pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 43,
            "inputs": {
              "merged_prs": 49,
              "open_issues": 48,
              "closed_issues": 14,
              "prs_merged_7d": null,
              "prs_decided_7d": null,
              "prs_merged_30d": null,
              "prs_decided_30d": null,
              "issue_closed_ratio": 0.226,
              "closed_unmerged_prs": 4,
              "first_time_authors_30d": null,
              "first_time_prs_merged_30d": null,
              "first_time_prs_decided_30d": null
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "23% of issues closed",
                "points": 9.5,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 23
                    }
                  }
                ],
                "max_points": 42
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "49/53 decided PRs merged",
                "points": 27.7,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 49,
                      "decided": 53
                    }
                  }
                ],
                "max_points": 30
              },
              {
                "key": "newcomer_pr_acceptance",
                "name": "Newcomer PR acceptance",
                "detail": "no first-time contributor's PR decided in 30d",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_newcomer_prs",
                    "params": {
                      "days": 30
                    }
                  }
                ],
                "max_points": 13
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/9 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "good",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "followers": 546,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "okfn-brasil",
              "public_repos": 119,
              "account_age_days": 5208
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "546 followers of okfn-brasil",
                "points": 19.7,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 546,
                      "login": "okfn-brasil"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "119 public repos, account ~14 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 119
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 14
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "excellent",
        "name": "Engineering Quality",
        "value": 90,
        "weight": 0.19,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "exceptional",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 94,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": true
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "4 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 16,
                "status": "met",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 9.6,
                "status": "met",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "5 out of 5 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "topics": [
                "python",
                "sql",
                "data-processing",
                "pipelines",
                "hacktoberfest",
                "opensearch"
              ],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": "6 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 6
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "weak",
        "name": "Security",
        "value": 41,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "weak",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 41,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 17,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 1,
              "scorecard_aggregate": 4.1
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "5 out of 5 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/9 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 17 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 5",
                "points": 2.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "exceptional",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "commit_weight_rule": {
                "min_commits": 50,
                "min_commit_share": 0.1
              },
              "review_only_matches": 0,
              "below_threshold_exposures": [],
              "assessed_self_published_locations": 23
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 60,
        "weight": 0.04,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "weak",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.9,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "90 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 90,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 76,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": true,
              "typed_language": false,
              "bootstrap_files": [
                "Makefile"
              ],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [],
              "agent_commit_share": 0.24,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Makefile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Makefile"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 11,
                "status": "met",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "24 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 24,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 5",
                "points": 5,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 16063,
              "source_files_sampled": 53,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/53 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 53,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? Carries a deliberately small weight: agent tooling is a real maintenance signal, but its absence must never gate the top of the scale (calibration saturates at raw 91, so 100/100 remains reachable with AI Readiness at zero)."
      }
    ],
    "classification": {
      "top": [],
      "labels": [],
      "scores": {},
      "primary": null,
      "evidence": [],
      "artifacts": [],
      "confidence": "none",
      "host_extension": false,
      "runs_as_process": false,
      "consumed_by_code": false
    },
    "metrics_version": "2.5.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-25T21:27:37.155881Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/o/okfn-brasil/querido-diario-data-processing.svg",
  "full_name": "okfn-brasil/querido-diario-data-processing",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Las puntuaciones son señales, no garantías. Reflejan prácticas públicamente visibles en GitHub; no son una auditoría de código ni una garantía de seguridad.

Los datos ausentes se excluyen y los pesos se renormalizan; nunca se puntúan como cero. La metodología es versionada y abierta: métricas v2.5.0, esquema v0.27.0 — metodología completa · wiki de métricas.

Cómo se sitúa un resultado dentro del registro general: estadísticas agregadas.