公开记录
软件健康报告模式 0.27.0 · 指标 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 星标⑂ 21 复刻始于 2020年10月在 GitHub 上查看 ↗

okfn-brasil/querido-diario-data-processing 的健康指数为 100 分中的 69 分,处于「良好」区间。 其得分最高的类别是Engineering Quality(90/100),最低的是Security(41/100)。 最近一次更新在 6 天前。 近期的大部分工作由 2 位贡献者完成。

69
总分 / 100
良好

软件健康指数

指标归入加权类别,统一采用 1–100 量表。总体分先取类别加权平均,再依据公开记录的分布进行校准,使各等级具有百分位含义;当公开证据触发高风险司法辖区政策时,评级会按政策调整,并设置 34(存在风险)的上限。

69
卓越93-100公开记录中的最高层级(约前 5%);基本满足所有检验标准
优秀80-92各方面均表现强劲;仅有少量不足
良好65-79健康;不足之处有限且可控
中等50-64可接受,但存在明显不足;建议进行审查
薄弱35-49多个领域存在实质性薄弱环节
存在风险20-34存在重大薄弱环节;采用时应保持审慎
危急1-19问题严重(项目被弃置、仅有单一维护者、缺乏基本工程规范)
活力社区与采用可持续性与治理工程质量安全AI 就绪度

评分画像

每条轴代表一个类别。形状比平均值更重要——健康的对象会填满整个图形,而“一峰一谷”式画像意味着某一维度的优势正掩盖另一维度的风险。

加权总体分 62 经校准后在公布的指数量表上为 69(记录校准 2026-08-02)。

所有权

546 关注者119 个公开仓库始于 2012年4月

该仓库由组织支持——共同承担、可问责的托管责任,可延续于任何单一维护者之后。

按类别列示的指标

活力

项目是否仍有生命——是否仍在编写代码,是否仍在发布版本?

56中等 · 占总体的 21%
评分方式
36/36推送新近度 — 最近一次推送于 6 天前
7.6/36提交节奏 — 52 周中有 11 周有提交
18/18提交量 — 最近一年 135 次提交
0/10OpenSSF Scorecard:Maintained — 1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
所用输入
commits_last_year135
human_commit_share1
days_since_last_push6
active_weeks_last_year11

发布纪律

48薄弱
评分方式
16.2/27有发布版本 — 20 个版本标签(无 GitHub 发布版本)
7.2/36发布时效 — 最近一次发布版本于 642 天前
19.8/27发布节奏 — 约每 47 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — 无数据
所用输入
releases_count20
latest_release_tagv0.13.3
releases_from_tags
days_since_latest_release642
mean_days_between_releases47
已排除计分(无数据或不适用):OpenSSF Scorecard:Signed-Releases。 其余权重已重新归一化。

社区与采用

项目是否拥有用户、下载量与关注度,并具备欢迎贡献者参与的配置?

61中等 · 占总体的 17%
评分方式
23.5/60星标 — 29 个星标
10.8/25复刻 — 21 个复刻
5.3/15关注者 — 10 位关注者
所用输入
forks21
stars29
watchers10
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history

社区健康

85优秀
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(MIT)
18/18CONTRIBUTING 指南
13.5/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
readme_badges
has_contributing
has_issue_template
has_code_of_conduct
readme_badge_services
has_pull_request_template

可持续性与治理

项目能否在其成员之外延续——巴士系数、响应能力、由谁支持,以及软件包的维护状况?

59中等 · 占总体的 23%
评分方式
25.2/54巴士系数 — 2 位贡献者贡献了半数提交
11.8/22.5提交分布 — 头号贡献者编写了 47% 的提交
13.5/13.5贡献者广度 — 12 位贡献者
10/10OpenSSF Scorecard:Contributors — project has 17 contributing companies or organizations
所用输入
bus_factor2
contributors_sampled12
top_contributor_share0.474
评分方式
9.5/42议题解决 — 23% 的议题已关闭
27.7/30PR 接受 — 已裁定的 PR 中 49/53 已合并
0/13Newcomer PR acceptance — 30 天内没有首次贡献者的 PR 得到裁决
0/15OpenSSF Scorecard:Code-Review — Found 0/9 approved changesets -- score normalized to 0
所用输入
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
已排除计分(无数据或不适用):newcomer_pr_acceptance。 其余权重已重新归一化。
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
19.7/25所有者影响力 — okfn-brasil 有 546 位关注者
25/25既往记录 — 119 个公开仓库,账户约 14 年
所用输入
followers546
owner_typeOrganization
is_verified
owner_loginokfn-brasil
public_repos119
account_age_days5,208

