公开记录
软件健康报告模式 0.26.0 · 指标 1.13.0 · 2026-07-22 03:23 UTC

Wacom-Developer / personal-knowledge-library

Library for accessing personal knowledge service.

PythonApache-2.0★ 3 星标⑂ 0 复刻始于 2022年3月在 GitHub 上查看 ↗

Wacom-Developer/personal-knowledge-library 的健康指数为 100 分中的 56 分,处于「中等」区间。 其得分最高的类别是Vitality(81/100),最低的是Community & Adoption(26/100)。 最近一次更新在 11 天前。 近期的大部分工作由 1 位贡献者完成。

56
总分 / 100
中等

软件健康指数

指标归入加权类别,统一采用 1–100 量表。总体分先取类别加权平均;当公开证据触发高风险司法辖区政策时,评级会按政策调整,并设置 49(有风险)的上限。AI 就绪度不计入总体分。

56
优秀85-100堪称典范;基本满足所有检验标准
良好70-84健康;仅有轻微不足
中等50-69可接受,但存在明显不足;建议进行审查
存在风险30-49存在重大薄弱环节;采用时应保持审慎
危急1-29问题严重(项目被弃置、仅有单一维护者、缺乏基本工程规范)
活力社区与采用可持续性与治理工程质量安全AI 就绪度

评分画像

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

所有权

Wacom组织
79 关注者38 个公开仓库始于 2018年5月

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

软件包生态系统

注册表软件包版本月下载量版本数最近发布标签
PyPIpersonal_knowledge_library4.3.3-7611 天前semantic-knowledgeknowledge-graph

按类别列示的指标

活力

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

81良好 · 占总体的 22%
评分方式
28.8/36推送新近度 — 最近一次推送于 11 天前
12.5/36提交节奏 — 52 周中有 18 周有提交
18/18提交量 — 最近一年 204 次提交
10/10OpenSSF Scorecard:Maintained — 20 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
所用输入
commits_last_year204
human_commit_share1
days_since_last_push11
active_weeks_last_year18

发布纪律

100优秀
评分方式
27/27有发布版本 — 已发布 63 个发布版本
36/36发布时效 — 最近一次发布版本于 11 天前
27/27发布节奏 — 约每 24.3 天发布一次
0/10OpenSSF Scorecard:Signed-Releases — 无数据
所用输入
releases_count63
latest_release_tagv4.3.3
releases_from_tags
days_since_latest_release11
mean_days_between_releases24.3
已排除计分(无数据或不适用):OpenSSF Scorecard:Signed-Releases。 其余权重已重新归一化。

社区与采用

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

26危急 · 占总体的 18%
评分方式
4.9/60星标 — 3 个星标
0/25复刻 — 0 个复刻
0/15关注者 — 1 位关注者
所用输入
forks0
stars3
watchers1
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonbelow_threshold

社区健康

50中等
评分方式
22.5/22.5README
22.5/22.5许可证 — 可识别的许可证(Apache-2.0)
0/18CONTRIBUTING 指南
0/13.5行为准则
0/7.2议题模板
0/6.3PR 模板
所用输入
has_readme
has_license
has_contributing
has_issue_template
has_code_of_conduct
has_pull_request_template

可持续性与治理

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

42存在风险 · 占总体的 24%
评分方式
9/54巴士系数 — 1 位贡献者贡献了半数提交
0.2/22.5提交分布 — 头号贡献者编写了 99% 的提交
2.7/13.5贡献者广度 — 2 位贡献者
3/10OpenSSF Scorecard:Contributors — project has 1 contributing companies or organizations -- score normalized to 3
所用输入
bus_factor1
contributors_sampled2
top_contributor_share0.993
评分方式
0/46.8议题解决 — 没有议题或无数据
0/38.3PR 接受 — 没有已裁定的拉取请求或无数据
0/15OpenSSF Scorecard:Code-Review — Found 0/30 approved changesets -- score normalized to 0
所用输入
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
已排除计分(无数据或不适用):议题解决, PR 接受。 其余权重已重新归一化。
评分方式
30/30所有权背书 — 组织持有
0/20已验证域名
13.7/25所有者影响力 — Wacom-Developer 有 79 位关注者
23.6/25既往记录 — 38 个公开仓库,账户约 8 年
所用输入
followers79
owner_typeOrganization
is_verified
owner_loginWacom-Developer
public_repos38
account_age_days2,974
评分方式
25/25已发布且可解析 — pypi 上有 1 个软件包
35/35发布时效 — 最近一次发布于 11 天前
20/20版本历史 — 76 个已发布版本
20/20未被弃用 — 活跃,未被弃用或撤回
所用输入
packagespersonal_knowledge_library
ecosystemspypi
any_deprecated
min_days_since_publish11

工程质量

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

78良好 · 占总体的 20%

工程实践

80良好
评分方式
24/24CI 工作流 — 3 个工作流
24/24存在测试
16/16Linter 配置 — .pylintrc
0/9.6Pre-commit 钩子
0/6.4.editorconfig
0/20OpenSSF Scorecard:CI-Tests — 无数据
所用输入
has_ci
has_tests
has_editorconfig
has_linter_config
has_precommit_config
已排除计分(无数据或不适用):OpenSSF Scorecard:CI-Tests。 其余权重已重新归一化。

文档

75良好
评分方式
30/30README
25/25文档目录
0/15文档 / 主页站点
10/10仓库描述
10/10主题标签 — 3 个主题标签
0/10Wiki
所用输入
topicsknowledge-graph, wikidata, wikidata-api
has_wiki
homepage
has_readme
has_docs_dir
has_description

安全

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

52中等 · 占总体的 16%

安全态势

40存在风险
评分方式
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — 无数据
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
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
7.5/7.5Maintained — 20 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — 无数据
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — no SAST tool detected
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_evaluated15
scorecard_versionv5.5.0
checks_inconclusive3
scorecard_aggregate4
已排除计分(无数据或不适用):ci_tests, packaging, signed_releases。 其余权重已重新归一化。
评分方式
35/35直接依赖不含已知公告 — 没有直接依赖携带已知公告
25/25间接依赖不含已知公告 — 没有间接依赖携带已知公告
0/40没有长期未处理的公告 — 没有公告带有发布日期
所用输入
sourceosv
advisories0
affected_packages0
assessed_packages26
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
已排除计分(无数据或不适用):没有长期未处理的公告。 其余权重已重新归一化。 比对的是 pypi:personal_knowledge_library@4.3.3 的运行时依赖闭包——安装已发布的软件包时真正被拉取进来的内容——共 26 个软件包。 未对可达性进行分析。

AI 就绪度

该仓库在多大程度上具备与 AI 编码代理协同开发与维护的条件?这是一枚独立的实验性徽章——权重为 0.0,因此单独呈现,不影响总体健康评分。

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

机器可读接口

40存在风险
评分方式
0/40API 模式(OpenAPI/GraphQL/proto)
0/20MCP 服务器
40/40可运行示例 — samples
所用输入
example_dirssamples
has_mcp_signal
api_schema_files

关键数据

3GitHub 星标
2贡献者
204最近 12 个月提交数
11距最近推送天数
63发布版本数
1巴士系数(bus factor)
0开放议题
PyPI软件包生态系统数

更多细节

Star 与 Fork 历史 3 ★ / 0 ⇿
3Star
12发布

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

12233312025-032025-072025-11
主版本 1次版本 4修订 7
OpenSSF Scorecard 4.0 / 10
4.0综合

来自开源项目 OpenSSF Scorecard 的独立、工具无关的安全评估。每项检查奖励的是安全实践本身,而非特定供应商的工具。Scorecard 无法判定的检查项标记为 不适用,并从安全评分中剔除(绝不按零分计)。Scorecard v5.5.0 · 2026-07-22 03:23 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
不适用CI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained20 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
不适用Packagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTno SAST tool detected
0Security-Policysecurity policy file not detected
不适用Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
直接依赖 11
注册表软件包版本约束清单文件
PyPIaiohttp>3.13.3pyproject.toml
PyPIrequests(>=2.32.0, <3.0.0)pyproject.toml
PyPIPyJWT(>=2.10.1,<3.0.0)pyproject.toml
PyPItqdm>=4.65.0pyproject.toml
PyPIrdflib>=7.1.0pyproject.toml
PyPIorjson>=3.10.0pyproject.toml
PyPIcertifipyproject.toml
PyPIcachetools>=5.3.0pyproject.toml
PyPIloguru==0.7.3pyproject.toml
PyPIurllib3(>=2.6.3,<3.0.0)pyproject.toml
PyPItypes-requests(>=2.32.4.20260107,<3.0.0.0)pyproject.toml
全部依赖 87

来自 GitHub 依赖图的完整解析依赖集合:11 个直接依赖与 76 个间接(传递)软件包。仓库提交锁文件时,传递闭包才是完整的。

