Öffentliches Register
Software-GesundheitsberichtSchema 0.27.0 · Metriken 1.13.0 · 2026-07-29 12:22 UTC

glemsom / dkvmmanager

DKVM Manager

GoKeine Lizenz erkannt★ 0 Sterne⑂ 0 Forksseit Apr. 2026Auf GitHub ansehen ↗

glemsom/dkvmmanager erreicht einen Gesundheitsindex von 55 von 100 und liegt damit im Bereich Mittel. Am stärksten schneidet es bei Vitality (76/100) ab, am schwächsten bei Community & Adoption (25/100). Zuletzt vor 9 Tagen aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

55
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.

55
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

Glenn SommerPersönliches Konto
18 Follower28 öffentliche Reposseit Feb. 2011

Dieses Repository gehört einem persönlichen Konto. Ein Projekt mit nur einem Eigentümer trägt ein höheres Kontinuitätsrisiko als ein organisationsgetragenes.

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlicht
Gogithub.com/glemsom/dkvmmanagerv0.2.6-38vor 9 Tagen

Metriken nach Kategorie

Vitalität

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

76Gut · 22 % des Gesamtindex
Wie die Bewertung erfolgt
28.8/36Push-Aktualität — letzter Push vor 9 Tagen
10.4/36Commit-Rhythmus — 15/52 Wochen mit Commits
18/18Commit-Volumen — 358 Commits im letzten Jahr
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
Verwendete Eingangsdaten
commits_last_year358
human_commit_share1
days_since_last_push9
active_weeks_last_year15
Wie die Bewertung erfolgt
27/27Liefert Releases aus — 38 Releases veröffentlicht
36/36Release-Aktualität — letztes Release vor 9 Tagen
27/27Release-Rhythmus — ein Release etwa alle 3,3 Tage
0/10OpenSSF Scorecard: Signed-Releases — Project has not signed or included provenance with any releases.
Verwendete Eingangsdaten
releases_count38
latest_release_tagv0.2.6
releases_from_tagsnein
days_since_latest_release9
mean_days_between_releases3,3

Community & Verbreitung

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

25Kritisch · 18 % des Gesamtindex
Wie die Bewertung erfolgt
0/60Stars — 0 Stars
0/25Forks — 0 Forks
0/15Watcher — 0 Watcher
Verwendete Eingangsdaten
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
22.5/22.5README
0/22.5Lizenz — keine Lizenzdatei erkannt
18/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
6.3/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licensenein
has_contributingja
has_issue_templatenein
has_code_of_conductnein
has_pull_request_templateja

Nachhaltigkeit & Governance

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

57Mittel · 24 % des Gesamtindex
Wie die Bewertung erfolgt
9/54Bus-Faktor — 1 Beitragende decken die Hälfte aller Commits ab
0/22.5Commit-Verteilung — wichtigste beitragende Person verfasste 100 % der Commits
1.4/13.5Breite der Beitragenden — 1 Beitragende
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Verwendete Eingangsdaten
bus_factor1
contributors_sampled1
top_contributor_share1
Wie die Bewertung erfolgt
46.8/46.8Issue-Lösungsquote — 100 % der Issues geschlossen
37.6/38.3PR-Annahme — 60/61 entschiedene PRs gemergt
0/15OpenSSF Scorecard: Code-Review — Found 0/21 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs60
open_issues0
closed_issues90
issue_closed_ratio1
closed_unmerged_prs1
Wie die Bewertung erfolgt
10/30Organisatorische Trägerschaft — persönliches (Nutzer-)Konto
0/20Verifizierte Domain — für Nutzerkonten nicht anwendbar
9.2/25Reichweite des Inhabers — 18 Follower von glemsom
22.6/25Kontohistorie — 28 öffentliche Repos, Kontoalter ca. 15 Jahre
Verwendete Eingangsdaten
followers18
owner_typeUser
is_verified
owner_loginglemsom
public_repos28
account_age_days5.653
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Verifizierte Domain. Die verbleibenden Gewichte wurden renormalisiert.

Paketpflege

100Exzellent
Wie die Bewertung erfolgt
25/25Veröffentlicht & auflösbar — 1 Paket(e) auf go
35/35Veröffentlichungsaktualität — letzte Veröffentlichung vor 9 Tagen
20/20Versionshistorie — 38 veröffentlichte Versionen
20/20Nicht veraltet — aktiv, nicht veraltet oder zurückgezogen
Verwendete Eingangsdaten
packagesgithub.com/glemsom/dkvmmanager
ecosystemsgo
any_deprecatednein
min_days_since_publish9

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

71Gut · 20 % des Gesamtindex
Wie die Bewertung erfolgt
24/24CI-Workflows — 3 Workflow(s)
24/24Tests vorhanden
0/16Linter-Konfiguration
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 11 out of 11 merged PRs checked by a CI test -- score normalized to 10
Verwendete Eingangsdaten
has_cija
has_testsja
has_editorconfignein
has_linter_confignein
has_precommit_confignein
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
0/15Dokumentations-/Homepage-Site
10/10Repository-Beschreibung
0/10Topics
10/10Wiki
Verwendete Eingangsdaten
topics
has_wikija
homepage
has_readmeja
has_docs_dirja
has_descriptionja

Sicherheit

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

38Gefährdet · 16 % des Gesamtindex

Sicherheitslage

38Gefä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
2.5/2.5CI-Tests — 11 out of 11 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/21 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
0/2.5Lizenz — license file not detected
7.5/7.5Maintained — 30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
1/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 2
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — Project has not signed or included provenance with any releases.
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
6.8/7.5Vulnerabilities — 1 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated18
scorecard_versionv5.5.0
checks_inconclusive0
scorecard_aggregate3,8

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.

72Gut · 0 % des Gesamtindex
Wie die Bewertung erfolgt
45/45Agentenanweisungen — AGENTS.md
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 98 von 100 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share0,98
agent_instruction_filesAGENTS.md
agent_instruction_max_bytes1.230
Wie die Bewertung erfolgt
18/18Bootstrap mit einem Befehl — Makefile
22/22Automatisierte Tests
0/11Lint-/Format-Konfiguration
11/11Statische Typprüfung — Go (statisch typisiert)
10/10Reproduzierbare Umgebung — Dockerfile, lockfile
0/10Belegte Agentenpraxis — keine von Agenten verfassten Commits unter den letzten 100
0/8Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet
2/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 2
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfilesgo.sum
has_dockerfileja
typed_languageja
bootstrap_filesMakefile
has_devcontainernein
has_linter_confignein
typecheck_configs
agent_commit_share0
toolchain_manifestsgo.mod
dependency_bot_commit_share0
Wie die Bewertung erfolgt
45/45Typprüfbarer Code — Go (statisch typisiert)
55/55Handhabbare Dateigrößen — 0/193 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languageGo
largest_source_bytes54.111
source_files_sampled193
oversized_source_files0
Wie die Bewertung erfolgt
0/40API-Schema (OpenAPI/GraphQL/proto)
0/20MCP-Server
40/40Lauffähige Beispiele — examples
Verwendete Eingangsdaten
example_dirsexamples
has_mcp_signalnein
api_schema_files

Eckdaten

0GitHub-Sterne
1Mitwirkende
358Commits, letzte 12 Monate
9Tage seit letztem Push
38Releases
1Bus-Faktor
0offene Issues
GoPaket-Ökosysteme

Warnungen zur Datenerhebung

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Weitere Details

OpenSSF Scorecard 3.8 / 10
3.8Gesamtwert

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-29 12:21 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests11 out of 11 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/21 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
0Licenselicense file not detected
10Maintained30 commit(s) and 30 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
2Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 2
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
0Signed-ReleasesProject has not signed or included provenance with any releases.
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
9Vulnerabilities1 existing vulnerabilities detected
Direkte Abhängigkeiten 7
RegistryPaketVersionsvorgabeManifest
Gocharm.land/bubbles/v2v2.1.0go.mod
Gocharm.land/bubbletea/v2v2.0.7go.mod
Gocharm.land/lipgloss/v2v2.0.3go.mod
Gogithub.com/charmbracelet/x/ansiv0.11.7go.mod
Gogithub.com/go-viper/mapstructure/v2v2.5.0go.mod
Gogithub.com/spf13/viperv1.21.0go.mod
Gogolang.org/x/sysv0.46.0go.mod
Alle Abhängigkeiten nicht erhoben

