Öffentliches Register
Software-GesundheitsberichtSchema 0.26.0 · Metriken 1.13.0 · 2026-07-22 03:23 UTC

Wacom-Developer / personal-knowledge-library

Library for accessing personal knowledge service.

PythonApache-2.0★ 3 Sterne⑂ 0 Forksseit März 2022Auf GitHub ansehen ↗

Wacom-Developer/personal-knowledge-library erreicht einen Gesundheitsindex von 56 von 100 und liegt damit im Bereich Mittel. Am stärksten schneidet es bei Vitality (81/100) ab, am schwächsten bei Community & Adoption (26/100). Zuletzt vor 11 Tagen aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

56
gesamt / 100
Mittel

Software-Gesundheitsindex

Metriken werden auf einer Skala von 1–100 in gewichtete Kategorien gruppiert. Der Gesamtwert beginnt als ihr Mittel; sobald öffentliche Evidenz die Richtlinie für Hochrisikojurisdiktionen auslöst, wird die Bewertung angepasst und erhält die Obergrenze 49 (Gefährdet). AI Readiness liegt außerhalb.

56
Exzellent85-100Vorbildlich; erfüllt im Wesentlichen alle geprüften Kriterien
Gut70-84Gesund; geringfügige Lücken
Mittel50-69Akzeptabel mit deutlichen Lücken; Überprüfung empfohlen
Gefährdet30-49Erhebliche Schwächen; eine Übernahme erfordert Vorsicht
Kritisch1-29Schwerwiegende Probleme (aufgegeben, nur ein Maintainer, keine Hygiene)
VitalitätCommunity &VerbreitungNachhaltigkeit &GovernanceEngineering-QualitätSicherheitAI Readiness

Bewertungsprofil

Jede Achse ist eine Kategorie. Die Form zählt mehr als der Durchschnitt — ein gesundes Projekt füllt die gesamte Fläche, während ein Profil aus Spitzen und Kratern bedeutet, dass Stärke in einer Dimension Risiken in einer anderen verdeckt.

Eigentümerschaft

WacomOrganisation
79 Follower38 öffentliche Reposseit Mai 2018

Dieses Repository wird von einer Organisation getragen — geteilte, rechenschaftspflichtige Trägerschaft, die jeden einzelnen Maintainer überdauern kann.

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlichtTags
PyPIpersonal_knowledge_library4.3.3-76vor 11 Tagensemantic-knowledgeknowledge-graph

Metriken nach Kategorie

Vitalität

Lebt das Projekt — wird Code geschrieben und werden Releases ausgeliefert?

81Gut · 22 % des Gesamtindex
Wie die Bewertung erfolgt
28.8/36Push-Aktualität — letzter Push vor 11 Tagen
12.5/36Commit-Rhythmus — 18/52 Wochen mit Commits
18/18Commit-Volumen — 204 Commits im letzten Jahr
10/10OpenSSF Scorecard: Maintained — 20 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Verwendete Eingangsdaten
commits_last_year204
human_commit_share1
days_since_last_push11
active_weeks_last_year18

Release-Disziplin

100Exzellent
Wie die Bewertung erfolgt
27/27Liefert Releases aus — 63 Releases veröffentlicht
36/36Release-Aktualität — letztes Release vor 11 Tagen
27/27Release-Rhythmus — ein Release etwa alle 24,3 Tage
0/10OpenSSF Scorecard: Signed-Releases — keine Daten
Verwendete Eingangsdaten
releases_count63
latest_release_tagv4.3.3
releases_from_tagsnein
days_since_latest_release11
mean_days_between_releases24,3
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): OpenSSF Scorecard: Signed-Releases. Die verbleibenden Gewichte wurden renormalisiert.

Community & Verbreitung

Hat das Projekt Nutzer, Downloads, Aufmerksamkeit und ein einladendes Umfeld für Beitragende?

26Kritisch · 18 % des Gesamtindex
Wie die Bewertung erfolgt
4.9/60Stars — 3 Stars
0/25Forks — 0 Forks
0/15Watcher — 1 Watcher
Verwendete Eingangsdaten
forks0
stars3
watchers1
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonbelow_threshold
Wie die Bewertung erfolgt
22.5/22.5README
22.5/22.5Lizenz — anerkannte Lizenz (Apache-2.0)
0/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
0/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licenseja
has_contributingnein
has_issue_templatenein
has_code_of_conductnein
has_pull_request_templatenein