注册表软件包版本关系
PyPIaiohttp3.14.1直接
PyPIcachetools7.1.4直接
PyPIcertifi2026.6.17直接
PyPIloguru0.7.3直接
PyPIorjson3.11.9直接
PyPIpyjwt2.13.0直接
PyPIrdflib7.6.0直接
PyPIrequests2.34.2直接
PyPItqdm4.68.4直接
PyPItypes-requests2.33.0.20260518直接
PyPIurllib32.7.0直接
PyPIaiodns4.0.4间接
PyPIaiohappyeyeballs2.7.1间接
PyPIaiosignal1.4.0间接
PyPIast-serialize0.6.0间接
PyPIastroid4.0.4间接
PyPIasync-timeout5.0.1间接
PyPIattrs26.1.0间接
PyPIbackports-asyncio-runner1.2.0间接
PyPIbackports-zstd1.6.0间接
PyPIbitarray3.8.2间接
PyPIbitstring4.4.0间接
PyPIblack26.5.1间接
PyPIbrotli1.2.0间接
PyPIbrotlicffi1.2.0.1间接
PyPIcffi2.1.0间接
PyPIcharset-normalizer3.4.9间接
PyPIclick8.4.2间接
PyPIcolorama0.4.6间接
PyPIcoverage7.15.0间接
PyPIdill0.4.1间接
PyPIdistlib0.4.3间接
PyPIexceptiongroup1.3.1间接
PyPIfaker18.9.0间接
PyPIfilelock3.29.7间接
PyPIflake87.3.0间接
PyPIfrozenlist1.8.0间接
PyPIidna3.18间接
PyPIiniconfig2.3.0间接
PyPIisodate0.7.2间接
PyPIisort8.0.1间接
PyPIlibrt0.13.0间接
PyPIlxml6.1.1间接
PyPImako1.3.12间接
PyPImarkdown3.10.2间接
PyPImarkupsafe3.0.3间接
PyPImccabe0.7.0间接
PyPImultidict6.7.1间接
PyPImypy2.2.0间接
PyPImypy-extensions1.1.0间接
PyPInumpy2.2.6间接
PyPIpackaging26.2间接
PyPIpathspec1.1.1间接
PyPIpdoc30.11.6间接
PyPIplatformdirs4.10.0间接
PyPIpluggy1.6.0间接
PyPIpropcache0.5.2间接
PyPIprotobuf3.20.3间接
PyPIpycares5.0.1间接
PyPIpycodestyle2.14.0间接
PyPIpycparser3.0间接
PyPIpyflakes3.4.0间接
PyPIpygments2.20.0间接
PyPIpylint4.0.6间接
PyPIpyparsing3.3.2间接
PyPIpyproject-api1.10.1间接
PyPIpytest9.1.1间接
PyPIpytest-asyncio1.4.0间接
PyPIpytest-cov7.1.0间接
PyPIpytest-env1.6.0间接
PyPIpytest-mock3.15.1间接
PyPIpython-dateutil2.9.0间接
PyPIpython-discovery1.4.4间接
PyPIpython-dotenv1.2.2间接
PyPIpytokens0.4.1间接
PyPIsix1.17.0间接
PyPItibs0.5.7间接
PyPItomli2.4.1间接
PyPItomli-w1.2.0间接
PyPItomlkit0.15.0间接
PyPItox4.56.4间接
PyPItyping-extensions4.16.0间接
PyPIuniversal-ink-library2.1.1间接
PyPIvarint1.0.2间接
PyPIvirtualenv21.6.0间接
PyPIwin32-setctime1.2.0间接
PyPIyarl1.24.2间接
依赖安全公告 0

安装 pypi:personal_knowledge_library@4.3.3 会引入 26 个包(直接与传递):其中 0 个存在已知公告,0 个为直接依赖。

没有已知公告影响已评估的依赖。

公告表示依赖图中记录的版本落入某条公告的受影响范围。可达性未经分析,且依赖图包含开发与测试的版本固定——某项发现可能只涉及工具链而非交付的软件。