Der aufgelöste Abhängigkeitssatz konnte für diesen Bericht nicht erhoben werden: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

JSON-Rohbericht maschinenlesbar
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 1382,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Go": 1357729,
        "Makefile": 6223,
        "Dockerfile": 1329
      },
      "pushed_at": "2026-07-20T05:18:24Z",
      "created_at": "2026-04-12T10:57:47Z",
      "owner_type": "User",
      "updated_at": "2026-07-20T05:18:28Z",
      "description": "DKVM Manager",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": null,
      "default_branch": "main",
      "license_spdx_raw": null,
      "primary_language": "Go",
      "significant_languages": [
        "Go"
      ]
    },
    "owner": {
      "blog": "https://glemsomtechs.blogspot.com/",
      "name": "Glenn Sommer",
      "type": "User",
      "login": "glemsom",
      "company": null,
      "location": null,
      "followers": 18,
      "avatar_url": "https://avatars.githubusercontent.com/u/601804?v=4",
      "created_at": "2011-02-05T11:13:24Z",
      "is_verified": null,
      "public_repos": 28,
      "account_age_days": 5653
    },
    "license": {
      "state": "absent",
      "spdx_id": null,
      "raw_spdx": null,
      "file_present": false,
      "scorecard_found": false,
      "profile_has_license": false
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.2.6",
          "kind": "patch",
          "published_at": "2026-07-20T05:18:59Z"
        },
        {
          "tag": "v0.2.5",
          "kind": "patch",
          "published_at": "2026-07-11T16:54:33Z"
        },
        {
          "tag": "v0.2.4",
          "kind": "patch",
          "published_at": "2026-07-10T20:37:50Z"
        },
        {
          "tag": "v0.2.3",
          "kind": "patch",
          "published_at": "2026-07-06T19:24:11Z"
        },
        {
          "tag": "v0.2.2",
          "kind": "patch",
          "published_at": "2026-07-04T08:12:00Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-07-02T14:41:20Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-06-22T10:55:27Z"
        },
        {
          "tag": "v0.1.31",
          "kind": "patch",
          "published_at": "2026-06-21T16:10:27Z"
        },
        {
          "tag": "v0.1.30",
          "kind": "patch",
          "published_at": "2026-06-21T09:24:48Z"
        },
        {
          "tag": "v0.1.29",
          "kind": "patch",
          "published_at": "2026-06-20T14:03:50Z"
        },
        {
          "tag": "v0.1.28",
          "kind": "patch",
          "published_at": "2026-06-19T07:24:43Z"
        },
        {
          "tag": "v0.1.27",
          "kind": "patch",
          "published_at": "2026-06-17T18:56:45Z"
        },
        {
          "tag": "v0.1.26",
          "kind": "patch",
          "published_at": "2026-06-17T18:48:00Z"
        },
        {
          "tag": "v0.1.25",
          "kind": "patch",
          "published_at": "2026-06-10T17:08:06Z"
        },
        {
          "tag": "v0.1.24",
          "kind": "patch",
          "published_at": "2026-06-09T18:01:33Z"
        },
        {
          "tag": "v0.1.23",
          "kind": "patch",
          "published_at": "2026-05-31T14:50:58Z"
        },
        {
          "tag": "v0.1.22",
          "kind": "patch",
          "published_at": "2026-05-31T13:14:44Z"
        },
        {
          "tag": "v0.1.21",
          "kind": "patch",
          "published_at": "2026-05-31T06:33:00Z"
        },
        {
          "tag": "v0.1.20",
          "kind": "patch",
          "published_at": "2026-05-23T06:57:04Z"
        },
        {
          "tag": "v0.1.19",
          "kind": "patch",
          "published_at": "2026-05-19T19:45:24Z"
        },
        {
          "tag": "v0.1.18",
          "kind": "patch",
          "published_at": "2026-05-18T18:31:17Z"
        },
        {
          "tag": "v0.1.17",
          "kind": "patch",
          "published_at": "2026-05-17T13:07:36Z"
        },
        {
          "tag": "v0.1.16",
          "kind": "patch",
          "published_at": "2026-05-16T13:14:04Z"
        },
        {
          "tag": "v0.1.15",
          "kind": "patch",
          "published_at": "2026-05-15T19:25:26Z"
        },
        {
          "tag": "v0.1.14",
          "kind": "patch",
          "published_at": "2026-05-15T17:26:59Z"
        },
        {
          "tag": "v0.1.13",
          "kind": "patch",
          "published_at": "2026-05-15T15:43:06Z"
        },
        {
          "tag": "v0.1.12",
          "kind": "patch",
          "published_at": "2026-05-15T13:14:09Z"
        },
        {
          "tag": "v0.1.11",
          "kind": "patch",
          "published_at": "2026-05-05T19:47:13Z"
        },
        {
          "tag": "v0.1.10",
          "kind": "patch",
          "published_at": "2026-05-04T19:26:10Z"
        },
        {
          "tag": "v0.1.9",
          "kind": "patch",
          "published_at": "2026-05-04T16:59:33Z"
        },
        {
          "tag": "v0.1.8",
          "kind": "patch",
          "published_at": "2026-05-03T19:05:06Z"
        },
        {
          "tag": "v0.1.7",
          "kind": "patch",
          "published_at": "2026-05-03T09:34:51Z"
        },
        {
          "tag": "v0.1.6",
          "kind": "patch",
          "published_at": "2026-05-03T07:43:07Z"
        },
        {
          "tag": "v0.1.5",
          "kind": "patch",
          "published_at": "2026-05-03T04:40:49Z"
        },
        {
          "tag": "v0.1.4",
          "kind": "patch",
          "published_at": "2026-05-01T19:33:17Z"
        },
        {
          "tag": "v0.1.3",
          "kind": "patch",
          "published_at": "2026-04-30T18:27:17Z"
        },
        {
          "tag": "v0.1.2",
          "kind": "patch",
          "published_at": "2026-04-30T16:18:42Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-04-28T16:24:01Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "8dbc98e5dbbf97585df2d06cb5e48c7e69faf8e5",
          "body": null,
          "is_bot": false,
          "headline": "chore: release v0.2.6",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-20T05:17:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7100c22d2b237dc945eb11ce77efba7ce5a34597",
          "body": "ListItemSelectedStyle bold assertion now respects TERM=linux\nenvironment where bold is intentionally skipped.\n\nAdd accessibility_test.go helper.",
          "is_bot": false,
          "headline": "test: skip bold check on linux term (vgacon workaround)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-12T08:14:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "27c85ea95817ec570a616b37b1456285386a3840",
          "body": "…OPPED]\n\nWhen guest shuts down internally, monitorProcess() sets r.running=false\nand r.qmpClient=nil before closing r.done. The status poll fires in\nthat window, sees nil QMP client, and unconditionally returns 'starting'\nwithout checking IsRunning().\n\nFix both initialStatus() and pollStatus() to check IsRunning() when\nQMP client is nil. If process has exited, return 'stopped'.\n\nFixes the visible [STARTING] -> [STOPPED] flicker becoming permanent.\n\ncloses #152",
          "is_bot": false,
          "headline": "fix(tui): status shows [STARTING] after guest shutdown instead of [ST…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-11T16:53:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0644b29e8c235339fe2d9114f484125a27e60d37",
          "body": null,
          "is_bot": false,
          "headline": "chore: release v0.2.4",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T20:37:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "59018a889ef6dd083f4438b188774a00b118ba88",
          "body": "fix(vm): goroutine & channel lifecycle cleanup",
          "is_bot": false,
          "headline": "Merge pull request #151 from glemsom/fix/goroutine-lifecycle-cleanup",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T19:37:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3aa44f94fa82fc734a28a00f9a4bde6bcfbe458b",
          "body": null,
          "is_bot": false,
          "headline": "docs(tickets): mark ticket 3 items as done",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T19:35:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2a882d9ae0729701946a62a4552b4742de4ececa",
          "body": "Bugs: 7, 8, 18 from bugs.md\n\n- qmpWatchdog: select on r.done to exit on VM cleanup\n- stop-script goroutines: track with WaitGroup, wait in Cleanup()\n- closePersistLog: replace select guard with sync.Once for thread-safe idempotency\n\nAdd tests:\n- TestClosePersistLogConcurrent: 10 concurrent callers no panic\n- TestQMPWatchdogExitsOnDone: watchdog exits when r.done closed\n- TestCleanupWaitsForStopScriptGoroutines: Cleanup waits for tracked goroutines",
          "is_bot": false,
          "headline": "fix(vm): goroutine & channel lifecycle cleanup (ticket 3)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T19:35:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2cd78a1c5acfc07fb26b67d4c4cfa5304b53fe6f",
          "body": "Fix TUI display bugs (Ticket 6)",
          "is_bot": false,
          "headline": "Merge PR #150: Fix TUI display bugs (Ticket 6)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T19:26:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4082c9d95ab80bced6049bef2038663129695276",
          "body": "… vm_running.go VMStatusUpdateMsg handler (keep origin/main cleaner version)",
          "is_bot": false,
          "headline": "Merge branch 'main' into fix/tui-display-bugs-6 # resolve conflict in…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T19:26:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d1835a54ccfba17e061b8b556b100588840ff87b",
          "body": null,
          "is_bot": false,
          "headline": "docs: update tickets.md and bugs.md with Ticket 6 completion",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T19:21:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bbf678f9e8be73f75492ec1c3ed65fb0112ca2c8",
          "body": "- Stop re-arming status tick when VM is stopping/stopped (Bug 10)\n- Add distinct [STOPPING] style using error color (Bug 11)\n- Normalize memory display to consistent '%.1f GB' format (Bug 12)\n- Fix effectiveWidth inconsistency using 'width' param (Bug 13)\n\nAdds tests:\n- StatusUpdateStopsPollWhenStop\n[…]\npdateStopsPollWhenStopped\n- StatusUpdateReArmsPollWhenNonTerminal\n- MemoryFormatConsistent\n- ViewStoppingStyle (stopping/finish use [STOPPING] not [STARTING])\n- ViewNarrowWidth (rendering at <80 cols)",
          "is_bot": false,
          "headline": "fix: TUI display bugs (Ticket 6)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T19:21:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cdba40a2bba55250120002646b20c223252e4d97",
          "body": "- StatusUpdateMsg: don't re-arm poll tick when VM status is\n  terminal (stopping/stopped). Prevents stale ticks overwriting\n  status or issuing commands after teardown.\n- effectiveWidth: remove 80-col clamping. Individual render\n  functions handle min-width as needed.\n- memory display: always show GB with one decimal instead of\n  conditional GB/MiB logic.\n- vm_running_test: add TestVMRunningModelStatusUpdateStopped\n  and TestVMRunningModelStatusUpdateStopping.",
          "is_bot": false,
          "headline": "fix(tui): terminal status freeze, width clamp, memory display (#149)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T19:14:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "df6531add331ce75c91eb0b44db85f32d2d9810d",
          "body": "Bug 6: readStatCPUJiffies used LastIndexByte on string(data) with no\nvalidation of opening '('. If comm field contains ')' characters\n(valid in Linux via prctl(PR_SET_NAME)), the old parsing assumed the\nlast ')' is the closing paren. This is correct by kernel format, but\nthe code lacked a guard for \n[…]\nntaining ')' chars\n- CommOnlyClosingParen: comm that is just ')'\n- EmptyComm: empty comm field '()'\n- NoOpeningParen: malformed without '(' but with ')'\n- SpecialCharsComm: multiple parens inside comm",
          "is_bot": false,
          "headline": "fix: robust /proc/stat parsing for comm field with ')' chars",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T18:29:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ee8007c8fe108dccc5c16c00e573fe73372b0fa7",
          "body": null,
          "is_bot": false,
          "headline": "tickets.md: mark ticket 7 items as done",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T18:21:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "25b3e1b6a6092eb2db97022ce8e6cce1d9526f68",
          "body": "Three independent fixes for LOW severity bugs from code review:\n\n- buildConfigListAdapter: guard against empty items slice to prevent\n  index-out-of-range panic when registry has no config menu items\n\n- config.Load/Save: use local viper.New() instances instead of global\n  viper singleton to eliminat\n[…]\nd tests:\n- TestBuildConfigListAdapterEmpty: no panic with empty registry\n- TestFormatErrorNilResult: nil result returns safe message\n- TestConcurrentLoad: no race on viper state with concurrent Load()",
          "is_bot": false,
          "headline": "fix: edge case panics and test pollution (ticket 7)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T18:21:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b90022bf7e34567fba5f6687c9c9654a0efec62a",
          "body": "…ader\n\nfix(vm-runner): prevent channel deadlocks when buffer full with no reader",
          "is_bot": false,
          "headline": "fix(vm-runner): prevent channel deadlocks when buffer full with no re…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T18:16:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bb14d208b5da813b949cf7f4a13e0697544a38ae",
          "body": "…ader\n\nBug 1: forwardViewLine drop-oldest pattern blocks forever when subscriber\nchannel full and no goroutine reading. Inner select takes default, then\nunbuffered 'ch <- line' blocks.\n\nBug 2: connectQMP writes to logChan after persistLogLoop exits. With no\nreader, buffer fills and subsequent writes\n[…]\n full, drop silently\n\nUsed in: forwardViewLine, readOutput, readScriptOutput, Subscribe\nstaging-drain, and all connectQMP log writes.\n\nAdd 4 tests proving no deadlock with full channels and no reader.",
          "is_bot": false,
          "headline": "fix(vm-runner): prevent channel deadlocks when buffer full with no re…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T18:11:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d863296876f108fdf81fd0cf4bb08f083cb44ce5",
          "body": "Add comprehensive security documentation covering:\n- SSH password handling (chpasswd, lbu commit)\n- PCI passthrough security (IOMMU, DMA, GPU reset attacks)\n- Configuration file permissions\n- Log file exposure (qemu.log, dkvm.log)\n- Command execution and privileges\n- Network exposure (VNC binding)\n- QMP socket access control\n\nCross-reference from scripts-and-ssh, hardware-config, setup,\nrunning-vms, power-and-save, and vm-management docs.\nAdd to learning path and documentation index.",
          "is_bot": false,
          "headline": "docs: add security considerations documentation (#112)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T17:43:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "12da8cdc06ddf1be2dc90c16db345c5cfb94dcf3",
          "body": "…l info panel\n\n- Remove BlockDevices rendering loop from renderInfoPanel\n- Remove NetDevices rendering loop from renderInfoPanel\n- Remove Balloon rendering from renderInfoPanel\n- Remove corresponding height calculations from calculateInfoHeight\n- Remove unused formatRate function\n- Remove 7 test functions: BlockMetricsUpdate, BlockMetricsRendering,\n  MultipleDisksRendering, BalloonUpdate, BalloonRendering, BalloonEmpty,\n  TestFormatRate\n\nCloses #143",
          "is_bot": false,
          "headline": "Remove Disk I/O, Network I/O, and Balloon sections from VMRunningMode…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T17:28:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "41e9aeeaf9dfcc9e9e5fea480d3c7394e901a1e3",
          "body": "B1 — Remove Network Metrics section from info panel (nested inside\nBalloonBytes check, causing netdev to vanish when no balloon driver).\nRemoved entirely per feature decision.\n\nB2 — Duplicate '─── QEMU Output ───' separator rendered in both\nrenderInfoPanel() and renderLogContent(). Removed from info\n[…]\ne.\n\nB5 — Dead threads []int field populated on every status update but\nnever rendered. Removed field and the dead QueryCPUsFast() calls in\ninitialStatus() and pollStatus() that only served this field.",
          "is_bot": false,
          "headline": "fix(vm_running): 5 bugs in status view",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-10T16:33:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "591b81eeef7c4b127e96e1a1b7d7b7e179aa6694",
          "body": "- rename AGENTS.md '## Agent conventions' -> '## Agent skills' block\n- add PRs as triage surface + Wayfinding operations to issue-tracker.md\n- update domain.md skill refs: /grill-with-docs -> /domain-modeling",
          "is_bot": false,
          "headline": "sync agent skill docs with updated skill templates",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-09T21:24:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "82e384ddf964c4e1b906ea72cab665356f7128b3",
          "body": "…info panel\n\nDeletes sparklineBuffer struct/methods, cpuTrend/memTrend fields,\nsparkline init, push calls, rendering blocks, and height+=2.\nRemoves sparkline.go, sparkline_test.go, and all sparkline/trend tests\nfrom vm_running_test.go. Adjusts height assertions by -2.\n\nCloses #142",
          "is_bot": false,
          "headline": "refactor: remove CPU and memory trend sparklines from VMRunningModel …",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-09T21:13:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dd72ffdc60a5ac6197fb51cd465423d9fde13eb3",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump version to 0.2.3",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-06T19:23:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a6636f96cc1f36000b8e60df78613c7ac73de60c",
          "body": "Add full vertical slice for query-netdev QMP command:\n\n- NetStat type in metrics.go with per-device RX/TX bytes and packets\n  and derived per-second rates (RXBps, TXBps, RXPps, TXPps)\n- Metrics.NetDevices field populated by Snapshot() via delta math\n- QMPNetDeviceStats / QMPNetDeviceIO types for que\n[…]\nrevNetStats + prevNetTime for delta computation\n- Network section in renderInfoPanel capped at 2 devices with\n  (+N more) overflow indicator\n- calculateInfoHeight accounts for net section\n\nCloses #136",
          "is_bot": false,
          "headline": "feat: add live network I/O metrics to running VM view (#136) (#141)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-06T19:15:09Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "112b05b0c0290909b976642e96414e7b15162c38",
          "body": "…#140)\n\nAdd sparklineBuffer circular buffer type (cap=30 = 60s window) and\nwire it into VMRunningModel. On each VMMetricsUpdateMsg, push aggregate\nCPU% and HostRSSBytes into cpuTrend and memTrend buffers.\n\nRender two sparkline lines in renderInfoPanel():\n- CPU: braille sparkline + current% + peak%\n-\n[…]\nille sparkline + current RSS + total guest memory\n\nPlaceholder dots (U+22EF) shown when buffer empty.\ncalculateInfoHeight() adds 2 for sparkline lines.\nLazy-init for zero-valued buffers (test safety).",
          "is_bot": false,
          "headline": "feat: add CPU and memory trend sparklines to running VM view (#137) (…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-06T18:56:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9213e9aedf129472eaad9ecd12f5ef8e74d35736",
          "body": "…levelToDotCount",
          "is_bot": false,
          "headline": "fix: export RenderBrailleSparkline, fix resample edge case, simplify …",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-06T18:41:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d8aaed242233351690bbb7d7bcce461dfc018bb6",
          "body": "Co-authored-by: glemsom <glemsom@gmail.com>",
          "is_bot": false,
          "headline": "feat: add RenderBrailleSparkline helper function",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-06T18:39:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26a6b5804fe4c1f4f140121ba48f8307156d08fb",
          "body": "…egistry\n\nCloses #131\r\nCloses #138\r\n\r\nUnifies all sub-views under ViewRegistry dispatch, removing stale MainModel fields and manual switch routing. Also removes redundant CI version generation step (committed version_gen.go is source of truth).",
          "is_bot": false,
          "headline": "refactor: unify ViewVMSelect, ViewVMDelete, ViewVMRunning under ViewR…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-06T17:03:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0fb2642d326b7293969abc3218fc1df0a8de5cb1",
          "body": "version_gen.go is committed to VCS with correct value. The Makefile's\ngenerate-version handles local dev. CI regeneration was redudant and\nhad a quoting bug (single quotes prevented 0.2.2 expansion).",
          "is_bot": false,
          "headline": "fix(ci): remove redundant Generate version step",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-06T17:02:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2e074c17fca2a46e77070a798238fc1b439ec578",
          "body": "- Remove hardcoded var Version from version.go — now provided by\n  generated version_gen.go (single source of truth: VERSION file)\n- Add version_gen.go generated from VERSION (v0.2.2, matching file)\n- Add generate-version Makefile target, wire into test dependency\n- Add 'Generate version' step to CI test workflow\n- Update bump-version target to use generate-version\n\nFixes TestVersionMatchesVERSIONFile failing because committed\nversion.go had var Version = \"0.2.1\" while VERSION file is 0.2.2.",
          "is_bot": false,
          "headline": "fix: version from VERSION file via generated version_gen.go",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-06T16:00:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd1b59afc601eba5ed2f7c959e9472a8846b9b82",
          "body": "…egistry\n\n- Fix registry cmd() dispatch: return cmd to BubbleTea runtime instead\n  of calling cmd() synchronously (breaks Tick-based polling)\n- Create VMSelectModel as a proper SubViewModel with its own Update/View\n- Route VMSelect, VMDelete, VMRunning through ViewRegistry instead of\n  manual switch\n[…]\nfy isSubViewActive() to just m.viewRegistry.IsActive()\n- Remove manual view routing fallbacks from update() and\n  delegateToSubView()\n- Update all tests to use new registry-based dispatch\n\nCloses #131",
          "is_bot": false,
          "headline": "refactor: unify ViewVMSelect, ViewVMDelete, ViewVMRunning under ViewR…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-06T15:48:44Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7ef2f1bce6060805acf6bb39c8a000d799d0231e",
          "body": "…nter panic\n\nMainModelConfig.Config is *config.Config — nil when omitted. tui.go\ncreated the config struct without setting Config, causing nil deref\nat init.go:26 on cfg.Config.VMsConfigFile.\n\nFix matches NewMainModel() in init.go:19 which already does\nConfig: config.Load().",
          "is_bot": false,
          "headline": "fix(tui): populate Config field in MainModelConfig to prevent nil poi…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-04T08:11:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "116b26c6f9b4ce7011442af876701f0c6d0f549c",
          "body": null,
          "is_bot": false,
          "headline": "chore: release v0.2.1",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-02T14:37:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1575feb93004ff2a82ed19789bd5343c3ba0925d",
          "body": "- README: s/internal\\/models/internal\\/domain/, add missing packages (theme, explanation, go.mod, Dockerfile)\n- AGENTS.md: add domain, hugepages, version to package list\n- architecture.md: add theme to Package Map; fix disk_add.go→disk_selector.go, tab_model.go→tabs.go\n- vm-config.md: 8× s/internal\\\n[…]\n/models.go/types.go/\n- faq.md, troubleshooting.md: s/power_and_save.go/debug.go/\n- vm-management.md: s/block_device.go/disk_selector_scanner.go/\n- hardware-config.md: s/host_discovery.go/discovery.go/",
          "is_bot": false,
          "headline": "docs: fix stale file references and update project layout",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-01T18:27:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "aa8e4af73b253323715262e20c142efd1adf0157",
          "body": "- Eliminate debugMode/dryRunMode package-level vars in tui/models and vm packages\n- MainModel: replace SetDebugMode/SetDryRunMode/SetSkipMountPointCheck with\n  MainModelConfig struct + NewMainModelWithConfig constructor\n- VMRunner: add dbgMode field, pass debugMode bool to NewVMRunner\n- Manager: add\n[…]\nke explicit debugMode bool instead of reading package-level var\n- Snapshot(): graceful degradation — collect partial metrics even on QMP errors\n- Formatting: struct alignment fixes, blank line cleanup",
          "is_bot": false,
          "headline": "refactor: remove package-level globals, use explicit config/fields",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-01T18:00:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "81de5dc832c1222560adfe8d1d36c8e2bcbb44c2",
          "body": "Replace Reverse(true) cursor rendering with explicit foreground/background\nswap (Background-Primary on Foreground-Background) — SGR 7 (reverse video)\nresets unreliably on 16-color terminals, causing wrong colors after cursor\npasses through a field.\n\nAdd explicit Background(Colors.Background) to all \n[…]\nlimited-color consoles.\n\nUse inline styles instead of pre-defined SelectedTextStyle/FormLabelStyle/\nMutedTextStyle to ensure every rendered segment has both Foreground and\nBackground set consistently.",
          "is_bot": false,
          "headline": "fix(tui): prevent ANSI attribute bleed on 16-color consoles",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-07-01T17:30:01Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1173da5437c2c50a0d5e091a1ee9b8976f60c7cb",
          "body": "Unify Message Dispatch — remove init() + global registry, move handlers to MainModel methods (#129)",
          "is_bot": false,
          "headline": "Merge pull request #133 from glemsom/unify-message-dispatch",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-30T18:53:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "07f15bdc3432962d47259554cfc5560ab2e1b5ed",
          "body": "Remove three coexisting dispatch paths, keep single type-switch pattern.\n- Delete init(), messageHandlers map, RegisterMessageHandler(), MessageHandler type\n- Remove reflect import from message_handlers.go\n- Convert 9 Handle*Msg funcs to MainModel methods (handleVMCreated, etc.)\n- Replace reflect-ba\n[…]\nubViewMsg with direct type-switch\n- Update type-switch in key_handlers.go to call m.handleFoo(msg)\n- Inline handleSubViewOutput() -> handleSubViewMsg()\n- Remove stale TestMessageHandlers_Registry test",
          "is_bot": false,
          "headline": "refactor: unify message dispatch, remove init() + global registry (#129)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-30T18:38:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bbd0bcf6019000a7cd7f77daf08b0b57c1ddbf31",
          "body": "Rename internal/models -> internal/domain (#128)",
          "is_bot": false,
          "headline": "Merge pull request #132 from glemsom/rename-models-to-domain",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-30T18:35:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f3c50461d738d898a0d3075734a15e0fe05d4d80",
          "body": "Resolve import-path collision with internal/tui/models.\nPackage name changes from 'models' to 'domain' everywhere.\n- internal/models -> internal/domain\n- models.go -> types.go, models_test.go -> types_test.go\n- All 67 Go import references updated\n- Doc files updated (CHANGELOG.md, docs/)",
          "is_bot": false,
          "headline": "fix: rename internal/models -> internal/domain (#128)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-30T17:39:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "693aea5c7414e2b7ae62e705b1e75916a215e3fa",
          "body": "On the Linux console (TERM=linux, kernel VGA/framebuffer), SGR reset\n(\\x1b[m) may not reliably clear the bold attribute. When an item was\nselected (bold + dark cyan) then unselected (light gray without bold),\nthe bold persisted via console attribute leak, making previously-\nselected items appear bri\n[…]\nay) alone provides\nsufficient visual distinction on the 16-color palette.\n\nAlso exports IsTERMLinux() from the theme package (was unexported\nisTERMLinux) so the styles package can check terminal type.",
          "is_bot": false,
          "headline": "fix: skip bold on selected list items when TERM=linux",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-30T16:33:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6ecb267c942f4401dbb0fb0ea4f647a448d603d2",
          "body": "The README claimed dkvmmanager can be installed via 'apk add dkvmmanager',\nbut the project is not shipped as an Alpine apk package — there is no\nAPKBUILD, no apk build step, and no .apk release artifact.\n\nReplace the incorrect apk add command with the actual curl-based binary\ndownload that works on Alpine/DKVM hosts.",
          "is_bot": false,
          "headline": "docs: fix Alpine Linux installation in README",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T09:45:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0c370d1c98386eaf917f2b0770df2fafc207d5c8",
          "body": null,
          "is_bot": false,
          "headline": "docs: separate explanatory content from how-to guides",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T06:34:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "acd782524a8a3f088f937ca05729de8b379a6d9b",
          "body": null,
          "is_bot": false,
          "headline": "docs: add config file schema reference",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T06:32:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c09577cb361352b612804d9e488018a76c291933",
          "body": null,
          "is_bot": false,
          "headline": "docs: add backup and restore guide",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T06:31:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fefbfb91f21b6380e7cc7edbcbdd1513b444b522",
          "body": null,
          "is_bot": false,
          "headline": "docs: add learning path to user README",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T06:30:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a127a845a6f941d007b97386febc18befb06682c",
          "body": null,
          "is_bot": false,
          "headline": "docs: deduplicate keybindings tables to single source of truth",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T06:29:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "356b123be31f373f46ca0decc937c65ed6a1def7",
          "body": null,
          "is_bot": false,
          "headline": "docs: add upgrade and migration guide",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T06:29:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e9afd35638b3242908e7999dbac3b55e2f6a3aec",
          "body": null,
          "is_bot": false,
          "headline": "docs: link CHANGELOG.md from README documentation table",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T06:28:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b0c242a6ea88e50d6a0ec81fdd42afbe137abe1e",
          "body": "docs: consolidate documentation — add missing pages, link orphans, polish README",
          "is_bot": false,
          "headline": "Merge pull request #116 from glemsom/docs/consolidation",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T05:34:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ab46307049b985ee795c5275806333dcc7f42b87",
          "body": "…lish README\n\nCloses #105 — broken link tutorial.md → troubleshooting.md (now exists)\nCloses #106 — link orphaned files from index pages\nCloses #107 — add troubleshooting guide (8 issues documented)\nCloses #108 — add installation guide for pre-built binaries\nCloses #109 — add FAQ page (9 questions)\nCloses #111 — consolidate CLI flags into single reference doc\nCloses #114 — add README badges and visual polish\nCloses #115 — document example scripts in examples/README.md",
          "is_bot": false,
          "headline": "docs: consolidate documentation — add missing pages, link orphans, po…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T05:31:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8616de5ee5ec09dc06ddf6af730d8a8bb0835f0b",
          "body": "Replace numbered lists with GitHub-native Mermaid diagrams:\n- Runner Lifecycle: sequence diagram with concurrent poll loops\n- Message Dispatch Flow: decision flowchart with routing chain",
          "is_bot": false,
          "headline": "docs: convert lifecycle and message flow to Mermaid diagrams",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-23T05:11:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3369e9e9e9c0e798d80fbbf3102d9e6a3f403fb9",
          "body": "4 fields were undocumented in user docs: reserved_mem_mb, bios_code,\nbios_vars, log_file, plus network_bridge default.\n\nAdd 'Configuration File' section covering all 10 config fields with\ndefaults and descriptions.\n\nAll 12 Configuration tab menu items already documented across\nvm-management.md, hardware-config.md, scripts-and-ssh.md, storage.md,\npower-and-save.md, keybindings.md.",
          "is_bot": false,
          "headline": "docs: document all config.Config struct fields in setup.md",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T18:56:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eaee7464dabba5a48d38273297a7d2005e587e62",
          "body": "Adds link to parent dkvm repository and context that DKVM Manager\nis the TUI frontend for the DKVM hypervisor stack.",
          "is_bot": false,
          "headline": "docs: clarify README as part of DKVM project",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T17:59:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6c4526ced5a17ea591cfeefc47878a0ba0b357b4",
          "body": "Introduces project overview, features, quick start, CLI flags,\ndocumentation index (user, developer, agent), keybinding quick\nreference, build/test commands, and project layout.\n\n- Links all docs/user/*.md, docs/dev/architecture.md, CONTEXT.md,\n  ADR 0001, CONTRIBUTING.md, and agent workflow docs.\n- Serves as end-user landing page for the repository.",
          "is_bot": false,
          "headline": "docs: add README.md binding all documentation",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T17:19:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ac8341e05cf9e1debefae1c3f9fed108c5c8ee8",
          "body": "Covers start/stop hook scripts (builtin + custom modes) and SSH\npassword configuration. Documents form layouts, keybindings,\nvalidation rules, execution flow, and architecture notes with\nsource code references.",
          "is_bot": false,
          "headline": "docs: create docs/user/scripts-and-ssh.md (#99)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T17:11:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a201b885cdf824c2a6afc68c4fbfaaaf7731ebb7",
          "body": "…entation\n\nCloses #102\n\n- Power Tab: power off and reboot system operations\n- Save Changes: LBU commit to persist configuration\n- Async execution model, message flow, architecture notes\n- Warnings about VM termination and unsaved changes",
          "is_bot": false,
          "headline": "docs: add power-and-save.md — power off, reboot, and LBU commit docum…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T17:09:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "56892963c6bd29ba933a4a48ab9a9aa777e3135b",
          "body": null,
          "is_bot": false,
          "headline": "docs: add storage.md — LV creation and disk management documentation",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T17:05:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "33dcd49f2e20249739231b69d6e0c7944f81d229",
          "body": "…s, PCI/USB passthrough\n\nCloses #98",
          "is_bot": false,
          "headline": "docs: add hardware-config.md — CPU topology, vCPU pinning, CPU option…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T17:02:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3ae876033c836d92d66eef4cfcb8e7f195a88f42",
          "body": "Closes #104\n\nCreate docs/dev/architecture.md covering:\n- Package map with import-direction rule\n- Runner lifecycle from create through teardown\n- View registry and message dispatch flow\n- Form framework internals (ScrollableForm, FormModel, FocusPos)\n- Testing patterns (Mock HostDiscovery, dry-run, table-driven, helpers)\n- Build instructions\n\nAll source references verified against codebase.",
          "is_bot": false,
          "headline": "docs: add developer architecture guide",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T16:58:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "395d32d96690dac285825e920437aa98f2555613",
          "body": "Closes #103\n\nComplete TUI keyboard reference covering:\n- Global keys (quit, tab nav, list nav)\n- VMs tab, Configuration tab, Power tab keys\n- Sub-view navigation and ESC behavior\n- VM create/edit form keys by field type (text, toggle, list)\n- File browser keys\n- Disk selector multi-step keys\n- Delete confirmation and VM selection list keys\n- Running VM view keys (running vs stopped state)\n- Mount point warning dismiss\n- Form-specific keys summary (text-entry vs toggle-only forms)",
          "is_bot": false,
          "headline": "docs: create docs/user/keybindings.md — complete keyboard reference",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T16:55:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1b1757c152ab6cf87cc5fa4678e34cce57bb4c44",
          "body": "… metrics, stop\n\nCloses #101\n\nComprehensive user documentation covering:\n- Starting VMs and startup sequence\n- Running view layout (info panel + log viewport)\n- Log viewer lifecycle (seeding, subscription, dedup, persistence)\n- Status badge states (STARTING, RUNNING, STOPPING, STOPPED)\n- Metrics display (per-vCPU, host process, per-disk I/O, balloon)\n- Graceful stop vs force kill\n- ESC safety behavior\n- Architecture notes (message flow, polling cadence, view bypass)",
          "is_bot": false,
          "headline": "docs: create docs/user/running-vms.md — start VM, log viewer, status,…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T16:54:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b2cd949778f1177b4201953e09f0a5ef223bfd16",
          "body": "Closes #97\n\nComprehensive user documentation covering:\n- VM creation form with all fields and keybindings\n- VM editing with pre-filled form and VM selection\n- VM deletion with confirmation dialog\n- File browser for ISO selection\n- Disk selection flow (file, block device, LVM)\n- Architecture notes: model hierarchy, message flow, form framework",
          "is_bot": false,
          "headline": "docs: create docs/user/vm-management.md — create, edit, delete VMs",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T16:53:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "201a1aea6ba6d486f87c059367f4465dc75f66cb",
          "body": null,
          "is_bot": false,
          "headline": "docs: add setup.md — host setup and prerequisites guide",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T16:48:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ff9142d5a5fd748e1ac17e2dbf0b400853cba2b7",
          "body": "Closes #95",
          "is_bot": false,
          "headline": "docs: create docs/user/README.md — user documentation index",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T16:46:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e8b2e6b165a340870ec4d6136bdb091d5fac2c1b",
          "body": "…erty\n\nQEMU property l3-cache-size-die<N> is DEFINE_PROP_UINT32 expecting raw bytes.\nPreviously passed human-readable strings like '96M' which QEMU rejects with\n'Parameter expects uint64'.\n\nAdd parseSizeToBytes() to convert e.g. '96M' -> 100663296 bytes before\nbuilding the -cpu flag. Supports K/M/G suffixes.",
          "is_bot": false,
          "headline": "fix: convert L3 cache size human string to bytes for QEMU UINT32 prop…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T16:23:40Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ecfc0a04806c9dce80e7f9ddb4a25e2a5532e848",
          "body": "When the Cancel button is focused, the hint text now correctly\nhighlights [ESC] Cancel in green (save style) instead of\nkeeping [Space/Enter] Save highlighted.\n\nFixes:\n- renderButtonPosition: add focused check for cancel key\n- renderButtons: add cancel-focused branch matching save-focused pattern\n\nTest: TestCustomScriptFormSaveCancelFocus verifies both focused states\nand unfocused state.",
          "is_bot": false,
          "headline": "fix: Start/Stop Script Cancel button highlights Cancel when focused",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T14:55:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "48ac0a44b3108093fd4877ef5470fb0115582b27",
          "body": "VM Form RenderFooter now uses the canonical string:\nTab/Shift+Tab Navigate  PgUp/PgDown Scroll  Space/Enter Toggle\nSpace/Enter Save  ESC Cancel\n\nAll 8 forms now use the same canonical footer (or trimmed variant\nwhere appropriate per issue criteria).\n\nFixes #92",
          "is_bot": false,
          "headline": "fix: standardize VM form footer help text to match other forms",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T14:55:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "38278533665dce69d633125744f64a482f91a365",
          "body": "fix: persist L3 cache size/assoc per-die override values",
          "is_bot": false,
          "headline": "Merge pull request #94 from glemsom/fix/l3-cache-persistence",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T14:29:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "98eeaa89f0732193c05d7e0206189094489fae99",
          "body": "Root cause: Repository.GetConfig uses mapstructure/v2 to decode Viper's\nstored map[string]interface{} back into Go structs. The JSON round-trip\nin SaveConfig (marshal->unmarshal to map[string]interface{}) converts\nmap[int]string/map[int]int keys to JSON string keys. Mapstructure\nwithout WeaklyTypedI\n[…]\nr map key types.\n\nTest: TestCPUOptionsFormL3CachePersistence — saves L3 cache size and\nassociativity via form, reloads from repo, and re-opens form to\nverify values persist across the full round-trip.",
          "is_bot": false,
          "headline": "fix: persist L3 cache size/assoc per-die override values",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T14:18:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a1667d5471081fa79914fcf77a200f8009da864f",
          "body": null,
          "is_bot": false,
          "headline": "chore: release v0.2.0",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T10:54:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e852e5fb56541a84c59b65648f650005e1979e04",
          "body": "Minor visual improvements — footer standardization, toggle symmetry, button hints",
          "is_bot": false,
          "headline": "Merge pull request #93 from glemsom/minor-visual-improvements",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T10:51:33Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d56e1d86ee660ec864495db665b43ad4320ac5d0",
          "body": "…cel highlighting\n\n- cpu_topology_form.go: unfocused save hint [Enter] → [Space/Enter]\n- start_stop_script_form_render.go: cancel-focused no longer green-highlights\n  Cancel; both Save and Cancel stay muted when cancel focused, matching all\n  other forms (only Save gets green when focused)",
          "is_bot": false,
          "headline": "fix: address kilo-code-bot review — [Space/Enter] consistency and can…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T10:49:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7833961f952bd17788ddf6f2ca10cccc7f27328a",
          "body": null,
          "is_bot": false,
          "headline": "fix: standardize footer help text across all 8 forms (#92)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T10:30:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a93be79e0bd9c6dda406a1806264fe1c2acacb7d",
          "body": "…e (#91)",
          "is_bot": false,
          "headline": "fix: Start/Stop Script Cancel button highlights Cancel instead of Sav…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T10:30:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "455e6890a0487af5c99f61242e79c948ea7b68d4",
          "body": "…] Save (#90)",
          "is_bot": false,
          "headline": "fix: CPU Topology save hint uses [Space/Enter] Save instead of [Enter…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T10:30:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f2f4a36e4283f5dd6e4a264fd8a9cf381662ad43",
          "body": "…C] Cancel format (#89)\n\nThe Apply button was rendering as bare [Apply] instead of the standard\nfooter pattern used by all other forms. Changed to\n[Space/Enter] Apply  [ESC] Cancel with focused state highlighting.\n\nOption A preferred: 'Apply' kept as verb since it's an immediate action,\nnot config persistence.\n\nAdds TestSSHPasswordForm_ApplyButtonFormat to verify the new format.",
          "is_bot": false,
          "headline": "fix: SSH Password Apply button uses standard [Space/Enter] Apply  [ES…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T10:26:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9b1904b0e381e057fb7980a11eadf768cc183977",
          "body": "Issue #88: vCPU Pinning toggle used '[ ON ]' (with extra spaces) while\nall other forms use compact '[ON]'/'[OFF]'. Changed to '[ON]' to match\nconvention and ensure symmetric width.\n\nAlso added TestVCPUPinningToggleRenderingSymmetric to verify.",
          "is_bot": false,
          "headline": "fix: symmetric vCPU Pinning toggle rendering [ON]/[OFF]",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T10:19:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e496df038f0def69a622739aa21c6535a1bcabd4",
          "body": "feat: detect host L3 cache associativity and show in CPU options form",
          "is_bot": false,
          "headline": "Merge pull request #87 from glemsom/issue-86-detect-l3-cache-assoc",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T09:37:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c76140520e63e82acdf18b9d0322b8de54d8849e",
          "body": "…back\n\nPR #87 review feedback:\n\n1. Fix misleading var name typeData → levelData (reads 'level' file, not 'type')\n2. Fix silent wrong-die fallback: return 0 instead of cpuDirs[0] when\n   no CPU found for requested dieID\n3. Extract shared L3 cache index path lookup into findL3CacheIndexPath()\n   to eliminate ~40 lines of duplication between readL3CacheAssoc and\n   readL3CacheKB",
          "is_bot": false,
          "headline": "refactor: extract findL3CacheIndexPath, fix variable naming, fix fall…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T09:33:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8790db254e6601e2d0974b25010c52fde096a852",
          "body": "… (#86)\n\n- Add L3CacheAssoc field to CPUDie struct\n- Add readL3CacheAssoc method to CPUScanner (reads ways_of_associativity)\n- Call readL3CacheAssoc during ScanTopology\n- Show detected associativity in per-die associativity field label\n- Add ways_of_associativity to test fixtures and verify new field",
          "is_bot": false,
          "headline": "feat: detect host L3 cache associativity and show in CPU options form…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T09:26:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "298879ad44d9ce7586b730ea26a30bfdb82c3f7e",
          "body": "…rder\n\nfix: move WindowSizeMsg handler before registry dispatch (#84)",
          "is_bot": false,
          "headline": "Merge pull request #85 from glemsom/fix/84-window-size-msg-registry-o…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T08:39:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ec2f48114047ab26578b95fdf5e62f849bd74a3d",
          "body": "…g view rendering\n\nWhen the mount point warning is active, the registry dispatch intercepts the\nfirst WindowSizeMsg sent by BubbleTea at startup. Since the warning model\ndoes not handle WindowSizeMsg, the message is consumed but windowWidth/\nwindowHeight are never set, leaving them at zero.\n\nLater, \n[…]\nonfig sub-views (Set SSH Password, CPU Options, PCI Passthrough, etc.).\n\nFix: handle WindowSizeMsg before registry dispatch so dimensions are always\nset regardless of active sub-view state.\n\nFixes #84",
          "is_bot": false,
          "headline": "fix: move WindowSizeMsg handler before registry dispatch to fix confi…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-22T08:33:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bfa4b098b05bfcaeed97c02b8523179c66ef8586",
          "body": "Two rendering fixes for QEMU console (50x160):\n\n1. Status bar now at bottom of screen instead of mid-screen when\n   sub-view content is short. Changed PadToScreen to leave 1 line\n   then append statusBarView at the very end.\n\n2. Faint(true) overlay now applied only to chrome elements\n   (header, tab\n[…]\nr, breadcrumbs) — not to form content or status\n   bar. Fixes invisible text (e.g. 'Strength:' label in SSH\n   Password) caused by double-dim on terminals with poor dim\n   support (TERM=linux/vgacon).",
          "is_bot": false,
          "headline": "fix: status bar at screen bottom, faint only on chrome not form content",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T19:06:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "89b70d7d88ab429578821d773487855e263e7e52",
          "body": null,
          "is_bot": false,
          "headline": "chore: release v0.1.31",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T15:59:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6767f715c92ee8ef60b9cefc5c725250b47bb3be",
          "body": "feat: add per-die L3 cache associativity override (l3-cache-assoc-die<N>)",
          "is_bot": false,
          "headline": "Merge pull request #83 from glemsom/issue-80-l3-cache-assoc-die-override",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T15:45:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7550bb554af2777d8a69e66fabb8e0cd89012fac",
          "body": "…<N>)\n\nAdds L3CacheAssocDie CPU option to set per-die L3 cache associativity\noverride flags for asymmetric AMD V-cache CPUs (9950X3D, EPYC).\n\n- Model: new L3CacheAssocDie map[int]int field in CPUOptions\n- QEMU emission: emits l3-cache-assoc-die<N>=<value> after size flags\n- TUI: per-die associativity text fields alongside size fields in form\n- Tests: QEMU arg emission + TUI form field interactions\n\nCloses #80",
          "is_bot": false,
          "headline": "feat: add per-die L3 cache associativity override (l3-cache-assoc-die…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T14:54:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0b1282a369f1488931cc2d432b71fec41a3c5353",
          "body": "feat: per-die L3 cache size override (l3-cache-size-die<N>)",
          "is_bot": false,
          "headline": "Merge pull request #82 from glemsom/issue-79-l3-cache-die-override",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T14:46:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "481e47f3f679f5b2c2be7d15d473c308e7dfc11e",
          "body": "- Sort die indices before iterating L3CacheSizeDie map for\n  deterministic QEMU arg ordering (WARNING: non-deterministic\n  map iteration).\n- Surface scanErr warning to user in renderAllLines() and\n  RenderFooter() so per-die L3 field absence is explained\n  (WARNING: silent omission).\n- Add NewCPUOptionsFormModelWithTopo test constructor so\n  TestCPUOptionsFormWithL3CacheSizeDie uses the constructor\n  instead of bypassing it (SUGGESTION: test bypass).",
          "is_bot": false,
          "headline": "fix: address PR #82 review comments",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T13:55:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5eade6aa0ea06bfcef649a725269507bcaaa3384",
          "body": null,
          "is_bot": false,
          "headline": "docs: add CHANGELOG entry for per-die L3 cache override (#79)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T13:30:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "efc58e9fd55288694ce3a054991937d374d74b01",
          "body": "Implements issue #79: Per-die L3 cache size override support for asymmetric\nAMD V-cache CPUs (9950X3D, EPYC). Works with custom dkvm-qemu build.\n\nChanges:\n- Model: Add L3CacheSizeDie map[int]string to CPUOptions\n- QEMU: Emit l3-cache-size-die<N>=<size> in buildCPUOptsString()\n- TUI: Dynamic per-die L3 cache size text fields in CPU options form,\n  showing detected sizes from host topology scanner as hints\n\nCloses #79",
          "is_bot": false,
          "headline": "feat: add per-die L3 cache size override (l3-cache-size-die<N>)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T13:29:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e145bda828af9d5db034d0f76de9f8ee28de866b",
          "body": "fix: emit x-force-cpuid-0x80000026=on in QEMU CPU flags",
          "is_bot": false,
          "headline": "Merge pull request #81 from glemsom/fix/force-cpuid-0x80000026-emission",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T13:20:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9efca71ea8ece0eb9f7758189104130888611a3b",
          "body": "ForceCPUID0x80000026 was modeled in CPUOptions and exposed in the TUI\nas 'Force AMD CPUID', but buildCPUOptsString() never emitted the\ncorresponding QEMU property. The toggle was dead.\n\nNow when opts.ForceCPUID0x80000026 is true, the flag\nx-force-cpuid-0x80000026=on is appended to the -cpu host,... argument.\n\nCloses #78",
          "is_bot": false,
          "headline": "fix: emit x-force-cpuid-0x80000026=on in QEMU CPU flags",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T13:03:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79e75f4a12d6b28a6fb21006fdc579b99a0baabf",
          "body": "…ailure\n\nTestVersionMatchesVERSIONFile failed because commit f716a5c bumped\nVERSION from 0.1.29 to 0.1.30 but didn't update the Go constant.\n\nChanges:\n- Sync version.go Version to 0.1.30\n- Add make bump-version target for atomic dual-file updates\n- Document sync requirement in CONTRIBUTING.md Release Process\n- Add CHANGELOG entry for [Unreleased]\n\nThe regression test (TestVersionMatchesVERSIONFile) will catch any\nfuture drift between VERSION and version.go.",
          "is_bot": false,
          "headline": "fix: sync internal/version/version.go with VERSION file to fix test f…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T09:37:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f716a5c6c699b8d474442f5ba473eca527789a20",
          "body": null,
          "is_bot": false,
          "headline": "chore: bump v0.1.29 → v0.1.30",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T09:24:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "54064ec9dc38007e01342ad08c376ac7b0f6f25b",
          "body": "fix: remove redundant persistBuf.Flush() in dry-run path to fix data race",
          "is_bot": false,
          "headline": "Merge pull request #77 from glemsom/fix/persistbuf-data-race",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T08:19:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15f46b561a2e9fa9be45facd4419d0353198ca32",
          "body": "…race\n\nwritePersistLine() already flushes after every line, so the explicit\nFlush() in Start()'s dry-run path was both redundant and racy —\nit accessed r.persistBuf from the calling goroutine while persistLogLoop\ncould be concurrently writing to it.\n\nRemoving the inline flush eliminates the race entirely. The subscriber\nchannel ordering (write → flush → notify) guarantees the file is\nup-to-date once the caller receives all lines.\n\nFixes #76",
          "is_bot": false,
          "headline": "fix: remove redundant persistBuf.Flush() in dry-run path to fix data …",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T07:27:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5bc8c63a53b8ec876b461ae735f3ae990c9692e1",
          "body": "style: replace rounded borders with straight borders for TERM=linux support (#74)",
          "is_bot": false,
          "headline": "Merge pull request #75 from glemsom/layout-improvements",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T07:16:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d0e4df109e43741b34815081b8c578ad1fc37e54",
          "body": "…upport (#74)\n\nStraight box-drawing (┌┐└┘├┤─│) are in CP437 and render natively on\nDKVM host tty1 (TERM=linux). Rounded arcs (╭╮╰╯) are not in CP437 and\nfall back to '+' on the kernel VGA console.\n\nChanges:\n- NormalBorder(): always return lipgloss.NormalBorder(), no TERM check\n- RoundedBorder()/GetB\n[…]\nerStyle: RoundedBorder→NormalBorder\n- VM card borders: ┌┐└┘─│ (was ╭╮╰╯─│ with ASCII fallback)\n- VM details action bar: lipgloss.NormalBorder()\n- Updated tests to expect NormalBorder chars\n\nCloses #74",
          "is_bot": false,
          "headline": "style: replace rounded borders with straight borders for TERM=linux s…",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-21T06:01:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "71ca87f5e05321ae2611e0037d299854c5569b5b",
          "body": "Root cause: Snapshot() used deprecated query-cpus QMP command (removed in\nQEMU 7.1+). When QMP connected, query-cpus failed, causing an early return\nthat dropped ALL metrics including /proc-derived host RSS/CPU.\n\nFixes:\n1. vm_runner.go: use QueryCPUsFast() instead of QueryCPUs() in Snapshot()\n2. key\n[…]\nandlers.go: use seedAndSubscribe() instead of waitForLog() so log\n   subscription is properly established after VM starts (was silently missing\n   because Init() skipped subscribe when runner was nil)",
          "is_bot": false,
          "headline": "fix: VM metrics disappear after QMP connects (use query-cpus-fast)",
          "author_name": "Glenn Sommer",
          "author_login": "glemsom",
          "committed_at": "2026-06-20T11:43:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 38,
      "commits_last_year": 358,
      "latest_release_at": "2026-07-20T05:18:59Z",
      "latest_release_tag": "v0.2.6",
      "releases_from_tags": false,
      "days_since_last_push": 9,
      "active_weeks_last_year": 15,
      "days_since_latest_release": 9,
      "mean_days_between_releases": 3.3
    },
    "community": {
      "has_readme": true,
      "has_license": false,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 57,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": [
        {
          "name": "github.com/glemsom/dkvmmanager",
          "exists": true,
          "license": null,
          "keywords": [],
          "ecosystem": "go",
          "matches_repo": true,
          "registry_url": "https://pkg.go.dev/github.com/glemsom/dkvmmanager",
          "is_deprecated": false,
          "latest_version": "v0.2.6",
          "repository_url": "https://github.com/glemsom/dkvmmanager",
          "versions_count": 38,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": null,
          "latest_published_at": "2026-07-20T05:17:48Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 9
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "Makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "go.mod"
      ],
      "largest_source_bytes": 54111,
      "source_files_sampled": 193,
      "oversized_source_files": 0,
      "agent_instruction_files": [
        "AGENTS.md"
      ],
      "agent_instruction_max_bytes": 1230
    },
    "dependencies": {
      "manifests": [
        "go.mod"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "go"
      ],
      "dependencies": [
        {
          "name": "charm.land/bubbles/v2",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v2.1.0"
        },
        {
          "name": "charm.land/bubbletea/v2",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v2.0.7"
        },
        {
          "name": "charm.land/lipgloss/v2",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v2.0.3"
        },
        {
          "name": "github.com/charmbracelet/x/ansi",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.11.7"
        },
        {
          "name": "github.com/go-viper/mapstructure/v2",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v2.5.0"
        },
        {
          "name": "github.com/spf13/viper",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.21.0"
        },
        {
          "name": "golang.org/x/sys",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.46.0"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 60,
        "open_issues": 0,
        "closed_ratio": 1,
        "closed_issues": 90,
        "closed_unmerged_prs": 1
      },
      "bus_factor": 1,
      "bot_contributors": 2,
      "top_contributors": [
        {
          "type": "User",
          "login": "glemsom",
          "commits": 350,
          "avatar_url": "https://avatars.githubusercontent.com/u/601804?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "release-please.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "go.sum"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "11 out of 11 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/21 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "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": 0,
            "reason": "license file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 30 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": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 2,
            "reason": "dependency not pinned by hash detected -- score normalized to 2",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 0,
            "reason": "Project has not signed or included provenance with any releases.",
            "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": 9,
            "reason": "1 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "8dbc98e5dbbf97585df2d06cb5e48c7e69faf8e5",
        "ran_at": "2026-07-29T12:21:54Z",
        "aggregate_score": 3.8,
        "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-20T05:18:55Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-10T19:37:14Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/glemsom/dkvmmanager",
    "host": "github.com",
    "name": "dkvmmanager",
    "owner": "glemsom"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 55,
      "inputs": {
        "security": 38,
        "vitality": 76,
        "community": 25,
        "governance": 57,
        "engineering": 71
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 76,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 67,
            "inputs": {
              "commits_last_year": 358,
              "human_commit_share": 1,
              "days_since_last_push": 9,
              "active_weeks_last_year": 15
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 9 days ago",
                "points": 28.8,
                "status": "partial",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 9
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "15/52 weeks with commits",
                "points": 10.4,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 15
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "358 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 358
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 30 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": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "releases_count": 38,
              "latest_release_tag": "v0.2.6",
              "releases_from_tags": false,
              "days_since_latest_release": 9,
              "mean_days_between_releases": 3.3
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "38 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 38
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 9 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 9
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~3.3 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 3.3
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 25,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "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": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 52,
            "inputs": {
              "has_readme": true,
              "has_license": false,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "no license file detected",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "license_absent",
                    "params": {}
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 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": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 57,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "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 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 84,
            "inputs": {
              "merged_prs": 60,
              "open_issues": 0,
              "closed_issues": 90,
              "issue_closed_ratio": 1,
              "closed_unmerged_prs": 1
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "100% of issues closed",
                "points": 46.8,
                "status": "met",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "60/61 decided PRs merged",
                "points": 37.6,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 60,
                      "decided": 61
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/21 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 52,
            "inputs": {
              "followers": 18,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "glemsom",
              "public_repos": 28,
              "account_age_days": 5653
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "18 followers of glemsom",
                "points": 9.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 18,
                      "login": "glemsom"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "28 public repos, account ~15 yr old",
                "points": 22.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 28
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 15
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "github.com/glemsom/dkvmmanager"
              ],
              "ecosystems": "go",
              "any_deprecated": false,
              "min_days_since_publish": 9
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on go",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "go"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 9 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 9
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "38 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 38
                    }
                  }
                ],
                "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": 71,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "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": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "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": "11 out of 11 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 38,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "name": "Security posture",
            "note": null,
            "notes": [],
            "value": 38,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 18,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 0,
              "scorecard_aggregate": 3.8
            },
            "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": "11 out of 11 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/21 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "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 not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 30 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 detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 2",
                "points": 1,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "Project has not signed or included provenance with any releases.",
                "points": 0,
                "status": "missed",
                "details": [],
                "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": "1 existing vulnerabilities detected",
                "points": 6.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "good",
        "name": "AI Readiness",
        "value": 72,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.98,
              "agent_instruction_files": [
                "AGENTS.md"
              ],
              "agent_instruction_max_bytes": 1230
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "AGENTS.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "AGENTS.md"
                    }
                  }
                ],
                "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": "98 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 98,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 63,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "go.sum"
              ],
              "has_dockerfile": true,
              "typed_language": true,
              "bootstrap_files": [
                "Makefile"
              ],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0,
              "toolchain_manifests": [
                "go.mod"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "Makefile",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Makefile"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "Go (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "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 2",
                "points": 2,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "Go",
              "largest_source_bytes": 54111,
              "source_files_sampled": 193,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Go (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Go"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/193 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 193,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "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": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "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": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-29T12:22:09.741571Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/g/glemsom/dkvmmanager.svg",
  "full_name": "glemsom/dkvmmanager",
  "license_state": "absent",
  "license_spdx": null
}

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.27.0 — vollständige Methodik · Metriken-Wiki.

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte StatistikenGo.