Nachhaltigkeit & Governance

Überdauert das Projekt die Menschen, die es tragen — Bus-Faktor, Reaktionsfähigkeit, Trägerschaft und Paketpflege?

42Gefährdet · 24 % des Gesamtindex
Wie die Bewertung erfolgt
9/54Bus-Faktor — 1 Beitragende decken die Hälfte aller Commits ab
0.2/22.5Commit-Verteilung — wichtigste beitragende Person verfasste 99 % der Commits
2.7/13.5Breite der Beitragenden — 2 Beitragende
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Verwendete Eingangsdaten
bus_factor1
contributors_sampled2
top_contributor_share0,993
Wie die Bewertung erfolgt
0/46.8Issue-Lösungsquote — keine Issues oder keine Daten
0/38.3PR-Annahme — keine entschiedenen Pull Requests oder keine Daten
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs0
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Issue-Lösungsquote, PR-Annahme. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
30/30Organisatorische Trägerschaft — im Besitz einer Organisation
0/20Verifizierte Domain
13.7/25Reichweite des Inhabers — 79 Follower von Wacom-Developer
23.6/25Kontohistorie — 38 öffentliche Repos, Kontoalter ca. 8 Jahre
Verwendete Eingangsdaten
followers79
owner_typeOrganization
is_verified
owner_loginWacom-Developer
public_repos38
account_age_days2.974

Paketpflege

100Exzellent
Wie die Bewertung erfolgt
25/25Veröffentlicht & auflösbar — 1 Paket(e) auf pypi
35/35Veröffentlichungsaktualität — letzte Veröffentlichung vor 11 Tagen
20/20Versionshistorie — 76 veröffentlichte Versionen
20/20Nicht veraltet — aktiv, nicht veraltet oder zurückgezogen
Verwendete Eingangsdaten
packagespersonal_knowledge_library
ecosystemspypi
any_deprecatednein
min_days_since_publish11

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

78Gut · 20 % des Gesamtindex
Wie die Bewertung erfolgt
24/24CI-Workflows — 3 Workflow(s)
24/24Tests vorhanden
16/16Linter-Konfiguration — .pylintrc
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — keine Daten
Verwendete Eingangsdaten
has_cija
has_testsja
has_editorconfignein
has_linter_configja
has_precommit_confignein
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): OpenSSF Scorecard: CI-Tests. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
0/15Dokumentations-/Homepage-Site
10/10Repository-Beschreibung
10/10Topics — 3 Topics
0/10Wiki
Verwendete Eingangsdaten
topicsknowledge-graph, wikidata, wikidata-api
has_wikinein
homepage
has_readmeja
has_docs_dirja
has_descriptionja

Sicherheit

Sind die sichtbaren Sicherheits- und Lieferkettenpraktiken belastbar, ohne ungeklärte Exposition gegenüber Hochrisikojurisdiktionen?

52Mittel · 16 % des Gesamtindex

Sicherheitslage

40Gefährdet
Wie die Bewertung erfolgt
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 — keine Daten
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.5Lizenz — 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 — keine Daten
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 — keine Daten
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated15
scorecard_versionv5.5.0
checks_inconclusive3
scorecard_aggregate4
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): ci_tests, packaging, signed_releases. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
35/35Direkte Abhängigkeiten ohne bekannte Advisories — keine direkte Abhängigkeit trägt ein bekanntes Advisory
25/25Indirekte Abhängigkeiten ohne bekannte Advisories — keine indirekte Abhängigkeit trägt ein bekanntes Advisory
0/40Keine offenen Advisories — kein Advisory trägt ein Veröffentlichungsdatum
Verwendete Eingangsdaten
sourceosv
advisories0
affected_packages0
assessed_packages26
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Keine offenen Advisories. Die verbleibenden Gewichte wurden renormalisiert. Abgeglichen wurde die Laufzeit-Abhängigkeitshülle von pypi:personal_knowledge_library@4.3.3 — das, was die Installation des veröffentlichten Pakets nach sich zieht — mit 26 Paketen. Erreichbarkeit wird nicht analysiert.

AI Readiness

Wie gut ist das Repository dafür ausgestattet, mit KI-Coding-Agenten entwickelt und gepflegt zu werden? Ein unabhängiges, experimentelles Badge — Gewicht 0,0, es wird eigenständig ausgewiesen und verändert den Gesamt-Gesundheitswert nicht.