原始 JSON 报告 机器可读
{
  "data": {
    "repo": {
      "topics": [
        "knowledge-graph",
        "wikidata",
        "wikidata-api"
      ],
      "is_fork": false,
      "size_kb": 6407,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "Python": 1264205
      },
      "pushed_at": "2026-07-10T05:45:32Z",
      "created_at": "2022-03-25T11:07:33Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-10T05:44:21Z",
      "description": "Library for accessing personal knowledge service.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "Apache-2.0",
      "default_branch": "main",
      "license_spdx_raw": "Apache-2.0",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": "https://developer.wacom.com/",
      "name": "Wacom",
      "type": "Organization",
      "login": "Wacom-Developer",
      "company": null,
      "location": null,
      "followers": 79,
      "avatar_url": "https://avatars.githubusercontent.com/u/39760899?v=4",
      "created_at": "2018-05-30T08:35:19Z",
      "is_verified": null,
      "public_repos": 38,
      "account_age_days": 2974
    },
    "license": {
      "state": "standard",
      "spdx_id": "Apache-2.0",
      "raw_spdx": "Apache-2.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v4.3.3",
          "kind": "patch",
          "published_at": "2026-07-10T05:45:32Z"
        },
        {
          "tag": "v4.3.2",
          "kind": "patch",
          "published_at": "2026-07-01T07:28:17Z"
        },
        {
          "tag": "v4.3.1",
          "kind": "patch",
          "published_at": "2026-05-04T11:25:41Z"
        },
        {
          "tag": "v4.3.0",
          "kind": "minor",
          "published_at": "2026-04-13T19:52:40Z"
        },
        {
          "tag": "v4.2.2",
          "kind": "patch",
          "published_at": "2026-02-23T11:11:52Z"
        },
        {
          "tag": "v4.2.1",
          "kind": "patch",
          "published_at": "2026-02-23T07:34:25Z"
        },
        {
          "tag": "v4.2.0",
          "kind": "minor",
          "published_at": "2026-02-20T15:37:16Z"
        },
        {
          "tag": "v4.1.0",
          "kind": "minor",
          "published_at": "2026-02-06T22:08:35Z"
        },
        {
          "tag": "v4.0.4",
          "kind": "patch",
          "published_at": "2026-01-22T00:52:34Z"
        },
        {
          "tag": "v4.0.3",
          "kind": "patch",
          "published_at": "2025-12-03T18:24:29Z"
        },
        {
          "tag": "v4.0.1",
          "kind": "patch",
          "published_at": "2025-11-27T09:56:37Z"
        },
        {
          "tag": "v3.5.0",
          "kind": "minor",
          "published_at": "2025-11-07T05:03:48Z"
        },
        {
          "tag": "3.4.0",
          "kind": "minor",
          "published_at": "2025-10-24T18:50:05Z"
        },
        {
          "tag": "v3.3.2",
          "kind": "patch",
          "published_at": "2025-09-19T10:05:03Z"
        },
        {
          "tag": "v3.3.1",
          "kind": "patch",
          "published_at": "2025-09-18T07:18:44Z"
        },
        {
          "tag": "v3.3.0",
          "kind": "minor",
          "published_at": "2025-09-17T18:46:41Z"
        },
        {
          "tag": "v3.2.2",
          "kind": "patch",
          "published_at": "2025-07-03T13:59:33Z"
        },
        {
          "tag": "v3.2.1",
          "kind": "patch",
          "published_at": "2025-06-04T10:33:07Z"
        },
        {
          "tag": "v3.2.0",
          "kind": "minor",
          "published_at": "2025-05-07T19:52:25Z"
        },
        {
          "tag": "v3.1.2",
          "kind": "patch",
          "published_at": "2025-04-04T13:05:15Z"
        },
        {
          "tag": "v3.1.1",
          "kind": "patch",
          "published_at": "2025-03-20T21:10:49Z"
        },
        {
          "tag": "v3.0.0",
          "kind": "major",
          "published_at": "2025-03-19T12:24:10Z"
        },
        {
          "tag": "v2.5.0",
          "kind": "minor",
          "published_at": "2025-01-22T19:27:29Z"
        },
        {
          "tag": "v2.4.3",
          "kind": "patch",
          "published_at": "2024-12-17T07:39:39Z"
        },
        {
          "tag": "v2.4.2",
          "kind": "patch",
          "published_at": "2024-12-09T14:29:29Z"
        },
        {
          "tag": "v2.4.1",
          "kind": "patch",
          "published_at": "2024-11-26T11:14:38Z"
        },
        {
          "tag": "v2.4.0",
          "kind": "minor",
          "published_at": "2024-10-24T10:09:05Z"
        },
        {
          "tag": "v2.3.0",
          "kind": "minor",
          "published_at": "2024-10-10T12:09:10Z"
        },
        {
          "tag": "v2.1.6",
          "kind": "patch",
          "published_at": "2024-09-02T20:13:32Z"
        },
        {
          "tag": "v2.1.5",
          "kind": "patch",
          "published_at": "2024-06-12T11:14:26Z"
        },
        {
          "tag": "v2.1.4",
          "kind": "patch",
          "published_at": "2024-05-31T09:40:14Z"
        },
        {
          "tag": "v2.1.3",
          "kind": "patch",
          "published_at": "2024-04-08T09:17:15Z"
        },
        {
          "tag": "v2.1.2",
          "kind": "patch",
          "published_at": "2024-02-27T05:13:22Z"
        },
        {
          "tag": "v2.1.1",
          "kind": "patch",
          "published_at": "2024-02-15T09:51:07Z"
        },
        {
          "tag": "v2.1.0",
          "kind": "minor",
          "published_at": "2024-02-13T18:16:09Z"
        },
        {
          "tag": "v2.0.3",
          "kind": "patch",
          "published_at": "2024-01-18T12:35:10Z"
        },
        {
          "tag": "v2.0.2",
          "kind": "patch",
          "published_at": "2024-01-11T07:02:32Z"
        },
        {
          "tag": "v2.0.1",
          "kind": "patch",
          "published_at": "2024-01-09T21:31:50Z"
        },
        {
          "tag": "v2.0.0",
          "kind": "major",
          "published_at": "2024-01-09T20:52:19Z"
        },
        {
          "tag": "v1.0.8",
          "kind": "patch",
          "published_at": "2023-07-15T17:21:10Z"
        },
        {
          "tag": "v1.0.7",
          "kind": "patch",
          "published_at": "2023-07-13T08:30:18Z"
        },
        {
          "tag": "v1.0.6",
          "kind": "patch",
          "published_at": "2023-07-04T15:08:34Z"
        },
        {
          "tag": "v1.0.5",
          "kind": "patch",
          "published_at": "2023-07-03T14:39:37Z"
        },
        {
          "tag": "v1.0.4",
          "kind": "patch",
          "published_at": "2023-06-26T07:14:00Z"
        },
        {
          "tag": "v1.0.3",
          "kind": "patch",
          "published_at": "2023-06-18T18:20:14Z"
        },
        {
          "tag": "v.1.0.2",
          "kind": "other",
          "published_at": "2023-06-16T10:48:29Z"
        },
        {
          "tag": "v1.0.1",
          "kind": "patch",
          "published_at": "2023-06-15T16:07:57Z"
        },
        {
          "tag": "v0.9.6",
          "kind": "patch",
          "published_at": "2023-05-23T09:26:52Z"
        },
        {
          "tag": "v0.9.5",
          "kind": "patch",
          "published_at": "2023-04-26T14:52:40Z"
        },
        {
          "tag": "v0.9.4",
          "kind": "patch",
          "published_at": "2023-03-24T09:04:16Z"
        },
        {
          "tag": "v0.9.3",
          "kind": "patch",
          "published_at": "2023-02-23T16:46:38Z"
        },
        {
          "tag": "v0.9.2",
          "kind": "patch",
          "published_at": "2023-01-11T07:47:18Z"
        },
        {
          "tag": "v0.9.1",
          "kind": "patch",
          "published_at": "2022-11-30T21:44:49Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2022-11-23T18:30:32Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2022-11-19T16:32:25Z"
        },
        {
          "tag": "v0.7.1",
          "kind": "patch",
          "published_at": "2022-10-28T13:10:30Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2022-10-26T16:25:52Z"
        },
        {
          "tag": "v0.6.2",
          "kind": "patch",
          "published_at": "2022-09-20T09:33:51Z"
        },
        {
          "tag": "v0.6.1",
          "kind": "patch",
          "published_at": "2022-08-23T07:02:23Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2022-08-09T07:58:10Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2022-07-03T10:19:46Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2022-05-24T16:14:33Z"
        },
        {
          "tag": "v0.3.1",
          "kind": "patch",
          "published_at": "2022-03-31T15:53:21Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "f226502359e81cdedb9b125a30af5266fdf58bc9",
          "body": "Add unit test ensuring AsyncSession._request_content with raw=True returns exact bytes without JSON deserialization. Regression guard for content downloads whose stored MIME type is application/json.",
          "is_bot": false,
          "headline": "Add test for raw content download preservation",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-07-10T05:44:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "78effcef5aa151f20c2a30823100507d23ec804d",
          "body": "Fix AsyncContentClient.download_content corrupting file bodies with application/json MIME type. The async transport was deserializing JSON responses into dicts, causing download_content to return stringified dicts instead of raw bytes. Resolved by requesting raw bytes via a new raw_content transport flag for the download path. Includes regression guard in tests/test_content_download_raw.py.",
          "is_bot": false,
          "headline": "Release 4.3.3: fix async content download",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-07-10T05:43:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "88e0bb53bd03e540ec51daa9e85eb9d5cbfd2038",
          "body": "Add support for retrieving raw bytes from async requests without JSON decoding. This enables downloading binary content or files stored with JSON MIME types that would be corrupted by deserializing to a dict. The `raw_content` parameter can be passed to request methods, and is automatically set for content download operations.",
          "is_bot": false,
          "headline": "Add raw_content flag for binary downloads",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-07-10T05:43:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bd440ce0bb386d13734440fc599ad7313a350afb",
          "body": "Version bump to 4.3.2. Deprecates `knowledge.utils.wikidata` module with a `DeprecationWarning` — users should migrate to `knowledge.public.wikidata` or vendor helpers. Scheduled for removal in v5.0. Also fixes ontology mapping issue. Removes unused `__status__` export.",
          "is_bot": false,
          "headline": "Release v4.3.2: deprecate utils.wikidata",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-07-01T07:25:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f5dbfbab96993c027c73ce8555de6f9e2059b5fd",
          "body": "Add LanguageCode to the __all__ export list in knowledge/base/entity.py to make it available when importing from the entity module.",
          "is_bot": false,
          "headline": "Export LanguageCode from entity module",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-07-01T07:22:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e6ba00d2aa48d2e921f4e5435da97b583cd9b353",
          "body": "Convert subclass tuples to lists when building domain_subclasses to avoid a list+tuple TypeError. Also apply minor formatting and style cleanups across knowledge/ontomapping/__init__.py (reflowed comprehensions/signatures, inlined logger messages and string returns). No other behavioral changes intended.",
          "is_bot": false,
          "headline": "Fix list/tuple concat in ontomapping",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-07-01T07:21:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d05c6229d160d60b03724ebf7aa0f7a1885650e",
          "body": "Reformat code to comply with project's black style guide using 120-character line length. Joins multiline function calls and string concatenations where they fit within the limit, and adds proper spacing after module docstrings.",
          "is_bot": false,
          "headline": "Apply black formatting (line length 120)",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-07-01T07:18:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f77fbbfdf2d804ccfbd57b283388d2901b2c7c66",
          "body": "Add a new \"Choosing Between Sync and Async Clients\" section and a comprehensive Content API guide. The update explains when to use synchronous or asynchronous clients, the intentional retry asymmetry (sync clients include urllib3 retries; async clients do not), client availability, token reuse patte\n[…]\n MIME-type integrity, quotas/scanning, derived artifacts, and audit/audit trail guidance. Finally, update the README table of contents and correct the import script path to samples/import_entities.py.",
          "is_bot": false,
          "headline": "Document sync vs async clients and Content API",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-13T08:58:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e41adb887e04f4184e880258ae7578a9e68c5309",
          "body": "Add a required -s/--update-file CLI option and use it to replace stored content. The script now reads replacement_bytes from the supplied file path and passes the file's basename as the filename to update_content_file, replacing the previous hardcoded content and filename.",
          "is_bot": false,
          "headline": "Use provided file for content replacement",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-13T08:37:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f38c98416b3596852ba671d94cddee8db0632832",
          "body": "Change docstring text from \"Default: 10 seconds.\" to \"Default: 60 seconds.\" in knowledge/services/asyncio/graph.py for AsyncWacomKnowledgeService methods (two occurrences). This updates the documented default timeout value to reflect the new 60s setting.",
          "is_bot": false,
          "headline": "Update default timeout in docstrings to 60s",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-13T08:37:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3b790b44a9e8816c2c54da783a1e015698206604",
          "body": "Prevent bearer tokens from leaking into logs by adding a _SENSITIVE_HEADER_KEYS set and a _redact_sensitive_headers helper that masks sensitive header values (case-insensitive) with '***REDACTED***'. format_exception now uses this helper to redact headers before formatting; None/empty headers are left unchanged.",
          "is_bot": false,
          "headline": "Redact sensitive headers in exception formatting",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-13T08:36:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cab57fc62cdb5f4f8eda9abe0f11b22c3d15cc2d",
          "body": "Add an explicit except WacomServiceException clause in AsyncIndexManagementClient to re-raise the existing exception, avoiding re-wrapping and preserving the structured status_code and service_response from the inner exception during document streaming errors.",
          "is_bot": false,
          "headline": "Preserve WacomServiceException details",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-13T08:35:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ffd70bed60a421601c02ca722132f44627a26942",
          "body": "Mark knowledge.utils.wikidata as deprecated: add a module docstring and emit a DeprecationWarning on import, and remove it from knowledge.utils.__all__ and the package __init__ import so importing knowledge.utils no longer triggers the warning. Advises callers to migrate to knowledge.public.wikidata or vendor helpers, and notes removal planned for v5.0.",
          "is_bot": false,
          "headline": "Deprecate utils.wikidata; stop re-exporting it",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-13T08:32:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ae9b4601aeb956c5db5bf3e4a245ecb11739c06c",
          "body": "Document that AsyncServiceAPIClient intentionally does not install transport-level retries so callers can coordinate retries with circuit breakers, idempotency keys, request budgets and back-pressure. Also update close() to set self._session = None after closing so subsequent attempts fail fast rather than dispatching on a closed session.",
          "is_bot": false,
          "headline": "Add no-retry note and clear session on close",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-13T08:27:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "54a9ea52e88886da5a06926c3e5ca900f56b47a6",
          "body": "Corrects a typo in ThingObject docstring in knowledge/base/ontology.py where the default for `use_for_nel` was misspelled as 'Ture'. This is a documentation-only change and does not affect runtime behavior.",
          "is_bot": false,
          "headline": "Fix typo 'Ture' to 'True' in ontology docstring",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-13T08:26:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7b800c9f00584e16104b8e5a715aa5f02402f9af",
          "body": "Prepare and document the 4.3.1 release: update CHANGELOG with token-handling hardening, new session validation behaviors, added unit tests, and minor API notes; bump package version to 4.3.1 in knowledge/__init__.py and pyproject.toml; tighten aiohttp dependency to >3.13.3 in pyproject.toml.",
          "is_bot": false,
          "headline": "Release 4.3.1: bump version and changelog",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-04T11:22:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dec63f8662de334e6f62af5780ea5c29f78df9b2",
          "body": "Add comprehensive unit tests for knowledge.services.session (TokenManager, PermanentSession, TimedSession, RefreshableSession) to validate JWT claim handling, refresh-token semantics, external_user_id matching, and session update edge cases. Update tests/test_content_async.py: import hashlib, add UP\n[…]\nailable, and modify the verification test to compare SHA256 of the updated image. These changes tighten validation around token/session behavior and make async content tests more robust and realistic.",
          "is_bot": false,
          "headline": "Add session unit tests; adjust async content tests",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-04T11:15:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "df2af6e29b078650214a47d9cb67a20807dbbd83",
          "body": "Extract JWT decoding and required-claim checks into _decode_and_validate_token and add a constant of required claims. Signature verification is intentionally skipped since tokens are obtained from TLS-verified PKS API responses. Change refresh_token typing to Optional throughout (RefreshableSession \n[…]\nate external_user_id against the JWT in PermanentSession. Also import Tuple for typing and remove redundant storage of external_user_id; update TokenManager to pass the optional refresh_token through.",
          "is_bot": false,
          "headline": "Add JWT validation helper; optional refresh_token",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-04T11:02:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cc12084ef4a23d3210fedc0e1c8a8e1adcae285b",
          "body": "Expose an optional show_deleted parameter on list_content, download_content, and get_content_info for both sync and async Content clients. When provided the flag is added as a showDeleted query parameter (lowercased) to requests. Error handling calls now include the request parameters to surface context, and docstrings were updated to describe the new option.",
          "is_bot": false,
          "headline": "Add show_deleted flag to content endpoints",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-04T10:14:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba5c0cc0db54dd52ae9bc643b0d9325e83b8ed6b",
          "body": "Introduce activation(...) methods to WacomKnowledgeService and AsyncWacomKnowledgeService to call GET /entity/{uri}/activation. The methods build the request (supporting depth, optional auth_key and timeout), parse returned entities and relations into ThingObject maps and (subject, predicate, object\n[…]\neption on failure. Update tests/test_async_client.py to exercise the single-entity activation and assert it returns non-empty results and the same set of related URIs as the bulk activations endpoint.",
          "is_bot": false,
          "headline": "Add single-entity activation endpoint",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-05-04T09:54:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5adfd67396d4b73dc73c5b05b52814d45210eb94",
          "body": "Correct the inverted condition in __import_format_to_thing__ (knowledge/utils/import_format.py) so entity.image is converted to an absolute file:// URI only when the referenced path actually exists. Previously non-existent paths were being converted, which could produce invalid URIs and hide missing-file errors; now missing files follow the existing error handling (raise_on_error).",
          "is_bot": false,
          "headline": "Fix image path existence check",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-04-16T08:56:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8918dc5db903658a656d345d6ad41af199e1e2de",
          "body": "Bump 4.3.0 release date to 2026/04/13 and add a changelog line noting optimization for wikidata handling with caching to reflect recent improvements prepared for the 4.3.0 release.",
          "is_bot": false,
          "headline": "Update CHANGELOG: release date and caching note",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-04-13T19:50:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ef70fbaacbb647938e7bf63cba39a71492a4ac85",
          "body": "Introduce a persistent requests.Session with Retry/HTTPAdapter mounts to reuse connections and improve resilience for Wikidata SPARQL and search calls. Add lru_cache-backed helpers (_superclasses_cached, _subclasses_cached) to cache superclass/subclass query results (maxsize=256) and refactor superc\n[…]\ning/logging (JSON decode warnings, fetch warnings) and small formatting cleanup. These changes reduce network overhead, increase retry/backoff robustness, and improve performance for repeated queries.",
          "is_bot": false,
          "headline": "Persistent session and caching for Wikidata",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-04-13T19:46:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "acb1d608b89376071154cf02172ecac20794c9dc",
          "body": "Add LRU caching to subclasses_of (maxsize=512) and change its return type to an immutable tuple for safer recursion/concatenation. Introduce clear_subclasses_cache() and call it from register_ontology() so the cache is invalidated when a new ontology is loaded. Add tqdm progress bars to build_config\n[…]\nstruction. Also include minor typing, formatting and refactor cleanups (multiline signatures/strings, small type hints and local variable adjustments) and import additions (functools.lru_cache, tqdm).",
          "is_bot": false,
          "headline": "Cache subclasses_of and add build progress",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-04-13T19:45:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "98dd2481063a43d8b0288ef3f60de2b01b1e763b",
          "body": "Bump project version from 4.2.2 to 4.3.0 in pyproject.toml and add a 2026/04/07 RELEASE 4.3.0 entry to CHANGELOG.md noting the addition of clients for the Content API of the graph service.",
          "is_bot": false,
          "headline": "Bump version to 4.3.0 and update changelog",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-04-07T13:47:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a6ac8d1e6df956b3407dbc8efd73eda3fa415d82",
          "body": "Introduce samples/content_handling.py — a CLI sample demonstrating the full Content API lifecycle: create a Page entity, upload files, tag and annotate content, inspect and download items, replace files, handle multi-content, list and delete items, and clean up the entity. Includes usage, MIME handling, and example error handling for WacomKnowledgeService/ContentClient interactions.",
          "is_bot": false,
          "headline": "Add content_handling sample script",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-04-07T13:46:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c5f33a4571ce6c2796f1504b39c3c540f660e6cc",
          "body": "Add two new integration test suites for the content service: tests/test_content_async.py and tests/test_content_sync.py. Both suites exercise the full content lifecycle (create user → create Page entity → upload content → update tags/metadata → verify info/listing → replace/download file → delete co\n[…]\nncContentClient, AsyncWacomKnowledgeService and pytest-asyncio fixtures; sync tests use ContentClient and WacomKnowledgeService with a class-scoped cache and teardown that removes test users/entities.",
          "is_bot": false,
          "headline": "Add content integration tests (sync & async)",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-04-07T13:31:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f40de9aebd45879d6291ae19610f8d8fcba17bb6",
          "body": "Introduce synchronous and asynchronous Content API clients at knowledge/services/content.py and knowledge/services/asyncio/content.py. Both clients provide full CRUD operations for content items: upload, download, list, get info, update (metadata, tags, file, partial updates) and delete (single or a\n[…]\nServiceAPIClient/session abstractions. Responses are mapped to ContentObject and errors are handled via the existing service error helpers; default timeouts and auth_key override support are included.",
          "is_bot": false,
          "headline": "Add Content and AsyncContent clients",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-04-07T13:25:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "132c28a841ac9aaa776deff11853a1973e041af5",
          "body": "Introduce a new ContentObject model (knowledge/base/content.py) to represent content items linked to the knowledge graph. The class provides typed properties, a from_dict constructor that parses ISO timestamps (handles trailing Z as UTC), an is_deleted flag, and a readable __repr__. Also update knowledge/services/__init__.py to include \"content\" in the package exports so the new module is exposed.",
          "is_bot": false,
          "headline": "Add ContentObject model and export 'content'",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-04-07T13:24:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e24fc6b0a2fef4c48b766fbe0a35ff55bfdaa324",
          "body": "Add explicit teardown to close async HTTP clients to prevent unclosed connector warnings and resource leaks. Updated fixtures in tests/test_index_management.py (async_index_client), tests/test_ink_services_async.py (export_service), and tests/test_queue_management.py (async_queue_client) to await client.close(), user_management.close(), and export_svc.close() where appropriate.",
          "is_bot": false,
          "headline": "Close async HTTP clients in tests",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T11:10:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fb0f449fcad3be41dbb67e5df9fa07e29990e9d5",
          "body": "tests/test_diff.py: import DE_DE and use it for the German description (changed text to \"Beschreibung 2\"). Also correct the count assertions for description diffs so the file side is asserted as 2 and the kg side as 1. This fixes a wrong expectation and uses the locale constant instead of constructing LocaleCode(\"de_DE\").",
          "is_bot": false,
          "headline": "Fix description locale and assertion in tests",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T10:54:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4f5a77c3d503c73993d890117c0086cfd45388ae",
          "body": "Add pytest and pytest_asyncio imports and introduce an autouse, session-scoped async fixture (close_async_clients) that yields for tests and then closes module-level aiohttp clients (async_client, group_management, user_management, vector_search, queue_monitor). This ensures clients are properly closed after the test session to avoid resource warnings.",
          "is_bot": false,
          "headline": "Add session fixture to close async clients",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T10:50:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2e3c37dfd884b01620f4de1da6479ce49cbf14c8",
          "body": "Prepare release 4.2.2: update package version in pyproject.toml and knowledge.__init__.py, and add a changelog entry describing added checks for unsupported locales, a grammar fix in API documentation, and regenerated API docs.",
          "is_bot": false,
          "headline": "Bump version to 4.2.2 and update changelog",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T10:35:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "92486e5cdbf74fe88c58733dd444bd343afcb519",
          "body": "Clean up import_format: remove unused logging import and use the module-level logger; normalize file suffix checks with .lower(); streamline control flow with elif/else and remove redundant else blocks; forward raise_on_error to __import_format_to_thing__ when loading files; iterate file handles directly instead of using readlines(); minor whitespace fix in language.py. These tweaks improve consistency, error reporting, and file handling in the import utilities.",
          "is_bot": false,
          "headline": "Refactor import_format logging and file checks",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T10:35:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a018e58e75ea861f0851fb792f2ae3949f91533e",
          "body": "Add new documentation modules for knowledge.base.index and knowledge.base.ink and several service management docs (including asyncio index/ink/queue management). Apply numerous editorial and API-doc fixes across the knowledge docs: grammar and phrasing improvements, clearer parameter descriptions, s\n[…]\ncal.Path), addition of InflectionSetting and helper retry functions, and an updated Wikidata sync_time. These changes improve coverage for ink/index features and tidy up existing module documentation.",
          "is_bot": false,
          "headline": "Docs: add ink/index modules and polish docs",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T10:32:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "00b9af5e9a8b836a9aa2cfc005fc2ac3a9ffb13f",
          "body": "Fix inverted kg/file assignments and related label usage in knowledge/utils/diff.py. Several places (description counts, alias counts, data property counts and label value) were swapped; these are corrected to report kg and file values accurately. Also simplified the data properties comparison by re\n[…]\nthing.data_properties' branch and relying on direct value membership checks. Changes applied to both sync (diff_entities) and async (diff_entities_async) functions to ensure consistent diff reporting.",
          "is_bot": false,
          "headline": "Correct kg/file fields and data property checks",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T10:28:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b810942af67430634b5143bb2318703cc46e59bc",
          "body": "Replace literal 'en_US' with EN_US constant in WacomKnowledgeService examples. Make small docstring clarifications: reword entity existence check, add a ValueError raise note for missing entity URI, and refine auth_key/commit error descriptions.",
          "is_bot": false,
          "headline": "Use EN_US in examples; minor docs updates",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T10:27:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "958bb20f9a6b2cad5386b02b2b86671836dbd6af",
          "body": "Update asyncio package exports to use the renamed module. The __all__ list in knowledge/services/asyncio/__init__.py now exposes \"queue_management\" instead of the old \"queue_monitor\" to match the module name and avoid import errors.",
          "is_bot": false,
          "headline": "Replace queue_monitor with queue_management",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T10:27:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e02ab4b327d3eacc4025821b546036f37d30dced",
          "body": "Change TenantConfiguration to use an empty string as the default for contentDataPropertyName instead of an empty list. This ensures content_data_property_name is consistently a string when the key is missing in data_dict, avoiding type mismatches during initialization or later usage.",
          "is_bot": false,
          "headline": "Default content_data_property_name to empty string",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T10:27:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9b197ecd9ed688026b798f2c5c0410c62f2c0c86",
          "body": "Apply numerous documentation and wording fixes across the codebase (typos, grammar, hyphenation, comment clarifications). Add comprehensive language/locale constants, supported lists and mappings in knowledge/base/language.py and export them. Export internal helper names (__waiting_request__, __wait\n[…]\nThingObject creation and update __all__ exports. Update tests to use SUPPORTED_LOCALES. Miscellaneous small clarifications in service clients, queue/index helpers and session/token manager docstrings.",
          "is_bot": false,
          "headline": "Fix docs/typos and add language constants",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T10:27:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d58d70c39745bd43c95de95bfbe6f01b117ad3b0",
          "body": "Cleanup and wording fixes across ontology.py: refine docstrings for clarity/grammar, adjust several docstring phrasings, and standardize wording. Improve error/log messages by introducing reference_id_or_uri fallback and using it in logs/exceptions instead of directly indexing URI. Replace some entity[URI_TAG] access with entity.get(URI_TAG) to avoid KeyError. Remove redundant else branches after raises while preserving logging. Minor whitespace and punctuation tweaks.",
          "is_bot": false,
          "headline": "Improve docs, logging, and URI handling in ontology.py",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T09:00:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "977602a4b3c88060f00a0f50407fb3368b41443f",
          "body": "Upgrade package version to 4.2.1 (knowledge/__init__.py and pyproject.toml) and add a CHANGELOG entry for RELEASE 4.2.1. The changelog notes the addition of a raise_on_error parameter to import parsing paths to control error handling.",
          "is_bot": false,
          "headline": "Bump package version to 4.2.1 and update changelog",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T07:32:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "373e444e1a1a7af93268bc0b23b44779c6746470",
          "body": "Introduce a raise_on_error parameter to import parsing paths to control error handling. ThingObject.from_import_dict now accepts raise_on_error and will either raise ValueError on unsupported locales, missing main labels, null descriptions, source reference/system mismatches, etc., or log errors/war\n[…]\nrmat signature updated to accept the flag and use it when parsing lines. Also made gzip/ndjson suffix checks case-insensitive and adjusted some warning logs to error logs when raise_on_error is False.",
          "is_bot": false,
          "headline": "Add raise_on_error flag to import parsing",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-23T07:30:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9d5aee92d6dc3dfc0e550a127cc55621cf2a9b7d",
          "body": "Bump library version to 4.2.0 (knowledge.__version__ and pyproject.toml). Add 4.2.0 release notes to CHANGELOG.md describing refactor and new clients (QueueClient, QueueManagementClient, IndexManagementClient, InkServicesClient) and additional samples. Update dev dependencies in pyproject.toml (add universal-ink-library and trailing comma after pdoc3).",
          "is_bot": false,
          "headline": "Release 4.2.0: bump version, changelog, deps",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T15:26:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3a9e2a4c209e9a215950eaa2241b594efc079082",
          "body": "Update README: add new Ink Services, Index Management, and Queue Management sections with usage examples and sample commands. Expand TOC to include the new sections and provide code snippets for InkServices (HWR, math recognition, named entity linking, format conversion), IndexManagementClient (heal\n[…]\ng documents, refresh/force-merge/delete), and QueueManagementClient (list queues, per-queue details). Also rename \"Wacom Private Knowledge (WPK)\" to \"Wacom Private Knowledge System (PKS)\" for clarity.",
          "is_bot": false,
          "headline": "Add ink, index, and queue docs",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T14:04:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1ba3200c063bb69ae156c67fb421cc341059d474",
          "body": "Add two new sample scripts demonstrating index and queue management APIs. samples/index_management.py shows how to login as a tenant admin, check index health, refresh and force-merge an index, stream documents, and delete a document by ID. samples/queue_management.py demonstrates listing queue names, monitoring queues, and retrieving per-queue details (size, state, message stats) using the QueueManagementClient.",
          "is_bot": false,
          "headline": "Add index and queue management samples",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T12:18:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e5fd3aa5a1b3e8f43e1630b58941be00186dc3fd",
          "body": "Expand README with onboarding and developer guidance: add Table of Contents, Installation instructions (pip, Python versions, optional dev extras), a Quick Start example for WacomKnowledgeService, and a comprehensive Development section (core/dev dependencies, environment setup, testing, and code quality commands). Also adjust Technology Stack/sectioning, remove outdated ontology service bullets, and update the API docs path to docs/knowledge to improve discoverability and developer onboarding.",
          "is_bot": false,
          "headline": "Add installation, quick start, and dev docs",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T09:06:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3f2b68ba358ad04ce32762e3a5b899a384e653f4",
          "body": "Update tests/test_queue_management.py to import AsyncQueueMonitorClient from knowledge.services.asyncio.queue_management instead of knowledge.services.asyncio.queue_monitor to match the refactored module location.",
          "is_bot": false,
          "headline": "Fix import path for AsyncQueueMonitorClient",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T09:01:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fb417442358721dd3f12af03ad8aa5fdb51a9a42",
          "body": "Introduce knowledge/base/index.py with dataclasses to model index health and streaming documents. Adds Shard, Node, Cluster, Index, Condition, and HealthResponse to parse cluster/index health responses, plus StreamedDocumentMeta and IndexDocument (with dynamic extra fields) for vector DB streaming. Each model includes from_dict helpers for easy parsing and an IndexMode Literal for index modes.",
          "is_bot": false,
          "headline": "Add index models and health/stream dataclasses",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T08:59:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1070b31fbbd8c2577dbf462d8fa275304afacb2b",
          "body": "Expose new service modules in package public APIs: add index_management and queue_management to knowledge.services (__all__ and imports), and add index_management and queue_monitor to knowledge.services.asyncio.__all__. This registers the new service modules so they can be imported via the package namespaces.",
          "is_bot": false,
          "headline": "Export index and queue services in init files",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T08:57:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c84be55e1c72f145c60f0566c48f39e18aee6288",
          "body": "Clean up knowledge/services/search.py by removing unused imports (QueueMonitor, QueueCount, QueueNames) from knowledge.base.queue. This reduces clutter and avoids linter/flake8 warnings about unused imports.",
          "is_bot": false,
          "headline": "Remove unused queue imports from search service",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T08:56:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a187ed98b0a2162b2e5d9c4fd4bd07d3959997b6",
          "body": "Add two new integration test modules: tests/test_index_management.py and tests/test_queue_management.py. These provide sync and async fixtures and tests for index management (health, iterate_documents, refresh/force-merge skipped) and queue monitoring (list names, sizes, emptiness, monitor info). Tests create temporary admin test users and attempt cleanup, and will skip when required environment variables or TenantAdmin users are not available.",
          "is_bot": false,
          "headline": "Add integration tests for index and queue",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T08:56:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7c4de4b39cea4e95d320568dec5f61cbb5043035",
          "body": "Add new ontology exports (THING_CLASS, LAST_UPDATE_DATE, SYSTEM_SOURCE_SYSTEM, SYSTEM_SOURCE_REFERENCE_ID) to __all__ so these constants are available to callers. Update async client tests: import and instantiate AsyncQueueMonitorClient, use it for queue-related operations (list/monitor/size/is_empt\n[…]\nfor subsequent label/document checks. Also add additional document_search assertions, tighten several assertions (e.g. join_key), and apply minor formatting/argument-wrapping cleanups for readability.",
          "is_bot": false,
          "headline": "Export system constants and update async tests",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T08:56:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "98e0c6ff8068741d9bc76fc5bed7c3824e23933f",
          "body": "Expand the QueueManagementClient class docstring to document its purpose (queue metadata interactions) and list constructor parameters (service_url, application_name, service_endpoint, verify_calls, max_retries, backoff_factor). No functional changes—this commit improves inline documentation for maintainability and clarity.",
          "is_bot": false,
          "headline": "Add detailed docstring to QueueManagementClient",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T08:54:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a87308bb715be27dbba7f94a0eda250405d8d9e2",
          "body": "Rename knowledge/services/asyncio/queue_monitor.py to queue_management.py and refactor the AsyncQueueMonitorClient implementation. Update the class docstring to clarify queue management responsibilities and add/init parameter docs (verify_calls, timeout); remove large usage examples. Perform stylist\n[…]\n error-raise formatting. Remove the obsolete index_health method. Changes are primarily renaming and readability/refactorings rather than behavior changes (except for the removed index_health helper).",
          "is_bot": false,
          "headline": "Rename and refactor queue_monitor to queue_management",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T08:54:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "41a2a6a124be8643748cd52f2fec343751a64334",
          "body": "Fix awaiting a non-awaitable attribute in AsyncInkServices: response.content is not awaitable, so remove the unnecessary await and return it directly when response.ok. Keeps existing error handling intact.",
          "is_bot": false,
          "headline": "Return response.content without await",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T08:53:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0f9469ed0b8081c2633389ee4c89e07fdd82e43c",
          "body": "Introduce IndexManagementClient (sync) and AsyncIndexManagementClient (async) for managing the vector index. Both clients provide index operations: index_health, refresh_index, force_merge_index, delete_document_by_id and an iterate_documents method that streams NDJSON documents from the index. The \n[…]\nent uses the existing request_session and Response handling (handle_error/WacomServiceException). Defaults and service endpoint configuration are included and both modules export their client classes.",
          "is_bot": false,
          "headline": "Add index management clients (sync & async)",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T08:53:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "325b48e84639dc3988cead5133d4b4f8ada14307",
          "body": "Apply stylistic cleanups across codebase: add/clarify type hints in Asyncio ResponseData docstring, tweak minor comment wording, and simplify many multiline calls and assertions in tests to single-line forms (login calls, file paths, skipif decorators, assert messages, and service calls). Changes are formatting-only to improve readability and consistency; no intended functional changes.",
          "is_bot": false,
          "headline": "Style: simplify tests and tidy asyncio base",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-20T08:52:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9b7702b18142e92c9af5e8df8dafb99eac994914",
          "body": "Split queue-related endpoints into their own clients and modules. Added AsyncQueueMonitorClient (knowledge/services/asyncio/queue_monitor.py) and a synchronous QueueManagementClient (knowledge/services/queue_management.py) to encapsulate queue listing, counts, monitor info and related helpers. Remov\n[…]\nents (knowledge/services/asyncio/search.py and knowledge/services/search.py) and cleaned up imports. This separates queue management from semantic search for clearer responsibilities and easier reuse.",
          "is_bot": false,
          "headline": "Move queue APIs to dedicated clients",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-19T15:16:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7fb4bff4e6f71c9f5e737ffdf8a22526ead2fce6",
          "body": "Add comprehensive synchronous InkServices integration tests (tests/test_ink_services_sync.py) covering export (PNG/JPG/SVG/PDF) and HWR/math flows with fixtures, format validators, and setup/cleanup logic. Also perform small test maintenance across multiple files: remove unused imports, wrap long li\n[…]\n_nel.py, and apply minor formatting/refactors in tests/test_access.py, tests/test_diff.py, tests/test_entity_unit.py, tests/test_graph_utils.py, and tests/test_ontology_unit.py to improve readability.",
          "is_bot": false,
          "headline": "Add ink sync integration tests; tidy unit tests",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-19T06:55:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ba9bfd6e2e767f83679dde1c54dbb1072eea2bb0",
          "body": "Add the 'ink' module to knowledge.services.asyncio __all__ so the package exports it. Also apply minor formatting/whitespace cleanups across several __init__ and helper files (knowledge/base, knowledge/nel, knowledge/public, knowledge/public/helper, knowledge/utils/wikidata, knowledge/utils/wikipedia) — no other functional changes.",
          "is_bot": false,
          "headline": "Export 'ink' and apply whitespace cleanups",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-19T06:54:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b633fc96284e6aa46d83645d86b699f6d112fe00",
          "body": "Add Examples sections to multiple service client docstrings (async and sync variants) including graph, group, search, users, ontology, tenant and others to show initialization and common calls. Introduce AsyncSemanticSearchClient.index_health to query index health (async) and print the response. Clean up typing imports in asyncio/users and reorganize/export __all__ in services/users. Minor docstring wording tweaks across files.",
          "is_bot": false,
          "headline": "Add usage examples and index_health method",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-19T06:53:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c079fd396a41705ce1be50a1baca5b1297d2d5e0",
          "body": "Expose the new `ink` service in the package by adding it to `__all__` and importing `knowledge.services.ink` in `knowledge/services/__init__.py`. Also includes a minor formatting newline. This makes `ink` available via `from knowledge.services import ink` as part of the public API.",
          "is_bot": false,
          "headline": "Add ink service to knowledge.services",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-18T20:06:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e04d7961f5774b39ddc4df7893af7702b70359ac",
          "body": "Add a guard in wikidata_to_thing (knowledge/ontomapping/manager.py) that logs a warning and raises a ValueError when no labels are found for a given QID. This surfaces missing-label cases early and prevents downstream processing of items without labels.",
          "is_bot": false,
          "headline": "Raise on missing label for QID",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-18T20:06:27Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2815a29eb6c0c30855971a021e507eba50b4d88a",
          "body": "Remove the int() conversion when reading ontologyVersion in TenantConfiguration. This preserves the original value from data_dict, avoiding conversion errors and allowing non-integer or None version values (e.g., semantic version strings) to pass through.",
          "is_bot": false,
          "headline": "Don't cast ontologyVersion to int",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-18T20:05:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "27bb307695015fb830267632bdcd94c99706ac36",
          "body": "Introduce Universal Ink model enums and settings (knowledge/base/ink.py) and implement both synchronous and asynchronous Ink Services clients (knowledge/services/ink.py, knowledge/services/asyncio/ink.py) with endpoints and operations for NEL, HWR, math, ink-to-x pipeline, and format/PDF conversion.\n[…]\nncludes helpers for format validation and user management setup/cleanup. Provides default InkToX settings and provider configuration handling to enable end-to-end interactions with Wacom Ink Services.",
          "is_bot": false,
          "headline": "Add Ink services clients, models, and async tests",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-18T20:05:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "11139135aa35b7ba1fb8192569ddcd6698471a55",
          "body": "Change PropertyType and DataPropertyType to inherit from str, enum.Enum so their values behave as plain strings (useful for dict keys/serialization). Also tighten the ThingObject source reference id check to only warn/raise on mismatches when dp_language_code == EN_US, avoiding spurious errors for non-English localized entries.",
          "is_bot": false,
          "headline": "Make enums str-based and adjust source-id warning",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-18T20:02:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a08430ca3f105f95558306b38749baabbef33f2a",
          "body": "Adjust various generated API docs to better reflect actual signatures: add explicit return annotations (mostly -> None) for many service methods, generalize kwargs/response types to Any, refine collection element types (e.g. group_users, resolve return), update split_updates return type to return batches of typed dicts, and update an auto-generated WikidataThing sync_time timestamp. These changes improve accuracy and readability of the documentation signatures.",
          "is_bot": false,
          "headline": "Update docs: refine type hints and return types",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T22:06:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7a1b39f179186f0455227018ad9816d0c9b759a6",
          "body": "Clean up typing imports in two service modules: remove the unused 'Literal' import from knowledge/services/asyncio/graph.py and remove the unused 'cast' import from knowledge/services/search.py. This reduces lint warnings and keeps imports minimal without changing functionality.",
          "is_bot": false,
          "headline": "Remove unused typing imports in services",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T22:05:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4241d09123bfdd67a013a24f063520e062778c1a",
          "body": "Document release 4.1.0 (2026-02-06): added comprehensive type annotations and return types, fixed response.content typing via cast(), resolved variable redefinition issues in try/except to satisfy mypy, introduced Optional types and logger guards, corrected imports and type compatibility, and refactored response handling into a ResponseData structure.",
          "is_bot": false,
          "headline": "Update CHANGELOG for v4.1.0 release",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T22:03:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4811531b35989fe7c25478298ed166d293b905c0",
          "body": "Add and tighten type hints, return annotations and casts across the knowledge service codebase to improve type safety and static checks. Key changes: use loguru.logger explicitly in package logger bridge; add Optional/Union/cast imports and cast response.content to concrete types; annotate async met\n[…]\n_TIMEOUT from services module where needed; and minor API/exception cleanup. These changes are focused on runtime robustness and better static typing (mypy) compliance without altering business logic.",
          "is_bot": false,
          "headline": "Improve typing, casting and logging usage",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T22:03:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e6b4332a18e84998f7311132871cc6d46fc98821",
          "body": "Improve and standardize documentation across knowledge module docs: add as_dict method docs for many classes (Entity descriptions/labels, LocalizedContent, DataProperty, Ontology-related classes, Wikidata classes, ThingObject, etc.), and make numerous typing clarifications (use Dict[str, Any], Optio\n[…]\ne/ontomapping/index.md, docs/knowledge/public/{cache,wikidata}.md, docs/knowledge/services/asyncio/base.md and related service docs. These changes improve API docs accuracy and serialization guidance.",
          "is_bot": false,
          "headline": "docs: add as_dict methods & typing fixes",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T20:58:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ba6ebbc39ff520e6eeec995752344fe1b2cfe78f",
          "body": "Update version from 4.0.4 to 4.1.0 in knowledge/__init__.py and pyproject.toml to reflect the new release.",
          "is_bot": false,
          "headline": "Bump package version to 4.1.0",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T20:56:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "16d4f4d814999eb1f469ed2b708cb0a9ef2a150a",
          "body": "Read SOURCE_SYSTEM_TAG from entity and validate it against data properties. Introduces a source_system variable and source_system_found flag, checks for SYSTEM_SOURCE_SYSTEM data properties, raises on mismatches, logs warnings when source system is missing or inconsistent, and adds a SYSTEM_SOURCE_SYSTEM DataProperty if the source system was present but not found among data properties.",
          "is_bot": false,
          "headline": "Handle source_system in ThingObject parsing",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T20:35:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1651598b5e7e1ea1492ef2838bd3e0649171d7d1",
          "body": "Fix int() usage in TenantConfiguration: use int(data_dict.get(\"ontologyVersion\", 0)) so a missing ontologyVersion supplies a default 0 instead of being interpreted as the int() base argument. This prevents incorrect conversion errors and ensures a sensible default value.",
          "is_bot": false,
          "headline": "Correct ontology_version int conversion",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T20:35:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6cabb70679f1c3663beb784a10109fb63209e89f",
          "body": "Improve type safety and runtime robustness across knowledge base and service modules.\n\n- Allow Label to accept either LocaleCode or LanguageCode for language_code.\n- Refine typing imports and add cast; annotate kwargs and method return types (e.g. session methods, properties, context manager methods\n[…]\n refresh).\n- Cast token manager result to PermanentSession and return a default empty refresh token when missing.\n\nThese changes reduce mypy/IDE warnings and guard against None/Type errors at runtime.",
          "is_bot": false,
          "headline": "Add typing annotations and runtime safety checks",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T19:27:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c7b237cbe1a85ece0f8a16e14ab6735320a44444",
          "body": "Remove unused `orjson` imports from knowledge/services/asyncio/group.py, search.py, and users.py. This cleans up unused imports and avoids unnecessary dependency references; no functional changes.",
          "is_bot": false,
          "headline": "Remove unused orjson imports in asyncio services",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T19:26:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "499cde060506df0e2c139d50b773eaaf9b0f592f",
          "body": "Apply typing improvements, null-safety and small refactors across ontology.py: make many list and field parameters Optional and default to empty lists, tighten several attribute types (visibility, owner_id, group_ids, subclass_of, ranges), and broaden language-parameter types to accept LocaleCode or\n[…]\n, a safety break when traversing subclass chains, and export selected symbols via __all__. These changes reduce None-related errors and clarify type expectations throughout the ontology handling code.",
          "is_bot": false,
          "headline": "Add typing and null-safety fixes to ontology",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T19:25:30Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d226001782c13a35be231b2f179ba54597c722b8",
          "body": "Add and tighten type hints (Union, cast, specific Dict/List types) and annotate several methods' return types. Normalize local variable names (entity_uri, result_uri, actual_file_name) and convert numeric JSON IDs to strings. Add validation to ensure entity.uri is present for updates and guard role checks against a missing current_session. Cast JSON responses where needed and refactor image handling and relation/index methods for clearer, safer behavior.",
          "is_bot": false,
          "headline": "Improve typing and error handling in graph service",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T19:25:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "82ea8fab3c1e2a80c78665e11b2c7bf6714140c8",
          "body": "Improve static typing and MyPy-friendliness across knowledge/services/ontology.py: import cast; widen several tuple element types to Optional for superclass/property refs; add explicit return types (None) for delete methods; mark labels/comments as Optional; cast response.json() results to Dict types where appropriate; normalize params typing and ensure RDF export returns a str. These changes clarify expected types and reduce type-checker warnings without altering runtime behavior.",
          "is_bot": false,
          "headline": "Refine type hints and casts in ontology service",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T19:24:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce3d3643029f62a33da70ef6aff59e98a9bd1567",
          "body": "Annotate session-related functions and variables for clearer typing: add a return type to PermanentSession.__str__ and to TokenManager.remove_session, and annotate the local `session` variable with a Union type. Also normalize refresh_token when creating a PermanentSession by substituting an empty string for None to avoid passing None where a string is expected.",
          "is_bot": false,
          "headline": "Add type hints and default refresh_token",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T19:23:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c82126d103dc5ba861952ce4df64a559323da5d",
          "body": "Strengthen type hints and improve runtime robustness in knowledge/services/users.py. Added return type annotations for meta_data.setter and __repr__, used Optional for nullable params (meta_data, roles), and annotated payload, results and params with more precise typing. Handle token expiration pars\n[…]\nrse errors) and guard logger usage. Ensure internal user id is returned as a string. These changes improve static type checking and reduce runtime errors when interacting with the user management API.",
          "is_bot": false,
          "headline": "Add typing and robustness fixes to users service",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T19:13:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9dc7de05983d16ce63562f7537de756cb5ca6833",
          "body": "Catch aiohttp.ContentTypeError and orjson.JSONDecodeError using a tuple, and simplify the fallback by always reading response.text(..., errors='ignore') after logging. This removes the nested try/except and streamlines handling of undecodable response bodies.",
          "is_bot": false,
          "headline": "Simplify response decode exception handling",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T19:13:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "58f771b22599fd15244e5baafe95582f5c8459f5",
          "body": "Add explicit encoding='utf-8' to all open() calls in knowledge/public/cache.py used for saving and loading the Wikidata caches (objects, properties, subclasses, superclasses). This enforces consistent UTF-8 handling across platforms and prevents issues with platform-default encodings when writing/reading JSON lines produced by orjson.",
          "is_bot": false,
          "headline": "Specify UTF-8 encoding when reading/writing cache",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T19:12:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "91a948cbf7a4f864c9b48f2232989231cfdd62a1",
          "body": "Add explicit __all__ exports for diff utilities and fix a bug in diff_entities_async where iterating file_thing.description could raise when it was None. The loop now iterates over an empty list if description is None, preventing TypeError and ensuring diffs are computed safely when descriptions are missing.",
          "is_bot": false,
          "headline": "Guard against None file descriptions in diff",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T18:12:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2d8ad644411009fdb9f489a5e152845cefaefa59",
          "body": "Expose module public APIs and apply widespread formatting/consistency fixes across the codebase. Changes include adding __all__ lists in many modules, reorganizing and grouping imports, normalizing multi-line parameter/argument formatting and trailing commas, small type and literal fixes (e.g. 0. ->\n[…]\nn-type annotations (e.g. update_entity -> None), and small logging/string formatting tweaks. These edits are largely non-functional and improve readability and the package's explicit exported symbols.",
          "is_bot": false,
          "headline": "Add __all__ exports and formatting cleanups",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T17:33:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "250acb379e15f3b139e30e21791167d5e9fd0439",
          "body": "Introduce iterate_large_import_format(file_path: Path) to stream-parse large import files and yield ThingObject instances per line. The function supports gzip (.gz) and ndjson (.ndjson) input, raises FileNotFoundError when the file is missing and ValueError for unsupported suffixes. Also add Iterable to the typing imports to support the new return type.",
          "is_bot": false,
          "headline": "Add iterator for large import format files",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:52:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "27c9468bd392dd235c100b9bfc937052c7ebf2cd",
          "body": "Cast extracted abstract and thumbnail source to str to avoid returning non-string/None values. Add typing annotations (Dict[str, Any]) for API response variables and include a Raises section in __extract_abstract__ docstring documenting ExtractionException. Improves type safety and error documentation for wikipedia utilities.",
          "is_bot": false,
          "headline": "Enforce string returns and add type hints",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:51:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d2d9f225c582e8ab1acb7c4e006f3fe10ac2b75",
          "body": "Update tests/test_wikidata.py to call cls.as_dict() rather than cls.__dict__(). This aligns the test with the class API for obtaining a dictionary representation and prevents improper invocation of the __dict__ attribute (updated in two assertions).",
          "is_bot": false,
          "headline": "Use as_dict() instead of __dict__()",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:51:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f36812bc3978150dcda88c1595333fa24af3b78b",
          "body": "Make search and named-entity-linking tests tolerant of unsupported languages. Added try/except around async_client.search_labels and async_client.link_personal_entities to record per-language success and only require that at least one language returns results. Handle WacomServiceException (treat 400 as unsupported, re-raise 401/other codes). Also adjusted listing call parameters and iterated per-entity labels to test linking across label languages.",
          "is_bot": false,
          "headline": "Handle multilingual failures in async tests",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:51:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8be8f58aa500e97307930f8871a153e68d23846f",
          "body": "Adjust dependency specifications in pyproject.toml: add upper bounds for requests and PyJWT, add urllib3 and types-requests, and remove python-dateutil and ndjson. Also reformat the loguru entry and remove the Python 3.9 classifier. These changes constrain major-version upgrades, add typing hints for requests and an explicit urllib3 runtime dependency, and clean up the declared package list.",
          "is_bot": false,
          "headline": "Update pyproject dependencies and classifiers",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:51:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3f24b9db795c6713d99d36d1e486cb693e4645db",
          "body": "Introduce ResponseData dataclass to encapsulate HTTP results and a _request_content helper to normalize response body decoding. Change AsyncSession.request and convenience methods to return ResponseData (and use async context managers) instead of raw aiohttp.ClientResponse. Update handle_error and a\n[…]\nonal annotations, explicit None returns, and some casts). This centralizes response handling and JSON/text decoding and updates callers throughout the asyncio services to match the new response model.",
          "is_bot": false,
          "headline": "Return ResponseData from AsyncSession requests",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:50:49Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "680a0f7fe0a470988dcca3cb59986cf15b8a9d81",
          "body": "Add and refine type annotations across knowledge service modules to improve type safety and clarity. Changes include:\n\n- base.py: added return type hints for exception and RequestsSession methods (-> None) and close().\n- graph.py: use typing (Dict[str, Any], Optional[str]) for params, response bodie\n[…]\n_data and roles as Optional where appropriate and update docstrings to reflect defaults.\n\nThese changes are primarily for typing correctness and documentation clarity; no behavioral logic was altered.",
          "is_bot": false,
          "headline": "Add type hints and refine Optional/Any usages",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:50:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b189caebf9e9ff065d9b2cb5f124caba7d9d899c",
          "body": "Export additional constants from the package, add return type annotations across cache/wikidata classes, and narrow exception handling in the API client to (ValueError, KeyError, HTTPError). Replace usages of object.__dict__ serialization with a new as_dict() API on WikidataClass/WikidataThing and update cache file writes accordingly. These changes improve type clarity, safer error handling, and consistent JSON serialization for cache persistence.",
          "is_bot": false,
          "headline": "Add type hints, stricter exceptions, and as_dict",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:49:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "22ebe6252f8b6a4080776c48ba7c9676598385e1",
          "body": "Add and tighten type annotations across ontomapping (method/constructor return types and property setters), correct the WikidataCache annotation, and annotate register_ontology/load_configuration to return None. Update WikidataClassEncoder.default to call as_dict() and include documentation. Ensure convert_dict consistently returns strings by casting various structure value types (time, quantity, external-id, string, url) to str for stable downstream handling.",
          "is_bot": false,
          "headline": "Add type hints, casts, and JSON encoder fix",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:49:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ad1d3b631f67fb44966f00d22dfe50304affb146",
          "body": "Add and refine Python type hints across knowledge/nel: annotate __repr__ and constructors with return types, add -> None to setters and __init__ methods, use Optional for supported_languages, and standardize LocaleCode/List types. Update typing imports in engine.py to include Any and annotate JSON response as Dict[str, Any]. Minor docstring wording cleanup in is_language_supported. These are non-functional, type-safety improvements for clarity and static checking.",
          "is_bot": false,
          "headline": "Add / refine type annotations in NEL module",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:48:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "87967c4d80941771b48573f376bd77c66f20338e",
          "body": "Add typing annotations (Optional, return and param types) across TenantConfiguration and its setters, and ensure setters return None. Update from_dict to cast/normalize incoming values (str/int/bool) and provide default empty lists for list fields. Change vector_search_object_properties setter to ac\n[…]\npe. These changes improve type safety and normalize external data, but note content_data_property_name is now defaulted from dict to an empty list if missing — review if a string default was intended.",
          "is_bot": false,
          "headline": "Add type hints and defaults to TenantConfiguration",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:48:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9c18d1f7bcb0a0f7372af4cf45be9bb53ccad238",
          "body": "Add return type annotations for several __repr__ and __init__ methods and other methods across search-related classes. Initialize LocaleCode with a safe default (en_US) when missing, and provide default values for tokenizer and number-of-tokens to avoid None issues. Add explicit return types for properties and static constructors to improve type checking and clarity.",
          "is_bot": false,
          "headline": "Add type hints and defaults in search models",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:36:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0468e9f7359edade39454e5ae1cf275fc4de9fb5",
          "body": "Convert userId, tenantId, internalJobId and jobId to strings when constructing JobStatus to ensure consistent types (avoid None or non-string values). Also add a return type annotation to __repr__ for improved type clarity.",
          "is_bot": false,
          "headline": "Cast job id fields to str and annotate __repr__",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:24:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e8100c9af01c43552005df4a110b8092e9268532",
          "body": "Add explicit -> None return type annotations to several __init__ methods in knowledge/base/queue.py (QueueCount, QueueNames, MessageRate, MessageStats, QueueMonitor) to improve type clarity and consistency. This is a non-functional change that enhances static typing.",
          "is_bot": false,
          "headline": "Annotate __init__ return types as None",
          "author_name": "Markus Weber",
          "author_login": "doctorink",
          "committed_at": "2026-02-06T16:23:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 63,
      "commits_last_year": 204,
      "latest_release_at": "2026-07-10T05:45:32Z",
      "latest_release_tag": "v4.3.3",
      "releases_from_tags": false,
      "days_since_last_push": 11,
      "active_weeks_last_year": 18,
      "days_since_latest_release": 11,
      "mean_days_between_releases": 24.3
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 37,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "personal_knowledge_library",
          "exists": true,
          "license": null,
          "keywords": [
            "semantic-knowledge",
            "knowledge-graph",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3.10",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Programming Language :: Python :: 3.13",
            "Topic :: Software Development :: Libraries :: Python Modules"
          ],
          "ecosystem": "pypi",
          "matches_repo": null,
          "registry_url": "https://pypi.org/project/personal_knowledge_library/",
          "is_deprecated": false,
          "latest_version": "4.3.3",
          "repository_url": null,
          "versions_count": 76,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2021-11-05T20:04:08.949538Z",
          "latest_published_at": "2026-07-10T05:46:10.724471Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 11
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 3,
      "watchers": 1,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [
          {
            "date": "2025-03-19",
            "count": 1
          },
          {
            "date": "2025-03-23",
            "count": 1
          },
          {
            "date": "2025-11-29",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 3,
        "total_stars": 3
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "samples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 106475,
      "source_files_sampled": 91,
      "oversized_source_files": 3,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 26,
        "malicious_count": 0,
        "assessed_package": "pypi:personal_knowledge_library@4.3.3",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "aiohttp",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">3.13.3"
        },
        {
          "name": "requests",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "(>=2.32.0, <3.0.0)"
        },
        {
          "name": "PyJWT",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "(>=2.10.1,<3.0.0)"
        },
        {
          "name": "tqdm",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=4.65.0"
        },
        {
          "name": "rdflib",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=7.1.0"
        },
        {
          "name": "orjson",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=3.10.0"
        },
        {
          "name": "certifi",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "cachetools",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=5.3.0"
        },
        {
          "name": "loguru",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "==0.7.3"
        },
        {
          "name": "urllib3",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "(>=2.6.3,<3.0.0)"
        },
        {
          "name": "types-requests",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "(>=2.32.4.20260107,<3.0.0.0)"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "aiohttp",
            "direct": true,
            "version": "3.14.1",
            "ecosystem": "pypi"
          },
          {
            "name": "cachetools",
            "direct": true,
            "version": "7.1.4",
            "ecosystem": "pypi"
          },
          {
            "name": "certifi",
            "direct": true,
            "version": "2026.6.17",
            "ecosystem": "pypi"
          },
          {
            "name": "loguru",
            "direct": true,
            "version": "0.7.3",
            "ecosystem": "pypi"
          },
          {
            "name": "orjson",
            "direct": true,
            "version": "3.11.9",
            "ecosystem": "pypi"
          },
          {
            "name": "pyjwt",
            "direct": true,
            "version": "2.13.0",
            "ecosystem": "pypi"
          },
          {
            "name": "rdflib",
            "direct": true,
            "version": "7.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "requests",
            "direct": true,
            "version": "2.34.2",
            "ecosystem": "pypi"
          },
          {
            "name": "tqdm",
            "direct": true,
            "version": "4.68.4",
            "ecosystem": "pypi"
          },
          {
            "name": "types-requests",
            "direct": true,
            "version": "2.33.0.20260518",
            "ecosystem": "pypi"
          },
          {
            "name": "urllib3",
            "direct": true,
            "version": "2.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "aiodns",
            "direct": false,
            "version": "4.0.4",
            "ecosystem": "pypi"
          },
          {
            "name": "aiohappyeyeballs",
            "direct": false,
            "version": "2.7.1",
            "ecosystem": "pypi"
          },
          {
            "name": "aiosignal",
            "direct": false,
            "version": "1.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ast-serialize",
            "direct": false,
            "version": "0.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "astroid",
            "direct": false,
            "version": "4.0.4",
            "ecosystem": "pypi"
          },
          {
            "name": "async-timeout",
            "direct": false,
            "version": "5.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "attrs",
            "direct": false,
            "version": "26.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "backports-asyncio-runner",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "backports-zstd",
            "direct": false,
            "version": "1.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "bitarray",
            "direct": false,
            "version": "3.8.2",
            "ecosystem": "pypi"
          },
          {
            "name": "bitstring",
            "direct": false,
            "version": "4.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "black",
            "direct": false,
            "version": "26.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "brotli",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "brotlicffi",
            "direct": false,
            "version": "1.2.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "cffi",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "charset-normalizer",
            "direct": false,
            "version": "3.4.9",
            "ecosystem": "pypi"
          },
          {
            "name": "click",
            "direct": false,
            "version": "8.4.2",
            "ecosystem": "pypi"
          },
          {
            "name": "colorama",
            "direct": false,
            "version": "0.4.6",
            "ecosystem": "pypi"
          },
          {
            "name": "coverage",
            "direct": false,
            "version": "7.15.0",
            "ecosystem": "pypi"
          },
          {
            "name": "dill",
            "direct": false,
            "version": "0.4.1",
            "ecosystem": "pypi"
          },
          {
            "name": "distlib",
            "direct": false,
            "version": "0.4.3",
            "ecosystem": "pypi"
          },
          {
            "name": "exceptiongroup",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "faker",
            "direct": false,
            "version": "18.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "filelock",
            "direct": false,
            "version": "3.29.7",
            "ecosystem": "pypi"
          },
          {
            "name": "flake8",
            "direct": false,
            "version": "7.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "frozenlist",
            "direct": false,
            "version": "1.8.0",
            "ecosystem": "pypi"
          },
          {
            "name": "idna",
            "direct": false,
            "version": "3.18",
            "ecosystem": "pypi"
          },
          {
            "name": "iniconfig",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "isodate",
            "direct": false,
            "version": "0.7.2",
            "ecosystem": "pypi"
          },
          {
            "name": "isort",
            "direct": false,
            "version": "8.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "librt",
            "direct": false,
            "version": "0.13.0",
            "ecosystem": "pypi"
          },
          {
            "name": "lxml",
            "direct": false,
            "version": "6.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mako",
            "direct": false,
            "version": "1.3.12",
            "ecosystem": "pypi"
          },
          {
            "name": "markdown",
            "direct": false,
            "version": "3.10.2",
            "ecosystem": "pypi"
          },
          {
            "name": "markupsafe",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "mccabe",
            "direct": false,
            "version": "0.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "multidict",
            "direct": false,
            "version": "6.7.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy",
            "direct": false,
            "version": "2.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy-extensions",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "numpy",
            "direct": false,
            "version": "2.2.6",
            "ecosystem": "pypi"
          },
          {
            "name": "packaging",
            "direct": false,
            "version": "26.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pathspec",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pdoc3",
            "direct": false,
            "version": "0.11.6",
            "ecosystem": "pypi"
          },
          {
            "name": "platformdirs",
            "direct": false,
            "version": "4.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pluggy",
            "direct": false,
            "version": "1.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "propcache",
            "direct": false,
            "version": "0.5.2",
            "ecosystem": "pypi"
          },
          {
            "name": "protobuf",
            "direct": false,
            "version": "3.20.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pycares",
            "direct": false,
            "version": "5.0.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pycodestyle",
            "direct": false,
            "version": "2.14.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pycparser",
            "direct": false,
            "version": "3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyflakes",
            "direct": false,
            "version": "3.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pygments",
            "direct": false,
            "version": "2.20.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pylint",
            "direct": false,
            "version": "4.0.6",
            "ecosystem": "pypi"
          },
          {
            "name": "pyparsing",
            "direct": false,
            "version": "3.3.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pyproject-api",
            "direct": false,
            "version": "1.10.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest",
            "direct": false,
            "version": "9.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-asyncio",
            "direct": false,
            "version": "1.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-cov",
            "direct": false,
            "version": "7.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-env",
            "direct": false,
            "version": "1.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-mock",
            "direct": false,
            "version": "3.15.1",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dateutil",
            "direct": false,
            "version": "2.9.0",
            "ecosystem": "pypi"
          },
          {
            "name": "python-discovery",
            "direct": false,
            "version": "1.4.4",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dotenv",
            "direct": false,
            "version": "1.2.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pytokens",
            "direct": false,
            "version": "0.4.1",
            "ecosystem": "pypi"
          },
          {
            "name": "six",
            "direct": false,
            "version": "1.17.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tibs",
            "direct": false,
            "version": "0.5.7",
            "ecosystem": "pypi"
          },
          {
            "name": "tomli",
            "direct": false,
            "version": "2.4.1",
            "ecosystem": "pypi"
          },
          {
            "name": "tomli-w",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tomlkit",
            "direct": false,
            "version": "0.15.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tox",
            "direct": false,
            "version": "4.56.4",
            "ecosystem": "pypi"
          },
          {
            "name": "typing-extensions",
            "direct": false,
            "version": "4.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "universal-ink-library",
            "direct": false,
            "version": "2.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "varint",
            "direct": false,
            "version": "1.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "virtualenv",
            "direct": false,
            "version": "21.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "win32-setctime",
            "direct": false,
            "version": "1.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "yarl",
            "direct": false,
            "version": "1.24.2",
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 87,
        "direct_count": 11,
        "indirect_count": 76
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 0,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "doctorink",
          "commits": 585,
          "avatar_url": "https://avatars.githubusercontent.com/u/54904301?v=4"
        },
        {
          "type": "User",
          "login": "wacom-github",
          "commits": 4,
          "avatar_url": "https://avatars.githubusercontent.com/u/39759464?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.993
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "pylint.yml",
        "python-package.yml",
        "python-publish.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [
        ".pylintrc"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "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": null,
            "reason": "no pull request found",
            "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/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "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": 10,
            "reason": "20 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "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": "f226502359e81cdedb9b125a30af5266fdf58bc9",
        "ran_at": "2026-07-22T03:23:41Z",
        "aggregate_score": 4,
        "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-10T05:47:30Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": null,
      "ci_last_conclusion": "FAILURE",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/Wacom-Developer/personal-knowledge-library",
    "host": "github.com",
    "name": "personal-knowledge-library",
    "owner": "Wacom-Developer"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 56,
      "inputs": {
        "security": 52,
        "vitality": 81,
        "community": 26,
        "governance": 42,
        "engineering": 78
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 81,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 69,
            "inputs": {
              "commits_last_year": 204,
              "human_commit_share": 1,
              "days_since_last_push": 11,
              "active_weeks_last_year": 18
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 11 days ago",
                "points": 28.8,
                "status": "partial",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 11
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "18/52 weeks with commits",
                "points": 12.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 18
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "204 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 204
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "20 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "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": 100,
            "inputs": {
              "releases_count": 63,
              "latest_release_tag": "v4.3.3",
              "releases_from_tags": false,
              "days_since_latest_release": 11,
              "mean_days_between_releases": 24.3
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "63 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 63
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 11 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 11
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~24.3 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 24.3
                    }
                  }
                ],
                "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": "excellent",
            "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": 11,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 11 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 11
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 26,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 5,
            "inputs": {
              "forks": 0,
              "stars": 3,
              "watchers": 1,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "below_threshold"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "3 stars",
                "points": 4.9,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "1 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "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 (Apache-2.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "Apache-2.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "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": "at_risk",
        "name": "Sustainability & Governance",
        "value": 42,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 15,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.993
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 99% of commits",
                "points": 0.2,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 99
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "critical",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution, PR acceptance. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution",
                    "pr_acceptance"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 1,
            "inputs": {
              "merged_prs": 0,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "no decided pull requests or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_decided_prs_or_data",
                    "params": {}
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 67,
            "inputs": {
              "followers": 79,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "Wacom-Developer",
              "public_repos": 38,
              "account_age_days": 2974
            },
            "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": "79 followers of Wacom-Developer",
                "points": 13.7,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 79,
                      "login": "Wacom-Developer"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "38 public repos, account ~8 yr old",
                "points": 23.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 38
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 8
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "personal_knowledge_library"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 11
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 11 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 11
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "76 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 76
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 78,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 80,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "3 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "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": ".pylintrc",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".pylintrc"
                    }
                  }
                ],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "topics": [
                "knowledge-graph",
                "wikidata",
                "wikidata-api"
              ],
              "has_wiki": false,
              "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": "3 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 52,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 40,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 15,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 3,
              "scorecard_aggregate": 4
            },
            "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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "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/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "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": "20 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "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": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the pypi:personal_knowledge_library@4.3.3 runtime dependency closure — what installing the published package pulls in — 26 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "pypi:personal_knowledge_library@4.3.3",
                  "assessed": 26
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 26,
              "unassessed_packages": 0,
              "affected_by_severity": "none",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "no indirect dependency carries a known advisory",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "no_indirect_advisories",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 26,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "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"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 1
            },
            "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": "at_risk",
        "name": "AI Readiness",
        "value": 39,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "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": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 33,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [],
              "agent_commit_share": 0,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": ".pylintrc",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".pylintrc"
                    }
                  }
                ],
                "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": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "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 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 53,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 106475,
              "source_files_sampled": 91,
              "oversized_source_files": 3
            },
            "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": "3/91 source files over 60KB",
                "points": 53.2,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 91,
                      "oversized": 3
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "samples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "samples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "samples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [],
  "report_type": "repository",
  "generated_at": "2026-07-22T03:23:46.208429Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/w/Wacom-Developer/personal-knowledge-library.svg",
  "full_name": "Wacom-Developer/personal-knowledge-library",
  "license_state": "standard",
  "license_spdx": "Apache-2.0"
}

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

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

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