工程质量

基础的工程与文档实践是否到位?

90优秀 · 占总体的 19%

工程实践

94卓越
评分方式
24/24CI 工作流 — 4 个工作流
24/24存在测试
16/16Linter 配置
9.6/9.6Pre-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
所用输入
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_config

文档

85优秀
评分方式
30/30README
25/25文档目录
0/15文档 / 主页站点
10/10仓库描述
10/10主题标签 — 6 个主题标签
10/10Wiki
所用输入
topicspython, sql, data-processing, pipelines, hacktoberfest, opensearch
has_wiki
homepage
has_readme
has_docs_dir
has_description

安全

可见的安全与供应链实践是否稳固,且不存在未解决的高风险司法辖区暴露?

41薄弱 · 占总体的 16%

安全态势

41薄弱
评分方式
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.5许可证 — 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 — 无数据
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
所用输入
sourceopenssf_scorecard
checks_evaluated17
scorecard_versionv5.5.0
checks_inconclusive1
scorecard_aggregate4.1
已排除计分(无数据或不适用):signed_releases。 其余权重已重新归一化。

AI 就绪度

该仓库在多大程度上具备与 AI 编码代理协同开发与维护的条件?权重刻意设小(4%):代理工具链是一项真实的维护信号,但完全不具备的仓库仍可达到 100/100。

60中等 · 占总体的 4%
评分方式
0/45代理指令 — 没有 CLAUDE.md / AGENTS.md / 编辑器规则
0/15机器可读文档(llms.txt)
40/40可读的提交历史 — 100 次人类提交中有 90 次说明了意图(结构化标题或解释性正文)
所用输入
has_llms_txt
legible_history_share0.9
agent_instruction_files
agent_instruction_max_bytes
评分方式
18/18一条命令的引导启动 — Makefile
22/22自动化测试
11/11Lint / 格式化配置
0/11静态类型检查
10/10可复现环境 — Dockerfile
10/10已体现的代理实践 — 最近 100 次提交中有 24 次由代理编写或署名代理
0/8自动化维护 — 未观察到自动依赖更新
5/10OpenSSF Scorecard:Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 5
所用输入
has_nix
has_tests
lockfiles
has_dockerfile
typed_language
bootstrap_filesMakefile
has_devcontainer
has_linter_config
typecheck_configs
agent_commit_share0.24
toolchain_manifests
dependency_bot_commit_share0
评分方式
0/45可类型检查的代码 — Python,未配置类型检查
55/55可控的文件大小 — 采样的 53 个源文件中有 0 个超过 60KB
所用输入
primary_languagePython
largest_source_bytes16,063
source_files_sampled53
oversized_source_files0

关键数据

29GitHub 星标
12贡献者
135最近 12 个月提交数
6距最近推送天数
20发布版本数
2巴士系数(bus factor)
48开放议题
PyPI软件包生态系统数

数据采集警告

  • 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

更多细节

Star 与 Fork 历史 0 ★ / 21 ⇿
0Star
21Fork
20发布

每颗 star 和每个 fork 的添加时间,来自 GitHub 并按天汇总。累计增长位于其构成来源——每日新增——的正上方,二者可相互对照:稳定的自然增长与短暂的突增形态截然不同。当这一差别可被衡量时,它会作为增长真实性予以报告。

048121620242122020-102023-082026-07
主版本 0次版本 5修订 15

每个点涵盖 6 天。

OpenSSF Scorecard 4.1 / 10
4.1综合

来自开源项目 OpenSSF Scorecard 的独立、工具无关的安全评估。每项检查奖励的是安全实践本身,而非特定供应商的工具。Scorecard 无法判定的检查项标记为 不适用,并从安全评分中剔除(绝不按零分计)。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
不适用Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
全部依赖 未采集

本报告未能采集到解析后的依赖集合:GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

原始 JSON 报告 机器可读
{
  "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"
}

评分是信号,而非担保。 评分反映的是 GitHub 上公开可见的实践——不是代码审计,也不是安全保证。

缺失数据将被剔除并重新归一化权重,绝不按零分计。方法论已版本化并公开:指标 v2.5.0、模式 v0.27.0—— 完整方法论 · 指标知识库.

单项结果在整体记录中的位置: 汇总统计.