39Gefährdet · 0 % des Gesamtindex
Wie die Bewertung erfolgt
0/45Agentenanweisungen — keine CLAUDE.md / AGENTS.md / Editor-Regeln
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 100 von 100 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share1
agent_instruction_files
agent_instruction_max_bytes
Wie die Bewertung erfolgt
0/18Bootstrap mit einem Befehl
22/22Automatisierte Tests
11/11Lint-/Format-Konfiguration — .pylintrc
0/11Statische Typprüfung
0/10Reproduzierbare Umgebung
0/10Belegte Agentenpraxis — keine von Agenten verfassten Commits unter den letzten 100
0/8Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfiles
has_dockerfilenein
typed_languagenein
bootstrap_files
has_devcontainernein
has_linter_configja
typecheck_configs
agent_commit_share0
toolchain_manifests
dependency_bot_commit_share0
Wie die Bewertung erfolgt
0/45Typprüfbarer Code — Python ohne Typprüfungs-Konfiguration
53.2/55Handhabbare Dateigrößen — 3/91 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languagePython
largest_source_bytes106.475
source_files_sampled91
oversized_source_files3
Wie die Bewertung erfolgt
0/40API-Schema (OpenAPI/GraphQL/proto)
0/20MCP-Server
40/40Lauffähige Beispiele — samples
Verwendete Eingangsdaten
example_dirssamples
has_mcp_signalnein
api_schema_files

Eckdaten

3GitHub-Sterne
2Mitwirkende
204Commits, letzte 12 Monate
11Tage seit letztem Push
63Releases
1Bus-Faktor
0offene Issues
PyPIPaket-Ökosysteme

Weitere Details

Stern- und Fork-Verlauf 3 ★ / 0 ⇿
3Sterne
12Releases

Wann jeder Stern und Fork hinzugefügt wurde, von GitHub erfasst und nach Tagen gruppiert. Das kumulierte Wachstum steht direkt über den täglichen Zugängen, aus denen es besteht, sodass beide gegeneinander lesbar sind: stetiger organischer Zuwachs sieht ganz anders aus als ein abrupter, kurzlebiger Ausschlag. Wo dieser Unterschied messbar ist, wird er als Wachstumsauthentizität ausgewiesen.

12233312025-032025-072025-11
Major 1Minor 4Patch 7
OpenSSF Scorecard 4.0 / 10
4.0Gesamtwert

Unabhängige, werkzeugneutrale Sicherheitsbewertung durch das quelloffene OpenSSF Scorecard. Jede Prüfung honoriert eine Sicherheits-Praxis, nicht das Werkzeug eines bestimmten Anbieters. Prüfungen, die Scorecard nicht ermitteln konnte, sind mit k. A. markiert und vom Sicherheitswert ausgeschlossen (nie als null gezählt).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
k. A.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
k. A.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
k. A.Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
Direkte Abhängigkeiten 11
RegistryPaketVersionsvorgabeManifest
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
Alle Abhängigkeiten 87

Vollständig aufgelöster Abhängigkeitssatz aus dem GitHub-Abhängigkeitsgraphen: 11 direkte und 76 indirekte (transitive) Pakete. Die transitive Hülle ist vollständig, wenn das Repository eine Lockfile eincheckt.

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

Die Installation von pypi:personal_knowledge_library@4.3.3 zieht 26 Pakete nach sich, direkt und transitiv: 0 tragen bekannte Advisories, davon 0 direkte Abhängigkeiten.

Keine bekannten Advisories betreffen die bewerteten Abhängigkeiten.

Ein Advisory bedeutet, dass die im Abhängigkeitsgraphen erfasste Version in den betroffenen Bereich eines Advisories fällt. Erreichbarkeit wird nicht analysiert, und der Graph enthält Entwicklungs- und Test-Pins — ein Fund kann das Werkzeug betreffen und nicht die ausgelieferte Software.

JSON-Rohbericht maschinenlesbar
{
  "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"
}

Bewertungen sind Signale, keine Garantien. Sie spiegeln öffentlich sichtbare Praxis auf GitHub wider — kein Code-Audit und keine Sicherheitsgarantie.

Fehlende Daten werden ausgeschlossen und die Gewichte neu normiert, nie als null bewertet. Die Methodik ist versioniert und offen: Metriken v1.13.0, Schema v0.26.0 — vollständige Methodik · Metriken-Wiki.

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte StatistikenPyPI.