Registro público
Informe de salud del softwareesquema 0.26.0 · métricas 1.13.0 · 2026-07-22 19:25 UTC

claymore666 / docker-net-dhcp

Docker network plugin: containers get DHCP leases from the LAN. Modernized fork of devplayer0/docker-net-dhcp with macvlan attachment mode.

GoGPL-3.0★ 9 estrellas⑂ 1 forkdesde may 2026Ver en GitHub ↗

claymore666/docker-net-dhcp tiene un índice de salud de 62 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Vitality (74/100) y la más baja, Community & Adoption (42/100). Se actualizó por última vez hace 2 días. Una sola persona concentra la mayor parte del trabajo reciente.

62
global / 100
Moderado

Índice de salud del software

Las métricas se agrupan en categorías ponderadas sobre una escala de 1 a 100. El resultado global parte de su media; cuando la evidencia pública activa la Política de Jurisdicciones de Alto Riesgo, la calificación se ajusta y recibe el límite 49 (En riesgo). Preparación para IA queda fuera.

62
Excelente85-100Ejemplar; cumple prácticamente todos los criterios evaluados
Bueno70-84Saludable; carencias menores
Moderado50-69Aceptable con carencias notables; se recomienda revisión
En riesgo30-49Debilidades significativas; su adopción exige cautela
Crítico1-29Problemas graves (proyecto abandonado, un solo mantenedor, sin higiene)
VitalidadComunidad yAdopciónSostenibilidady GobernanzaCalidad deIngenieríaSeguridadPreparaciónpara IA

Perfil de puntuación

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

Titularidad

ChrisCuenta personal
4 seguidores23 repositorios públicosdesde feb 2015

Este repositorio pertenece a una cuenta personal. Un proyecto con un único propietario conlleva más riesgo de continuidad que uno respaldado por una organización.

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicación
Gogithub.com/devplayer0/docker-net-dhcpapunta a otro repositorio; no se puntúav0.1.4-5hace 1833 días

Métricas por categoría

Vitalidad

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

74Bueno · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 2 días
3.5/36Cadencia de commits — 5/52 semanas con commits
18/18Volumen de commits — 323 commits en el último año
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Datos de entrada utilizados
commits_last_year323
human_commit_share0,97
days_since_last_push2
active_weeks_last_year5
Cómo se puntúa
27/27Publica versiones — 28 versiones publicadas
36/36Recencia de las versiones — última versión hace 16 días
27/27Cadencia de publicación — una versión cada ~2,2 días
8/10OpenSSF Scorecard: Signed-Releases — 5 out of the last 5 releases have a total of 5 signed artifacts.
Datos de entrada utilizados
releases_count28
latest_release_tagv1.3.3
releases_from_tagsno
days_since_latest_release16
mean_days_between_releases2,2

Comunidad y Adopción

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

42En riesgo · 18% del índice global
Cómo se puntúa
14.6/60Estrellas — 9 estrellas
0/25Forks — 1 forks
0/15Observadores — 1 observadores
Datos de entrada utilizados
forks1
stars9
watchers1
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (GPL-3.0)
0/18Guía CONTRIBUTING
13.5/13.5Código de conducta
0/7.2Plantilla de issues
6.3/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
has_contributingno
has_issue_templateno
has_code_of_conduct
has_pull_request_template

Sostenibilidad y Gobernanza

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

51Moderado · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
7.6/22.5Distribución de commits — el principal contribuyente firma el 66% de los commits
4.1/13.5Amplitud de contribuyentes — 3 contribuyentes
10/10OpenSSF Scorecard: Contributors — project has 3 contributing companies or organizations -- score normalized to 10
Datos de entrada utilizados
bus_factor1
contributors_sampled3
top_contributor_share0,661
Cómo se puntúa
43.4/46.8Resolución de issues — 93% de issues cerradas
36/38.3Aceptación de PR — 147/156 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/25 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs147
open_issues12
closed_issues155
issue_closed_ratio0,928
closed_unmerged_prs9
Cómo se puntúa
10/30Respaldo de la propiedad — cuenta personal (usuario)
0/20Dominio verificado — no aplicable a cuentas de usuario
5/25Alcance del propietario — 4 seguidores de claymore666
22.1/25Trayectoria — 23 repos públicos, cuenta de ~11 años
Datos de entrada utilizados
followers4
owner_typeUser
is_verified
owner_loginclaymore666
public_repos23
account_age_days4162
Excluidos de la puntuación (sin datos o no aplicable): Dominio verificado. Los pesos restantes se han renormalizado.

Calidad de Ingeniería

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

71Bueno · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 12 flujo(s) de trabajo
24/24Pruebas presentes
0/16Configuración de linter
0/9.6Hooks de pre-commit
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 28 out of 28 merged PRs checked by a CI test -- score normalized to 10
Datos de entrada utilizados
has_ci
has_tests
has_editorconfigno
has_linter_configno
has_precommit_configno
Cómo se puntúa
30/30README
25/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
10/10Descripción del repositorio
0/10Topics
10/10Wiki
Datos de entrada utilizados
topics
has_wiki
homepage
has_readme
has_docs_dir
has_description

Seguridad

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

71Bueno · 16% del índice global
Cómo se puntúa
7.5/7.5Binary-Artifacts — no binaries found in the repo
2.2/7.5Branch-Protection — branch protection is not maximal on development and all release branches
2.5/2.5CI-Tests — 28 out of 28 merged PRs checked by a CI test -- score normalized to 10
1.2/2.5CII-Best-Practices — badge detected: Passing
0/7.5Code-Review — Found 0/25 approved changesets -- score normalized to 0
2.5/2.5Contributors — project has 3 contributing companies or organizations -- score normalized to 10
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
5/5Fuzzing — project is fuzzed
2.5/2.5Licencia — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
5/5Packaging — packaging workflow detected
5/5Pinned-Dependencies — all dependencies are pinned
5/5SAST — SAST tool is run on all commits
5/5Security-Policy — security policy file detected
6/7.5Signed-Releases — 5 out of the last 5 releases have a total of 5 signed artifacts.
7.5/7.5Token-Permissions — GitHub workflow tokens follow principle of least privilege
3.8/7.5Vulnerabilities — 5 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated18
scorecard_versionv5.5.0
checks_inconclusive0
scorecard_aggregate7,5
Cómo se puntúa
10.4/35Dependencias directas libres de avisos conocidos — 1 afectados: github.com/docker/docker v28.5.2+incompatible (high 8.8)
0/25Dependencias indirectas libres de avisos conocidos — el conjunto transitivo no es separable de las dependencias de desarrollo y prueba en este alcance
32.8/40Sin avisos pendientes — 1 paquete(s) con avisos sin atender más allá de 90 días; el más antiguo publicado hace 117 días
Datos de entrada utilizados
sourceosv
advisories10
affected_packages1
assessed_packages65
unassessed_packages2
affected_by_severityhigh 1
direct_affected_packages1
Excluidos de la puntuación (sin datos o no aplicable): Dependencias indirectas libres de avisos conocidos. Los pesos restantes se han renormalizado. Se cotejaron 65 dependencias resueltas con OSV. 2 no pudieron evaluarse: sin versión resuelta, ecosistema no admitido o fuera de la lista de paquetes informada. Este repositorio no publica ningún paquete que el índice resuelva, por lo que se evaluó en su lugar el grafo de dependencias del repositorio. Ese grafo mezcla fijaciones de desarrollo y prueba con las dependencias distribuidas, de modo que solo se puntúan las dependencias declaradas en tiempo de ejecución; los hallazgos transitivos se informan como contexto y quedan excluidos de la puntuación. No se analiza la alcanzabilidad.

Preparación para IA

¿Hasta qué punto está el repositorio preparado para desarrollarse y mantenerse con agentes de codificación de IA? Es una insignia independiente y experimental — peso 0,0, de modo que se presenta por separado y no afecta a la puntuación de salud global.

69Moderado · 0% del índice global
Cómo se puntúa
0/45Instrucciones para agentes — sin CLAUDE.md / AGENTS.md / reglas de editor
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 97 de 97 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share1
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
18/18Arranque con un solo comando — Makefile
22/22Pruebas automatizadas
0/11Configuración de lint / formato
11/11Verificación estática de tipos — Go (tipado estático)
10/10Entorno reproducible — Dockerfile, lockfile
0/10Práctica demostrada con agentes — ningún commit con autoría de agente entre los últimos 100
8/8Mantenimiento automatizado — 3 de los últimos 100 commits son actualizaciones automáticas de dependencias
10/10OpenSSF Scorecard: Pinned-Dependencies — all dependencies are pinned
Datos de entrada utilizados
has_nixno
has_tests
lockfilesgo.sum
has_dockerfile
typed_language
bootstrap_filesMakefile
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0
toolchain_manifestsgo.mod
dependency_bot_commit_share0,03
Cómo se puntúa
45/45Código verificable por tipos — Go (tipado estático)
55/55Tamaños de archivo manejables — 0/86 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageGo
largest_source_bytes41.827
source_files_sampled86
oversized_source_files0

Datos clave

9estrellas de GitHub
3contribuidores
323commits en los últimos 12 meses
2días desde el último push
28versiones publicadas
1factor bus
12issues abiertas
Go, PyPIecosistemas de paquetes

Advertencias de recopilación de datos

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • go package 'github.com/devplayer0/docker-net-dhcp' points at a different repository (https://github.com/devplayer0/docker-net-dhcp); excluded from ecosystem scoring

Más detalle

OpenSSF Scorecard 7.5 / 10
7.5agregado

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

10Binary-Artifactsno binaries found in the repo
3Branch-Protectionbranch protection is not maximal on development and all release branches
10CI-Tests28 out of 28 merged PRs checked by a CI test -- score normalized to 10
5CII-Best-Practicesbadge detected: Passing
0Code-ReviewFound 0/25 approved changesets -- score normalized to 0
10Contributorsproject has 3 contributing companies or organizations -- score normalized to 10
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
10Fuzzingproject is fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
10Packagingpackaging workflow detected
10Pinned-Dependenciesall dependencies are pinned
10SASTSAST tool is run on all commits
10Security-Policysecurity policy file detected
8Signed-Releases5 out of the last 5 releases have a total of 5 signed artifacts.
10Token-PermissionsGitHub workflow tokens follow principle of least privilege
5Vulnerabilities5 existing vulnerabilities detected
Dependencias directas 7
RegistroPaqueteRestricción de versiónManifiesto
Gogithub.com/docker/dockerv28.5.2+incompatiblego.mod
Gogithub.com/gorilla/handlersv1.5.2go.mod
Gogithub.com/mitchellh/mapstructurev1.5.0go.mod
Gogithub.com/sirupsen/logrusv1.9.4go.mod
Gogithub.com/vishvananda/netlinkv1.3.1go.mod
Gogithub.com/vishvananda/netnsv0.0.5go.mod
Gogolang.org/x/sysv0.46.0go.mod
Todas las dependencias 67

Conjunto completo de dependencias resueltas según el grafo de dependencias de GitHub: 7 paquetes directos y 60 indirectos (transitivos). El cierre transitivo es completo cuando el repositorio incluye un lockfile.

RegistroPaqueteVersiónRelación
Gogithub.com/docker/dockerv28.5.2+incompatibledirecta
Gogithub.com/gorilla/handlersv1.5.2directa
Gogithub.com/mitchellh/mapstructurev1.5.0directa
Gogithub.com/sirupsen/logrusv1.9.4directa
Gogithub.com/vishvananda/netlinkv1.3.1directa
Gogithub.com/vishvananda/netnsv0.0.5directa
Gogolang.org/x/sysv0.46.0directa
Gogithub.com/cespare/xxhash/v2v2.3.0indirecta
Gogithub.com/containerd/errdefsv1.0.0indirecta
Gogithub.com/containerd/errdefs/pkgv0.3.0indirecta
Gogithub.com/containerd/logv0.1.0indirecta
Gogithub.com/distribution/referencev0.6.0indirecta
Gogithub.com/docker/go-connectionsv0.7.0indirecta
Gogithub.com/docker/go-unitsv0.5.0indirecta
Gogithub.com/felixge/httpsnoopv1.0.4indirecta
Gogithub.com/go-logr/logrv1.4.3indirecta
Gogithub.com/go-logr/stdrv1.2.2indirecta
Gogithub.com/microsoft/go-winiov0.6.2indirecta
Gogithub.com/moby/docker-image-specv1.3.1indirecta
Gogithub.com/moby/sys/atomicwriterv0.1.0indirecta
Gogithub.com/moby/termv0.5.2indirecta
Gogithub.com/morikuni/aecv1.1.0indirecta
Gogithub.com/opencontainers/go-digestv1.0.0indirecta
Gogithub.com/opencontainers/image-specv1.1.1indirecta
Gogithub.com/pkg/errorsv0.9.1indirecta
Gogo.opentelemetry.io/auto/sdkv1.2.1indirecta
Gogo.opentelemetry.io/contrib/instrumentation/net/http/otelhttpv0.68.0indirecta
Gogo.opentelemetry.io/otelv1.43.0indirecta
Gogo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttpv1.43.0indirecta
Gogo.opentelemetry.io/otel/metricv1.43.0indirecta
Gogo.opentelemetry.io/otel/tracev1.43.0indirecta
Gogolang.org/x/timev0.15.0indirecta
Gogotest.tools/v3v3.5.2indirecta
PyPIbabel2.18.0indirecta
PyPIbackrefs7.0indirecta
PyPIcertifi2026.5.20indirecta
PyPIcharset-normalizer3.4.7indirecta
PyPIclick8.4.1indirecta
PyPIcolorama0.4.6indirecta
PyPIdocker-image-pyindirecta
PyPIghp-import2.1.0indirecta
PyPIidna3.18indirecta
PyPIjinja23.1.6indirecta
PyPImarkdown3.10.2indirecta
PyPImarkupsafe3.0.3indirecta
PyPImergedeep1.3.4indirecta
PyPImike2.2.0indirecta
PyPImkdocs1.6.1indirecta
PyPImkdocs-get-deps0.2.2indirecta
PyPImkdocs-material9.7.6indirecta
PyPImkdocs-material-extensions1.3.1indirecta
PyPIpackaging26.2indirecta
PyPIpaginate0.5.7indirecta
PyPIpathspec1.1.1indirecta
PyPIplatformdirs4.10.0indirecta
PyPIpygments2.20.0indirecta
PyPIpymdown-extensions10.21.3indirecta
PyPIpyparsing3.3.2indirecta
PyPIpython-dateutil2.9.0.post0indirecta
PyPIpython-dxfindirecta
PyPIpyyaml6.0.3indirecta
PyPIpyyaml-env-tag1.1indirecta
PyPIrequests2.34.2indirecta
PyPIsix1.17.0indirecta
PyPIurllib32.7.0indirecta
PyPIverspec0.1.0indirecta
PyPIwatchdog6.0.0indirecta
Avisos de dependencias 1

Este repositorio no publica ningún paquete que el índice resuelva, así que se evaluó su propio grafo de dependencias — 65 paquetes, que incluyen también fijaciones de desarrollo y prueba que nunca se distribuyen: 1 tienen avisos conocidos, de los cuales 1 son directas. 2 no pudieron evaluarse: sin versión resuelta, ecosistema no admitido, o fuera de la lista de paquetes informada.

PaqueteVersiónRelaciónGravedadAvisosCorregido en
github.com/docker/dockerv28.5.2+incompatibledirectaalta1029.3.1

Un aviso significa que la versión registrada en el grafo de dependencias cae dentro del rango afectado de un aviso. No se analiza la alcanzabilidad, y el grafo incluye fijaciones de desarrollo y prueba: un hallazgo puede referirse al utillaje y no al software distribuido.

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 2258,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Go": 617745,
        "Shell": 62878,
        "Python": 7946,
        "Makefile": 4517,
        "Dockerfile": 7163
      },
      "pushed_at": "2026-07-19T23:06:05Z",
      "created_at": "2026-05-02T12:19:50Z",
      "owner_type": "User",
      "updated_at": "2026-07-20T13:13:03Z",
      "description": "Docker network plugin: containers get DHCP leases from the LAN. Modernized fork of devplayer0/docker-net-dhcp with macvlan attachment mode.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "GPL-3.0",
      "default_branch": "main",
      "license_spdx_raw": "GPL-3.0",
      "primary_language": "Go",
      "significant_languages": [
        "Go"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Chris",
      "type": "User",
      "login": "claymore666",
      "company": null,
      "location": "Germany, Mainz-Bingen",
      "followers": 4,
      "avatar_url": "https://avatars.githubusercontent.com/u/11246284?v=4",
      "created_at": "2015-02-28T15:32:11Z",
      "is_verified": null,
      "public_repos": 23,
      "account_age_days": 4162
    },
    "license": {
      "state": "standard",
      "spdx_id": "GPL-3.0",
      "raw_spdx": "GPL-3.0",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v1.3.3",
          "kind": "patch",
          "published_at": "2026-07-06T00:55:50Z"
        },
        {
          "tag": "v1.3.3-rc1",
          "kind": "prerelease",
          "published_at": "2026-07-06T00:52:46Z"
        },
        {
          "tag": "v1.3.2",
          "kind": "patch",
          "published_at": "2026-07-05T12:02:15Z"
        },
        {
          "tag": "v1.3.2-rc1",
          "kind": "prerelease",
          "published_at": "2026-07-05T11:59:11Z"
        },
        {
          "tag": "v1.3.1",
          "kind": "patch",
          "published_at": "2026-07-05T08:09:05Z"
        },
        {
          "tag": "v1.3.1-rc1",
          "kind": "prerelease",
          "published_at": "2026-07-05T08:05:40Z"
        },
        {
          "tag": "v1.3.0",
          "kind": "minor",
          "published_at": "2026-07-04T05:59:44Z"
        },
        {
          "tag": "v1.3.0-rc1",
          "kind": "prerelease",
          "published_at": "2026-07-04T05:55:49Z"
        },
        {
          "tag": "v1.2.0",
          "kind": "minor",
          "published_at": "2026-06-16T08:20:01Z"
        },
        {
          "tag": "v1.2.0-rc2",
          "kind": "prerelease",
          "published_at": "2026-06-16T08:11:19Z"
        },
        {
          "tag": "v1.1.1",
          "kind": "patch",
          "published_at": "2026-06-14T15:30:39Z"
        },
        {
          "tag": "v1.1.1-rc1",
          "kind": "prerelease",
          "published_at": "2026-06-14T14:53:20Z"
        },
        {
          "tag": "v1.1.0",
          "kind": "minor",
          "published_at": "2026-06-14T10:51:11Z"
        },
        {
          "tag": "v1.1.0-rc1",
          "kind": "prerelease",
          "published_at": "2026-06-14T10:46:28Z"
        },
        {
          "tag": "v1.0.0",
          "kind": "major",
          "published_at": "2026-06-13T08:45:07Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2026-05-05T22:39:38Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-05-05T13:10:26Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-05-05T08:32:29Z"
        },
        {
          "tag": "v0.6.1",
          "kind": "patch",
          "published_at": "2026-05-04T22:39:03Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-05-04T22:24:27Z"
        },
        {
          "tag": "v0.5.3",
          "kind": "patch",
          "published_at": "2026-05-04T17:23:06Z"
        },
        {
          "tag": "v0.5.2",
          "kind": "patch",
          "published_at": "2026-05-03T01:14:30Z"
        },
        {
          "tag": "v0.5.1",
          "kind": "patch",
          "published_at": "2026-05-03T00:05:25Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-05-02T21:03:13Z"
        },
        {
          "tag": "v0.4.1",
          "kind": "patch",
          "published_at": "2026-05-02T17:20:15Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-05-02T14:14:23Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-05-02T14:03:10Z"
        },
        {
          "tag": "v0.2.0",
          "kind": "minor",
          "published_at": "2026-05-02T14:02:54Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "c2baff17ebabee144c0d182945c58a22ba84639e",
          "body": "Release v1.3.3",
          "is_bot": false,
          "headline": "Merge pull request #322 from claymore666/dev",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-06T00:50:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e634d192854fa0f30ffff42728b31cd3e845cce4",
          "body": "…te (#317) (#323)\n\nPR #320 patched config.json only; the coverage workflow builds its\ninstrumented plugin from config-cover.json, so the release-PR coverage\nrun failed TestNonRootContainer_PersistentClientStarts against an\nunfixed manifest (the new test doing its job, and the improved await\nerror su\n[…]\n  (capabilities, network.type, pidhost, interface.types) must agree\n  between the two manifests; cover-only extras stay unchecked\n- meta-test + wired into test.yaml (gate self-tests + a required step)",
          "is_bot": false,
          "headline": "fix(ci): CAP_SYS_PTRACE in config-cover.json too + manifest parity ga…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-05T20:13:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "916679a9682221016ce028832c7d112f77309d7c",
          "body": "- bump install pins v1.3.2 -> v1.3.3\n- document CAP_SYS_PTRACE in the requested-privileges lists (README,\n  docs/index.md, docs/reference.md)\n- RELEASE_NOTES: v1.3.3 section (#317 fix + counter, #318 badge)",
          "is_bot": false,
          "headline": "Prepare v1.3.3 release (#321)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-05T19:07:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d6525195051fff84ce514b1952883dca9396651f",
          "body": "…non-root containers' netns (#317) (#320)\n\nThe persistent DHCP client opens /proc/<pid>/ns/net at Join; the kernel\ngates that with a PTRACE_MODE_READ check (same uid or CAP_SYS_PTRACE).\nThe manifest granted only NET_ADMIN+SYS_ADMIN, so for any container\nrunning as a non-root USER the open failed EAC\n[…]\ntStarts (user\n  65534:65534, short T1 via option 58, asserts a renewal ACK from the\n  non-root netns and a flat join_start_failures delta); harness gains\n  RunContainerUser and the health-mirror field",
          "is_bot": false,
          "headline": "fix(plugin): grant CAP_SYS_PTRACE so the persistent client can enter …",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-05T18:24:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d924227856cb2de3c99af5e67ccf1472eb4bc7b2",
          "body": "… (#318) (#319)",
          "is_bot": false,
          "headline": "docs: drop the Go Report Card badge — goreportcard.com is end-of-life…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-05T18:24:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1f82a32aaaa25ac215b9b945eb098b3e4b01390a",
          "body": "Release v1.3.2",
          "is_bot": false,
          "headline": "Merge pull request #316 from claymore666/dev",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-05T11:57:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1da580468ad244fb5dff6b1945b40565c45ab9ec",
          "body": "* Prepare v1.3.2 release\n\n- bump install pins v1.3.1 -> v1.3.2 (scripts/bump-version.sh)\n- README: note the docs-only fast-skip on the integration check\n- RELEASE_NOTES: v1.3.2 section (CI-only release, #311/#312 gate)\n\n* fix(ci): gate script uses curl+jq — the runner image has no gh CLI (#311, #312\n[…]\nf too large to see fully fails\n  open instead of judging a truncated view\n- meta-test: stub curl instead of gh; new cases for pagination\n  (full-page continuation both ways) and missing-tool fail-open",
          "is_bot": false,
          "headline": "Prepare v1.3.2 release (#315)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-05T11:09:31Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4cbce2a4077865ad8bcdbe1be1aa0ce330d92caa",
          "body": "…s exit early (#311, #312) (#314)\n\nA first job step decides whether the event needs the suite:\n- pull_request: all changed paths *.md -> skip (#311). Allowlist is\n  deliberately just *.md; workflows, scripts, Dockerfile, comment-only\n  code changes all still run.\n- push: the commit's tree matches a \n[…]\nuns. Gate logic lives in\nscripts/integration-run-gate.sh with a 15-case meta-test wired into\ntest.yaml's gate-script step (mixed diffs must never classify as\ndocs-only; novel trees must never dedupe).",
          "is_bot": false,
          "headline": "ci(integration): suite-needed gate — docs-only PRs and duplicate tree…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-05T10:23:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f459fee277a88eee280795f4fe1b46f351bd9de9",
          "body": "Release v1.3.1",
          "is_bot": false,
          "headline": "Merge pull request #313 from claymore666/dev",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-05T08:02:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2a9a69648bbb1ce3557f3b925db3e0e17435e34b",
          "body": "- bump install pins v1.3.0 -> v1.3.1 (scripts/bump-version.sh)\n- add v1.3.1 section to RELEASE_NOTES.md\n- docs reviewed PR-by-PR against the milestone: #308 is the only\n  user-visible change and its doc updates shipped in-PR (verified,\n  no stale probe-timing references); #301/#302/#304/#306/#309 are\n  CI/test-internal",
          "is_bot": false,
          "headline": "Prepare v1.3.1 release (#310)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-04T23:09:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1dd4ef601985898f67fd48836d0986beba12fde3",
          "body": "The milestone was renamed: the cycle carries one bug fix (#307) plus\nCI/test hardening — a patch release by semver, not a minor.",
          "is_bot": false,
          "headline": "docs(ci): v1.4.0 -> v1.3.1 in coverage-baseline decision notes (#309)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-04T22:25:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4b1b1029a6dc0160fb08116ad2d077ee1540e32e",
          "body": "…307) (#308)\n\n5s -> 8s. The probe interface is a freshly-created macvlan child that\nsolicits immediately; the first broadcast DISCOVER is not reliably\ndelivered, and dhcpcd's jittered ~4s retransmit plus 1-2s startup on\nslow/virtualized hosts exceeded the old budget — a live DHCP server\ngot reported\n[…]\nxtra 3s.\n\nPinned by TestPreflightProbeBudget_CoversOneLostDiscover (startup +\nretry + response floor; verified failing at the old 5s value).\nDocs and the failure-test's elapsed bound updated to match.",
          "is_bot": false,
          "headline": "fix(plugin): size preflight probe budget for a lost first DISCOVER (#…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-04T21:07:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4c1cd5a0b7fd07bae847424d692aaf82374c2ac0",
          "body": "…tence (#305) (#306)\n\n* tests(plugin): cover CreateTemp and Rename error arms of state persistence (#305)\n\nFour tests in the existing failure-injection style: read-only state\ndir for the CreateTemp arm (root-skipped like the other DAC tests),\nand a non-empty directory occupying the final path for th\n[…]\nm tests (#305)\n\nMeasured merged 84.1 on this PR's coverage dispatch (run #26); all\nother packages identical to the decimal across four runs, so the\n+0.3 is attributable to the new tests, not variance.",
          "is_bot": false,
          "headline": "tests(plugin): cover CreateTemp and Rename error arms of state persis…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-04T19:58:33Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dc7d05680ac1420aafd8352e0abd8217609fa0ed",
          "body": "…03) (#304)\n\npkg/dhcp 85.5 -> 89.5, cmd/dhcp-handler 50.0 -> 74.0, pkg/plugin\n82.0 -> 83.5. The first two were still udhcpc-era carry-overs; the\ndhcpcd migration and v1.3.0 test work earned coverage no PR ratcheted\nin, leaving up to 25 points of silent-regression headroom. Measured\nagainst Coverage \n[…]\n its rules.\n\nVerified locally: ratchet passes on measured numbers, fails on a\nsynthetic 0.6-point pkg/dhcp regression the old floor would have\npassed, and scripts/test-coverage-ratchet.sh stays green.",
          "is_bot": false,
          "headline": "tests(ci): ratchet coverage floors to post-dhcpcd measured levels (#3…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-04T18:25:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5df1b428eb7fb3cdec335f12b798c778860b48ab",
          "body": "The #207 workflow audit found two comments in coverage.yml that\npredate #127 wiring the pull_request->main trigger:\n\n- the header claimed only workflow_dispatch is wired so forks can't\n  trigger the workflow at all — a forked PR into main does trigger it;\n  the outside-collaborator approval requirem\n[…]\now runs only on manual\n  dispatch — it also runs on every release PR.\n\nComment-only; no behavior change. Audit verdict on the issue: all 12\nworkflows earn their place, nothing redundant or superseded.",
          "is_bot": false,
          "headline": "docs(ci): fix stale coverage.yml trigger comments (#207) (#302)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-04T16:55:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3b15dc1f3f34cb220078e9bdc9d1ff8287fdc528",
          "body": "…p (#296) (#301)\n\nThe cutover to the ephemeral runner pool dropped the gpu1-era\nselfhosted-docker concurrency group on the grounds that the runners\nisolate all Docker state. State, yes — but they still share one host's\nCPU/IO, and the suite carries real-time DHCP timing: on the v1.3.0\nrelease PR, co\n[…]\n.yml,\ncancel-in-progress: false. Documented caveat: GitHub keeps at most one\npending run per group, so a third concurrent run cancels the queued\none (manual re-run) — acceptable at this repo's volume.",
          "is_bot": false,
          "headline": "ci: serialize privileged self-hosted jobs via shared concurrency grou…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-04T16:55:12Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8bf19622175f744b205e0f1e16c8a68c8950ccda",
          "body": "Release v1.3.0",
          "is_bot": false,
          "headline": "Merge pull request #295 from claymore666/dev",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-04T05:53:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a94fb3148437cb90b8af3608fc3e945398190150",
          "body": "The tee'd test steps ran under the implicit Actions shell (bash -e,\nno pipefail), so tee's exit 0 masked go-test failures since #277 —\nthe comment claiming the default shell has pipefail was wrong. Declare\nshell: bash explicitly (bash -eo pipefail) on both steps.\n\nExpected effect: this PR's own integration run goes red on the\nalready-failing TestStableLease_IPvlanSameIPAcrossRecreate (#298) —\nthat red is the fix working.",
          "is_bot": false,
          "headline": "ci(integration): fail the gate on piped test failures (#297) (#299)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-04T01:56:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "30f1d1298122d6427a94646ba65f2a41b65465fe",
          "body": "* Revert \"feat(ipvlan): stable DHCP client-id for lease stability across recreate (#219) (#285)\"\n\nThis reverts commit c4b4f95e4ff9276568381931ee2daa889a47fc1f.\n\n* docs(release): drop stable_lease from v1.3.0 notes and option docs (#298)\n\nThe #286 release prep documented stable_lease/lease_seed; with #285\nreverted they are no longer in the release. The option-61 paragraph now\nstates the recreate-stability gap plainly and points at the\ndeterministic-MAC track (#218/#219) that closes it.",
          "is_bot": false,
          "headline": "revert: de-scope stable_lease (#219) from v1.3.0 (#300)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-04T01:34:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23b5c651dd0da8ef7b348ef10659db999ca1e7e4",
          "body": "* docs: prepare v1.3.0 release (pins, notes, doc reconciliation)\n\n- bump published-image pins v1.2.0 -> v1.3.0 (README, docs/)\n- add RELEASE_NOTES v1.3.0 section with option-121 compatibility note\n- reconcile docs/parent-attached-modes.md against the milestone:\n  document stable_lease / lease_seed /\n[…]\n(GO-2026-5746, GO-2026-5617, and the newly published GO-2026-5668),\nso govulncheck reports them via init-chain traces; they are now accepted\nin .github/vuln-allowlist.txt (#292). Assessment unchanged.",
          "is_bot": false,
          "headline": "Prepare v1.3.0 release (#286)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-03T21:17:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "dd211f53eda3664bbc532a222cc7b379972f53bf",
          "body": "…check allowlist (#291) (#294)\n\nThe config claimed govulncheck was green on the accepted docker/docker\nadvisories and declared any govulncheck report as voiding an\nacceptance. Since the Go vuln DB imported the docker cp/archive\nadvisories (2026-06-28), govulncheck reports them through init-chain\nsym\n[…]\ny instead, map each GHSA to its GO- ID,\nand record why the two medium-severity advisories are absent from\nallow-ghsas (below fail-on-severity). No functional change: the\nallow-ghsas list is unchanged.",
          "is_bot": false,
          "headline": "docs(ci): reconcile dependency-review config comments with the govuln…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-03T21:17:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "519c815e7274846b3dbd1a9ee708adb95d9ad14e",
          "body": "… (#293)\n\nBumps the actions group with 8 updates in the / directory:\n\n| Package | From | To |\n| --- | --- | --- |\n| [actions/checkout](https://github.com/actions/checkout) | `6.0.3` | `7.0.0` |\n| [actions/setup-go](https://github.com/actions/setup-go) | `6.4.0` | `6.5.0` |\n| [github/codeql-action/in\n[…]\npe: version-update:semver-patch\n  dependency-group: actions\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "build(deps): bump the actions group across 1 directory with 8 updates…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-03T21:17:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "173c1eee9ae2bc1b21b5604e1647515338ddca37",
          "body": "…s (#289)\n\nBumps the docker group with 1 update in the / directory: golang.\nBumps the docker group with 1 update in the /ci/runner-image directory: debian.\n\n\nUpdates `golang` from `f1ddd9f` to `3ad5730`\n\nUpdates `debian` from `4e401d9` to `28de087`\n\n---\nupdated-dependencies:\n- dependency-name: debia\n[…]\npendency-type: direct:production\n  dependency-group: docker\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "build(deps): bump the docker group across 2 directories with 2 update…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-03T21:10:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "67deee0b2f119371e0b1aa978a8d1f5216d09f5c",
          "body": "… (#291) (#292)\n\nGO-2026-5617, GO-2026-5668 and GO-2026-5746 all live in dockerd's\ndocker cp / container archive handling; this plugin only uses the\nclient API. No fixed release exists for the legacy\ngithub.com/docker/docker module line (fix is only in\ngithub.com/moby/moby/v2@v2.0.0-beta.14), so per the allowlist rules\nthese are accepted with justification until a fixed release ships.",
          "is_bot": false,
          "headline": "ci(govulncheck): allowlist three daemon-side docker/docker advisories…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-07-03T20:43:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4b4f95e4ff9276568381931ee2daa889a47fc1f",
          "body": "…te (#219) (#285)\n\nipvlan children share the parent NIC's MAC on the wire, so a DHCP server\nkeying on MAC cannot tell them apart, and the default per-endpoint\nclient-id is derived from the random Docker endpoint ID, which changes on\nevery recreate. Add an opt-in stable_lease mode (ipvlan only) that \n[…]\nivation, the full\nresolve precedence, and the bridge/macvlan rejection; integration coverage\nfor same-IP-across-recreate (headline), distinct-identities-distinct-IPs\n(control), and the mode rejection.",
          "is_bot": false,
          "headline": "feat(ipvlan): stable DHCP client-id for lease stability across recrea…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-17T14:38:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "22f64910091d415bbade6deb55a19ac45b363209",
          "body": "…(#274)\n\nBumps the docker group with 2 updates in the / directory: golang and alpine.\n\n\nUpdates `golang` from `7a3e500` to `f1ddd9f`\n\nUpdates `alpine` from 3.24.0 to 3.24.1\n\n---\nupdated-dependencies:\n- dependency-name: golang\n  dependency-version: 1.26-alpine\n  dependency-type: direct:production\n  d\n[…]\nype: version-update:semver-patch\n  dependency-group: docker\n...\n\nSigned-off-by: dependabot[bot] <support@github.com>\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>",
          "is_bot": true,
          "headline": "build(deps): bump the docker group across 1 directory with 2 updates …",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-17T09:09:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "17f099b434fce7718186b8c5982be12272161841",
          "body": "refactor: rename pkg/udhcpc → pkg/dhcp, cmd/udhcpc-handler → cmd/dhcp-handler (#245)",
          "is_bot": false,
          "headline": "Merge pull request #284 from claymore666/feature/245-rename-dhcp-pkg",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T20:30:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c6aa0280251b0bf84ed102295c1496766d06d55",
          "body": "…-handler (#245)\n\nPost-#152 (busybox→dhcpcd) the udhcpc names are misnomers. Rename to\nclient-agnostic names so the package isn't tied to a concrete client\nagain:\n\n- pkg/udhcpc → pkg/dhcp (package, import paths, qualifiers)\n- cmd/udhcpc-handler → cmd/dhcp-handler (dir, built binary,\n  /usr/lib/net-d\n[…]\nhistorical \"busybox udhcpc/udhcpc6\" comments (accurate\nhistory) and RELEASE_NOTES.md (frozen per-release changelog).\n\nPure internal refactor — no wire, manifest, state, or upgrade impact.\n\nCloses #245",
          "is_bot": false,
          "headline": "refactor: rename pkg/udhcpc → pkg/dhcp, cmd/udhcpc-handler → cmd/dhcp…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T19:49:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "eb5fb6fe9c0925e7bbdffe8caea9a747f914ddf3",
          "body": "feat(dhcp): surface WPAD + timezone DHCP options (observe-only) (#262)",
          "is_bot": false,
          "headline": "Merge pull request #283 from claymore666/feature/262-wpad-timezone",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T19:45:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2d0c22f8d4394f4df3c42ece9af3a5caf71bb7cf",
          "body": "Parse and log four more server-supplied informational options, the same\nobserve-only way as NTP/TFTP (no container injection — the no-plumbing\nbar):\n- WPAD URL (option 252)\n- RFC 4833 timezone PCode/TCode (options 100/101)\n- legacy time offset (option 2)\n\ndhcpcd option names verified against the ima\n[…]\ndefine; integration (fixture advertises 252/100/101/2,\nasserts the plugin log surfaces them) — which also pins the dhcpcd option\nnames end-to-end. Docs: parent-attached-modes.md observed-options list.",
          "is_bot": false,
          "headline": "feat(dhcp): surface WPAD + timezone DHCP options (observe-only) (#262)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T19:23:15Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e26f8fc6e05121ecf3be090e0e46294c25b1da0b",
          "body": "A container on a `-o register_dns=true` network now asks the DHCP server\nto register its name in DNS: it becomes resolvable by name on the LAN,\nnot just reachable by its leased IP — the on-mission completion of the\nhostname hint we already send (no per-container plumbing).\n\n- dhcpcd config: new `fqd\n[…]\nter_dns=true container resolves <hostname>.<domain> to its leased\n  IP. The resolving itself proves opt 81 (not the bare hostname) landed.\n\nDocs: reference.md option table row + a dynamic-DNS section.",
          "is_bot": false,
          "headline": "feat(dhcp): opt-in DHCP FQDN registration (option 81/39) (#261) (#282)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T18:38:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "38976f13d704fd3794da7c02f75f81cc31f1224e",
          "body": "…m) (#281)\n\nREADME and docs/index.md said \"MIT — see LICENSE.md\", but LICENSE.md is\nand has always been the GPL-3.0 text, and GitHub detects the repo as\nGPL-3.0. Upstream (devplayer0/docker-net-dhcp) is GPL-3.0, so this fork —\na derivative work — must remain GPL-3.0; it was never MIT and could not\nb\n[…]\no MIT LICENSE file ever\nexisted and there are no MIT/SPDX headers in source. Correct the stated\nlicense to GPL-3.0 in both places and note the upstream inheritance so\nthe same confusion doesn't recur.",
          "is_bot": false,
          "headline": "docs: correct stated license to GPL-3.0 (matches LICENSE.md + upstrea…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T18:22:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c6ca90386b3e5e9f49a094b2291d33db88d2c958",
          "body": "…(#280)\n\nDHCP servers that hand out classless static routes (option 121, RFC 3442)\nwere ignored: dhcpcd was asked for the option, but the event builder never\nread new_classless_static_routes back and nothing applied it. Containers\nonly got routes copied from the host parent link, never DHCP-pushed o\n[…]\n option 121 to a\nvendor-class-tagged client and asserts the route lands in the container\n(and is absent without the opt-in). Docs: option-121 behaviour and the\nskip_routes interaction in reference.md.",
          "is_bot": false,
          "headline": "feat(routes): honor DHCP classless static routes (option 121) (#260) …",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T17:55:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "80c16bd4e9a5f3ba2315f21f85f81610e1441b30",
          "body": "The integration suite is ~20 min of mostly deliberate DHCP-protocol\nwaits, but where that wall-clock goes was only visible by grepping the\nverbose go-test output. Add a summary so every run self-documents its\nslowest tests.\n\n- scripts/integration-timing.sh: parse one or more 'go test -v' logs,\n  pri\n[…]\ny' step (pipefail keeps a test failure fatal despite\n  the tee).\n\nThis is the tooling that made the #253 renewal target obvious and points\nat the next ones (the failure suite and the v6 renewal test).",
          "is_bot": false,
          "headline": "ci(integration): surface a per-test timing summary (#277)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T16:53:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ae1fd5be848731c5d86c644ed70237c441658c2f",
          "body": "…255) (#273)\n\nThe plugin image was rebuilt from scratch every integration run (~43s):\nthe COPY of cmd/ and pkg/ invalidates the build layer on any code\nchange, so 'go build ./cmd/...' recompiled every package each PR with no\nincremental build cache, and 'go mod download' re-fetched modules.\n\nAdd Bui\n[…]\nakefile: export DOCKER_BUILDKIT=1 on build / build-cover so the\n  classic builder can't be picked up and choke on the mount flags\n  (Docker >= 23 defaults to BuildKit anyway; this is belt-and-braces).",
          "is_bot": false,
          "headline": "ci(integration): cache the plugin build's Go module + build caches (#…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T15:06:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c2ff5c87a0732e880b1fdc99e31bdae234c280de",
          "body": "… lease (#253) (#272)\n\nThe lease_renew test was the single longest case in the suite: it rode\nthe shared 2m fixture lease and waited ~70s for T1 (half-lease) to fire.\ndnsmasq's minimum lease is a hard 2m, so the lease can't be shortened —\nbut a server may advertise DHCP option 58 (T1, renewal) / 59 \n[…]\nn top of the bind, IP unchanged). The\nmechanism is self-validating — if the advertised T1 is not honoured, no\nrenewal ACK lands in the shortened window and the test fails rather than\nsilently passing.",
          "is_bot": false,
          "headline": "test(integration): drive lease renewal via advertised T1, not a short…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T14:04:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cf9117802796348479a7cc09932877369b0793b0",
          "body": "The failure-injection suite and two v6 recovery polls slept at 1–2s in\npure poll-until-condition loops, overshooting the moment each bounded\ncondition was actually met. Drop them to a 250ms floor (500ms for the\nre-acquisition loop, which polls via docker exec) so the loops return\nsooner. Deadline bu\n[…]\ns floor honours the caution in #254: keep extra CPU off the\ntiming-sensitive preflight probe. Sleeps already at 100–500ms and the\nreal protocol-timing waits (the ~30s outage ticks) are left untouched.",
          "is_bot": false,
          "headline": "test(integration): tighten coarse poll intervals (#254) (#271)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T13:26:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b76ca5faf1716be52070215b841bd350e9162e79",
          "body": "… (#267) (#270)\n\n:latest was published by a SECOND `make push`, which re-ran\n`docker plugin create` and re-tarred the rootfs non-reproducibly — so\n:latest got its own digest, distinct from :vX.Y.Z and uncovered by the\ncosign signature (cosign signs by digest). Confirmed live: :v1.1.1 and\n:latest car\n[…]\nr diverges again\n\nThe retag is :latest-only (off for rc), so the rc dry-run does not\nexercise the wiring; the mechanism is validated manually on the issue,\nand the assertion guards every real release.",
          "is_bot": false,
          "headline": "fix(release): retag :latest onto the signed version digest with crane…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T10:58:17Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6c45ed5fa06936d74a3f0c85157ff81ab33f7996",
          "body": "Closes #268. Split intent (docs/requirements.in) from a pip-compile --generate-hashes lock (docs/requirements.txt); both pip installs use --require-hashes. Clears the two Scorecard PinnedDependencies alerts. Dependabot bumps versions+hashes together.",
          "is_bot": false,
          "headline": "ci(pages): hash-pin the Python doc toolchain (#269)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T10:35:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4819317c39cee3d726f56b21c88ff230af04c85c",
          "body": "Release v1.2.0 — cosign v3 signing fix",
          "is_bot": false,
          "headline": "Merge pull request #266 from claymore666/dev",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T08:08:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e39fd9b48826138556121476ce0fe8c30614c0f4",
          "body": "…#265)\n\nThe cosign-installer bump (#196) moved the installed cosign binary from\nv2 to v3.0.6. cosign v3 removed sign-blob's --output-signature /\n--output-certificate pair in favour of a single Sigstore bundle, so the\n\"Package and sign release artifact\" step failed:\n\n    Error: signing checksums.txt:\n[…]\nhcp:v1.1.1\n  placeholder in parent-attached-modes.md to v1.2.0\n- generalise bump-version.sh to match the image at any namespace so\n  placeholder examples bump too (the v1.1.1 drift above was this gap)",
          "is_bot": false,
          "headline": "fix(release): migrate cosign sign-blob/verify-blob to the v3 bundle (…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T07:43:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "26d5f1e30fd49880c332abced97489341816bc51",
          "body": "Release v1.2.0",
          "is_bot": false,
          "headline": "Merge pull request #257 from claymore666/dev",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-16T07:13:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "63ce96eb7792d1e6d7df03f75310b315764de085",
          "body": "…tays measured (#259)\n\nThe dhcpcd migration (#152) silently dropped cmd/udhcpc-handler out of\nthe coverage ratchet: the cover build sets GOCOVERDIR in the plugin env\nand the handler (a separate process) used to inherit it, but dhcpcd\nscrubs the environment before exec'ing its hook — the same reason \n[…]\n it set. Production never sets GOCOVERDIR, so this emits\nnothing there; only the -cover build (config-cover.json sets\nGOCOVERDIR=/coverage) is affected, restoring the handler's counters.\n\nCloses #258.",
          "is_bot": false,
          "headline": "fix(coverage): forward GOCOVERDIR to the dhcpcd hook so the handler s…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T23:16:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "273e9d93e19ce002923df199bd65258179fe581b",
          "body": "…s (#256)\n\n- Bump every published-image install pin v1.1.1 → v1.2.0 across README\n  and docs/ via scripts/bump-version.sh (#251's first real use; it\n  caught pins in bridge-mode.md and index.md that the manual list\n  missed).\n- Add the ## v1.2.0 RELEASE_NOTES section: dhcpcd replaces busybox\n  (#152\n[…]\ns a\n  \"future enhancement\" — both shipped in this release via the dhcpcd\n  migration. Also corrected the capability list (the manifest grants\n  CAP_NET_ADMIN + CAP_SYS_ADMIN only, not CAP_SYS_PTRACE).",
          "is_bot": false,
          "headline": "docs: v1.2.0 release prep — bump pins, RELEASE_NOTES, doc-review fixe…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T22:26:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b4c49513402dbfd0b3971e5d0ae251c606bba91b",
          "body": "…252)\n\nThe release version-pin bump (runbook step 2) was a manual hand-edit of\nevery published-image snippet in README/docs — mechanical and easy to\ndo partially, which ships docs that install the previous version.\n\nAdd scripts/bump-version.sh vX.Y.Z, which rewrites only the image-ref\npins (ghcr.io/\n[…]\nt breaking the release branch where pins lead the latest tag.\nscripts/test-check-version-pins.sh self-tests both, per the gates-are-\ntested rule. Runbook step 2 now points at the script.\n\nCloses #251.",
          "is_bot": false,
          "headline": "ci: automate release version-pin bump + add a pin-consistency gate (#…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T21:56:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "599a74fe0034914295955f85738a85c83e619ce7",
          "body": "* ci(integration): add opt-in hosted cross-check lane (#238)\n\nAdd integration-hosted.yml: runs the live integration + failure-injection\nsuites on a stock ubuntu-latest runner via workflow_dispatch and a weekly\nschedule. It is explicitly non-gating and not a required check — a\nportability probe that \n[…]\nld pending it is now live (it starts firing once the file\nreaches the default branch). Refresh the security note: schedule, like\nworkflow_dispatch, runs repo-owned code only — no fork-PR-as-root path.",
          "is_bot": false,
          "headline": "ci(integration): opt-in hosted cross-check lane (#238) (#241)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T21:56:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7b3fb7d73f2aad5c39c0cecd9ce153a3d06857dd",
          "body": "…only proc (#250)\n\ndhcpcd writes net/ipv4/conf/<if>/promote_secondaries (and, for v6,\nautoconf/accept_ra) during if_init regardless of --noconfigure. On a\nread-only /proc/sys — the managed-plugin rootfs, and stock Docker\ncontainers where runc remounts it ro — the v4 write returns EROFS,\ndhcpcd abort\n[…]\n-hosted runner).\n\nAlso tee dhcpcd's stderr into a bounded tail buffer and fold it into the\nnon-zero-exit error, so a future failure surfaces dhcpcd's real\ndiagnostic instead of a bare \"exit status 1\".",
          "is_bot": false,
          "headline": "fix(dhcpcd): remount /proc/sys rw so interface setup survives a read-…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T19:03:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "892bdbc261691b00d6e9b4035df7719fa217782a",
          "body": "* fix(ipvlan): wire the dhcpcd broadcast directive (#243)\n\nipvlan-L2 slaves share the parent NIC's MAC, so a unicast OFFER/ACK to\nthat MAC during initial acquisition can't be demuxed to the right slave.\nbusybox set the DHCP BROADCAST flag for this via 'udhcpc -B'; the dhcpcd\nport (#223) declared DHC\n[…]\ns it robust regardless of whether the server unicasts to an\nunconfigured client. All five lifecycle tests (incl. ipvlan without the\nfixture crutch) already passed; this fixes the remaining probe test.",
          "is_bot": false,
          "headline": "fix(ipvlan): wire the dhcpcd broadcast directive (#243) (#249)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T18:37:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "74a8b5a6da735091d151a23df60b99b7efcb8e4b",
          "body": "…gration (#242) (#244)\n\nThe busybox->dhcpcd migration (#152) and v6 work (#213) shipped, but many\ncode comments still described the old busybox udhcpc/udhcpc6 client and\nits mechanisms. Update comments (and a couple of log/string texts) to the\ndhcpcd reality across pkg/plugin, pkg/udhcpc, pkg/util, \n[…]\n' own busybox tooling (genuinely busybox, not the plugin\nclient).\n\nFlagged a real latent gap found during the sweep: the ipvlan\nDHCPClientOptions.Broadcast field is a no-op in the dhcpcd port -> #243.",
          "is_bot": false,
          "headline": "chore: refresh stale udhcpc/busybox code comments after the dhcpcd mi…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T11:56:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "35ba85e152517e50c4d698d3ab59da08641c3c31",
          "body": "…stone (#239) (#240)\n\nThe doc review (step 3) was a memory-based top-to-bottom read, with the\nrc dry-run (step 8) as the last checkpoint. That let the #205<->#152\ndrift through: a behaviour change shipped while the docs were restructured\nin the same milestone, and the prose still described the old c\n[…]\nsignal to look harder. The full top-to-\nbottom read stays as the catch-all. Reframe the rc window (step 8) as the\nenforcement gate: no real tag until every milestone PR is ticked off\nagainst the docs.",
          "is_bot": false,
          "headline": "docs(runbook): make the release doc review PR-driven against the mile…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T11:55:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1023dcf1c8cbbc4bda05f521b92b23f8d646b599",
          "body": "* docs: correct client references for the dhcpcd migration (#234)\n\nThe README/docs restructure (#205) and the busybox->dhcpcd client\nmigration (#152) landed in the same milestone, leaving the restructured\ndocs describing the old busybox udhcpc/udhcpc6 client. Bring every\nclient-behaviour description\n[…]\nys state by interface name with no runtime override. Kept at\nthe conceptual altitude: no argv flags or wire-format specifics (those\nlive in code comments, which can drift with the code they describe).",
          "is_bot": false,
          "headline": "docs: correct client references for the dhcpcd migration (#234) (#237)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T11:55:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "9a87bf5b4c65baaf279bf5e4e5f17b246a07737b",
          "body": "…t) (#213) (#236)\n\nTwo IPv6 inputs were captured but dropped because busybox udhcpc6 had\nno v6 equivalent of -r: a static --ip6 (Interface.AddressIPv6) and the\nprior endpoint's v6 address preserved through the tombstone. v6 was\ntherefore non-sticky exactly where v4 was sticky.\n\nNow that #152 moved t\n[…]\nack container keeps its v6\naddress across docker restart (the v6 sibling of the v4 tombstone\ntest). Docs (reference, parent-attached-modes) corrected — they\npreviously stated v6 requests were ignored.",
          "is_bot": false,
          "headline": "feat(dhcpv6): request a preferred IPv6 address (--ip6 + tombstone hin…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T10:22:07Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "af82874bdd2ddb832e30327aa68d31aa19a4fbaf",
          "body": "The /Plugin.Health wire counters (leases_obtained, leases_renewed,\ndhcp_timeouts, naks_received, lease_changed) were family-agnostic:\nhandleEvent/renew already receive a v6 bool but bumped the same atom\nfor v4 and v6. On a dual-stack host that hides the v6-specific failure\nsignal — exactly what we n\n[…]\nvent leaves the v6 sibling at zero (and vice versa), plus that the\nnew fields serialize under their snake_case keys on /Plugin.Health.\nDocs Health sections (reference + parent-attached-modes) updated.",
          "is_bot": false,
          "headline": "feat(health): split DHCP wire counters by address family (#212) (#235)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T09:40:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c305403016e67a4a2409cdfa88ef72fbb8e40f00",
          "body": "* refactor(udhcpc): parse dhcpcd hook events instead of busybox (#152)\n\nbusybox udhcpc6 fills the DHCPv6 IAID with rand() per process and offers\nno override, so the CreateEndpoint one-shot and the persistent client\nalways land in different identity associations and the server hands out\ntwo addresses\n[…]\nllowlist (1–15 chars, alphanumeric-led, [A-Za-z0-9._-])\nbefore it can reach the command — closing the taint flow and rejecting\nany flag-shaped or shell-meaningful value as the simple correct contract.",
          "is_bot": false,
          "headline": "DHCPv6: replace busybox with dhcpcd to unify the IA (#152) (#223)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T09:15:53Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "7d804151432a185f536b69bb06dfd13a43b540bb",
          "body": "…) (#233)\n\nCodeQL go/path-injection (CWE-22): the per-network options helpers\ninterpolate networkID — which originates from the libnetwork driver\nrequest — into filesystem paths without validation\n(stateFilePath -> filepath.Join; saveOptions -> os.CreateTemp pattern).\nA network ID containing path se\n[…]\nqueness), removing that taint sink entirely.\n- Unit tests cover the rejection paths and that nothing is written\n  out of bounds.\n\nPre-existing; surfaced as the only red, non-required check on PR #223.",
          "is_bot": false,
          "headline": "fix(state): validate networkID before building state-file paths (#232…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T08:30:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "52d5cf62b1cfde91cf052c403259bd12e3384227",
          "body": "apk-pin-check signals when a newer busybox-extras/iproute2 is available\nbut not whether the pinned versions carry CVEs. Add a Trivy scan of the\nbuilt runtime rootfs scoped to OS packages (--pkg-types os), so it\ncomplements rather than overlaps govulncheck (Go, reachability-gated).\n\nInformational lik\n[…]\nr the same discipline as the govulncheck\nallowlist: justification + review date, never a bare ID.\n\nRuns weekly, on dispatch, on push to dev, and on PRs that touch the\nDockerfile or this scan's config.",
          "is_bot": false,
          "headline": "ci: scan plugin rootfs for OS-package CVEs with Trivy (#143) (#231)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-15T00:29:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "db537f846d020b96d34854278c978e5d3b1e15c9",
          "body": "ci: bump alpine to 3.24.0 + re-pin apk packages (#195)",
          "is_bot": false,
          "headline": "Merge pull request #230 from claymore666/ci/195-alpine-3.24",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T23:43:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eea3dc3864dc9f166055664714e723f07d913139",
          "body": "Dependabot #195 bumped only the FROM digest, which breaks the build: the\napk pins (busybox-extras, iproute2) reference 3.20 package versions that\ndon't exist in 3.24's repos. Re-pin both to their 3.24.0 versions so the\nruntime stage installs cleanly:\n\n- busybox-extras 1.36.1-r31 -> 1.37.0-r31 (suppl\n[…]\n.9.0-r0    -> 7.0.0-r0\n\nVerified: image builds on alpine:3.24.0; udhcpc, udhcpc6, and ip present\nin the runtime image; scripts/check-apk-pins.sh --strict reports all pins\ncurrent against the new base.",
          "is_bot": false,
          "headline": "ci: bump alpine to 3.24.0 and re-pin apk packages (#195)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T23:25:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d25947b87e14b6e1c4803191d436dfd323221a28",
          "body": "ci: bump cosign-installer to v4.1.2, hold download-artifact at v7 (#196)",
          "is_bot": false,
          "headline": "Merge pull request #227 from claymore666/ci/196-split-deps",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T23:22:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f873cc2bd44e6d65de7e1f319c98eb0b8db819a7",
          "body": "ci: bump pages.yml setup-python to v6.2.0 (Node 24) (#225)",
          "is_bot": false,
          "headline": "Merge pull request #226 from claymore666/fix/225-setup-python-node24",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T23:10:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d7df9ea27d08b7960c1e012d62bb9d7ab149b9cc",
          "body": "Splits Dependabot's grouped actions PR (#196) so the two bumps can be\nhandled on their own risk profiles:\n\n- sigstore/cosign-installer 3.9.2 -> 4.1.2 (default cosign 2.x -> 3.x).\n  Release-path only (release.yml signing step); not exercised by PR CI,\n  so it must ride an rc-tag dry-run before the ne\n[…]\nad-artifact has no v8 yet, so\n  pairing upload v7 with download v8 would mix majors on the release\n  artifacts. Added a Dependabot ignore (>= 8) until upload-artifact v8\n  ships so both bump together.",
          "is_bot": false,
          "headline": "ci: bump cosign-installer to v4.1.2, hold download-artifact at v7 (#196)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T23:05:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3693fce69118eb0113e908c86e0fc721d7fb8a20",
          "body": "actions/setup-python v5 runs on Node 20, which GitHub forces off on\n2026-06-16. v6.2.0 declares using: node24. Bump both the build and deploy\njobs; the rest of the repo's actions are already on node24-capable majors.",
          "is_bot": false,
          "headline": "ci: bump pages.yml setup-python to v6.2.0 (Node 24) (#225)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T22:53:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eb56239bdd708f61ec5c89563191042d2e2eec05",
          "body": "docs: versioned documentation site via GitHub Pages (#133)",
          "is_bot": false,
          "headline": "Merge pull request #224 from claymore666/docs/133-pages-site",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T22:44:23Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ffe332a56bb94059ee2dc59251732881a0a9cdc7",
          "body": "Add a project documentation site built from the in-repo docs/ tree with\nmkdocs-material and versioned with mike, mirroring the registry tagging\nscheme: each release publishes its vX.Y.Z docs and moves the latest\nalias; rc tags publish a preview without moving latest; dev pushes\nrefresh a moving dev \n[…]\ntracked).\n- runbook: one-time Pages enablement + per-release behavior; the docs\n  review now is the site review.\n- README: docs-site badge + link; reference.md cross-link repointed to\n  the site home.",
          "is_bot": false,
          "headline": "docs: versioned mkdocs-material site published to GitHub Pages (#133)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T22:27:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "085bd392d33af4a0b2bb8bdbe1458d6fa58c4770",
          "body": "docs: restructure README into a concise landing page + docs/ split (#205)",
          "is_bot": false,
          "headline": "Merge pull request #222 from claymore666/docs/205-readme-restructure",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T22:01:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4910e566ab7a5873d860243ea8e6f70eae67cdcd",
          "body": "The README had grown to ~300 lines doing four jobs at once (marketing,\nquick start, deep how-to, internals). Split it into a ~150-line landing\npage that routes to docs/:\n\n- New docs/bridge-mode.md: the manual host-bridge setup + network/\n  container walkthrough moved out of the README.\n- New docs/in\n[…]\nserved (linked from\nSECURITY.md, GOVERNANCE.md, RELEASE_NOTES.md, reference.md, and the\nOpenSSF badge/Scorecard evidence). All internal links verified.\n\nPrecursor to #133 (Pages docs site).\n\nRefs #205",
          "is_bot": false,
          "headline": "docs: restructure README into a concise landing page + docs/ split",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T21:43:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "46fe075b6a14875078e9bb976bed4d31537ceb29",
          "body": "tests: unit-level error-path coverage via docker + netlink seams (#206)",
          "is_bot": false,
          "headline": "Merge pull request #220 from claymore666/tests/206-coverage-ratchet",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T21:38:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dfbc2b6fd4cce96932be4233f209221f0c6f205c",
          "body": "Lock in the error-path coverage from this PR. Merged unit+integration\non the Coverage workflow measured pkg/plugin 82.3% (restoring the\npre-v1.0.0 ~82 level the v1.0.0 decision intended to ratchet back to)\nand pkg/util 88.7%. Floors set with epsilon headroom.\n\npkg/udhcpc and cmd/net-dhcp are left at their floors: their small bumps\nthis run are integration run-to-run variance, not earned by this PR.\n\nRefs #206",
          "is_bot": false,
          "headline": "ci: ratchet coverage floors — pkg/plugin 77.5->82.0, pkg/util 87.0->88.0",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T18:11:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1f83b832a39aad3102cdafc508a43bae4df6edec",
          "body": "…quire arm\n\nPush the docker/netlink seams further now that they're in place:\n\n- findLinkByMAC takes a linkLister interface (*netlink.Handle satisfies\n  it), so the MAC-walk logic is unit-tested for list-error/no-match/found\n  without a live netns handle.\n- addRoutes: add v6 default-gateway, skip_rou\n[…]\nl-route-skip and\n  on-link (no-gateway) cases -> 100%.\n- reacquireEndpoint: cover the docker MAC-lookup error arm via the fake\n  client; the CreateEndpoint replay stays integration-covered.\n\nRefs #206",
          "is_bot": false,
          "headline": "tests: extend seam coverage — findLinkByMAC, addRoutes branches, reac…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T17:50:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c57f3e5256998e33220a1e812f9eecccaa8b2aea",
          "body": "Introduce two narrow test seams so the failure arms that previously\nonly ran (or never ran) under integration become unit-testable:\n\n- dockerClient interface (Close/ContainerInspect/NetworkInspect/\n  NetworkList) replaces the concrete *client.Client on Plugin and\n  dhcpManager; util.AwaitContainerIn\n[…]\nerver/non-error log classes.\n\nNo behavioural change to production code — each seam var is the netlink\nfunction it replaces, and the concrete docker client satisfies the new\ninterface as-is.\n\nRefs #206",
          "is_bot": false,
          "headline": "tests: add unit-level error-path coverage via docker + netlink seams",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T17:38:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0730c6d27c3ce5b764c5cfe5d3237163a134d63a",
          "body": "docs: governance, code of conduct, security assurance (OpenSSF silver)",
          "is_bot": false,
          "headline": "Merge pull request #217 from claymore666/docs/silver-governance-coc",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T17:02:57Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ef45cd93d2bea507eba6a0bbb287aedf108ba88b",
          "body": "Adds project-oversight and security documentation for OpenSSF Best\nPractices silver:\n- GOVERNANCE.md: maintainer model, roles/responsibilities, decision\n  process, path to additional maintainers.\n- CODE_OF_CONDUCT.md: adopts Contributor Covenant 2.1 by reference with\n  a conduct-report contact.\n- SE\n[…]\nurance case (goals, threats,\n  mitigations, residual risk).\n\nHonest note: silver's access_continuity (MUST) and bus_factor remain\nunmet while solo-maintained; these address the documentation criteria.",
          "is_bot": false,
          "headline": "docs: add governance, code of conduct, security assurance case",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T15:13:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8ced2aff606fc270dbc666abade79dba759597b7",
          "body": "Release v1.1.1",
          "is_bot": false,
          "headline": "Merge pull request #211 from claymore666/dev",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T14:51:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "26513c7b329ecfc26320b63e0bedf9566195a086",
          "body": "Bump install/usage pins v1.1.0 -> v1.1.1 in README and docs (historical\n'v1.1.0 onward'/'v1.1.0+' signing references left intact), and add the\nv1.1.1 RELEASE_NOTES section (compliance/hygiene release, no functional\nplugin changes).",
          "is_bot": false,
          "headline": "docs: v1.1.1 release prep — bump install pins, add RELEASE_NOTES (#210)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T14:19:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f9ef48aac0608755c5378ab9deae2dd182a3d9e5",
          "body": "New step 11: after the dev fast-forward, delete the release branch and\nsweep for any other branch already merged into dev. Notes that\nauto-delete-on-merge (now enabled) covers PR head branches, and that\nopen-PR / Dependabot / upstream-remote branches are left alone.",
          "is_bot": false,
          "headline": "docs: add post-release branch-prune step to runbook (#209)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T13:54:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6339488d9eade5dd1948273e52f2357fdcfa9d0d",
          "body": "Project earned the OpenSSF Best Practices passing badge\n(bestpractices.dev project 13229). Add it to the README badge row;\nalso feeds the Scorecard CII-Best-Practices check.",
          "is_bot": false,
          "headline": "docs: add OpenSSF Best Practices passing badge (#204)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T13:38:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dbdb1dc8e1cd806a8901c05656ebe58a0032196f",
          "body": "* docs: add Contributing section to README\n\nDocuments how to interact (issues), how to contribute (PRs against dev +\nrequired CI checks + tests-with-changes policy), and points to SECURITY.md\nfor vulnerability reports. Satisfies the human-readable interaction/\ncontribution documentation expected by \n[…]\niccheck, plus\nshellcheck/actionlint) and the tests/green-CI requirements, so the\ncontribution requirements are documented for contributors (OpenSSF Best\nPractices contribution_requirements criterion).",
          "is_bot": false,
          "headline": "docs: add Contributing section to README (#200)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T13:38:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "265d6c286c728e7ed648b3571804f1aa22c72454",
          "body": "Adds GitHub issue forms (bug report, feature request), an ISSUE_TEMPLATE\nconfig that disables blank issues and links the private security-advisory\nprocess, and a PR template with a contributor checklist (targets dev,\ntests added, docs updated, no secrets). Aligns the contribution surface\nwith OpenSSF Best Practices report/contribution criteria.",
          "is_bot": false,
          "headline": "ci: add issue forms and PR template (#202)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T13:32:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "865e62c5b6bd24da62c0882823cb1fd9bef7f919",
          "body": "The default GITHUB_TOKEN cannot read branch-protection settings, so the\nBranch-Protection check scored -1 (inconclusive) despite protection being\nconfigured. Wire a single-repo, read-only fine-grained PAT (Administration:\nread) via the SCORECARD_TOKEN secret as scorecard-action's repo_token.",
          "is_bot": false,
          "headline": "ci: give Scorecard a read-only admin token for Branch-Protection (#198)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T13:32:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a7a214033b85f43f9317ebdf95bb78d29956979d",
          "body": "Release v1.1.0",
          "is_bot": false,
          "headline": "Merge pull request #192 from claymore666/dev",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T10:44:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0b821e114d2da7c184f90ad25eb5dfd136d4123c",
          "body": "…isories\n\nci: allowlist unreachable docker/docker advisories in dependency-review (#193)",
          "is_bot": false,
          "headline": "Merge pull request #194 from claymore666/ci/193-dep-review-docker-adv…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T02:03:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7feef57c6e86b7917f33b445b3e5f6dc4261b33",
          "body": "…endency-review (#193)\n\ndependency-review flags three high docker/docker advisories on the\ndev->main release PR (the go-deps bump moves the module 28.4.0->28.5.2).\nAll three are daemon-side / docker-cp-side Moby paths; this plugin uses\nthe module only as a client (NetworkList/NetworkInspect/Containe\n[…]\nor the three GHSAs, mirroring vuln-allowlist.txt\n(justification + 2026-06-14 review date, reachability as arbiter).\nDocument the two newer advisories in RELEASE_NOTES acknowledged-findings.\n\nRefs #193",
          "is_bot": false,
          "headline": "ci: allowlist unreachable daemon-side docker/docker advisories in dep…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T01:46:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2c827da5ef6f9294bfafb39061c9d685b9461f41",
          "body": "docs: v1.1.0 release prep (version bumps, verification docs, release notes)",
          "is_bot": false,
          "headline": "Merge pull request #191 from claymore666/release/v1.1.0",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T01:36:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c0cba7cc1c4bdb6b03f83366f388bcf52bf964e4",
          "body": "…NOTES",
          "is_bot": false,
          "headline": "docs: prep v1.1.0 — bump image tags, add Verifying releases, RELEASE_…",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T01:19:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "99745e2fa458fda5d9a9a5e2f6498e7e3f6b8ee0",
          "body": "ci: fix check-apk-pins.sh trailing-colon false positive + self-test (#169)",
          "is_bot": false,
          "headline": "Merge pull request #190 from claymore666/fix/169-apk-pin",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T01:15:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "acf6919f73f9d4d0c05dc8cea182f85fbea9d12c",
          "body": "apk policy prints the candidate version with a trailing colon\n(1.36.1-r31:), which the checker compared verbatim against the pin\n(1.36.1-r31) — so a current pin was always reported as an upgrade\ncandidate. Strip the trailing colon before comparing.\n\nAdd scripts/test-check-apk-pins.sh (table-driven, \n[…]\nr) and\nwire it into the gate self-tests. It was the only gate script without a\nself-test — the gap that let this ship. The regression case fails on the\nunfixed script and passes on the fix.\n\nRefs #169",
          "is_bot": false,
          "headline": "ci: fix check-apk-pins.sh trailing-colon false positive + add self-test",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T00:57:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "2695a24f2d3593d9b3cbc2465998186ee4b9db7c",
          "body": "build: Go 1.25.9 → 1.26.4 (#177 step 2 of 2)",
          "is_bot": false,
          "headline": "Merge pull request #189 from claymore666/ci/177-go126-gomod",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T00:47:39Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "67f9f7486839eb251411b2d44131e7a0b7793462",
          "body": "Source side of the Go 1.26 bump. The runner pool is already on Go 1.26\n(runner image #187/#188, orchestrator pulled), so this PR's integration\nruns on the 1.26 pool.\n\n- go.mod: go 1.26.4\n- test.yaml + coverage.yml: go-version 1.25 -> 1.26 (5 pins)\n- Dockerfile builder: golang:1.25-alpine -> golang:1\n[…]\n, so they follow\nautomatically. Validated locally on go1.26.4: go mod tidy -diff clean,\nbuild, vet, race tests, and staticcheck v0.7.0 all pass (staticcheck\nsupports 1.26 — no bump needed).\n\nRefs #177",
          "is_bot": false,
          "headline": "build: bump Go 1.25.9 -> 1.26.4 (#177 step 2 of 2)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T00:28:47Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "fd55ff7f5d27eff4e550b3c062469da2e1cad83f",
          "body": "ci(runner-image): selftest checks golang:1.26 seed (#177 step 1 fix)",
          "is_bot": false,
          "headline": "Merge pull request #188 from claymore666/ci/177-selftest-go126",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-14T00:06:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7f17990fa51141132f71af00df37e7b64efb3c06",
          "body": "#187 bumped the seeded golang base to 1.26 in the Dockerfile but left\nthe entrypoint selftest asserting golang:1.25-alpine, so the Go-1.26\nimage failed its own selftest (\"golang seed missing\") and — correctly —\ndid not publish. Point both seed checks at golang:1.26-alpine.\n\nThe selftest gate working as intended: a mismatched image never reached\n:latest, so the pool was untouched.\n\nRefs #177",
          "is_bot": false,
          "headline": "ci(runner-image): selftest checks golang:1.26 seed (follow-up to #187)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T23:48:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c0917c86e937a6be6d13d512429dd84a1c9a6c59",
          "body": "ci(runner-image): bump baked Go 1.25.9 → 1.26.4 (#177 step 1 of 2)",
          "is_bot": false,
          "headline": "Merge pull request #187 from claymore666/ci/177-runner-go126",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T23:46:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5bb38dbf2d00b5ffcdf26d4cd877e86a21de4f27",
          "body": "First half of the Go 1.26 bump. The dhcp-ci runner image bakes the Go\ntoolchain (integration skips setup-go) and seeds the golang base for the\nnested plugin build, so the pool must be on 1.26 BEFORE go.mod is bumped\n— otherwise the go.mod bump PR runs its own integration on a 1.25 pool.\n\n- ARG GO_VE\n[…]\non still builds on the\ncurrent 1.25 pool. After merge, runner-image.yml republishes :latest;\nthe orchestrator must pull it and a job must pass on 1.26 before the\ngo.mod bump (step 2) opens.\n\nRefs #177",
          "is_bot": false,
          "headline": "ci(runner-image): bump baked Go 1.25.9 -> 1.26.4 (#177 step 1)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T23:18:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "51c77d28520206fd8fd96722d468ddbf7db23d7c",
          "body": "ci: CodeQL advanced setup for Go + actions (#170)",
          "is_bot": false,
          "headline": "Merge pull request #179 from claymore666/ci/170-codeql-advanced",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T23:09:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "600200c4c62c0bf5ae71dc9e807d80848c5a039d",
          "body": "ci: release signing tier — images + provenance + SBOM + signed tags (#173, #174, #175)",
          "is_bot": false,
          "headline": "Merge pull request #186 from claymore666/ci/173-174-supply-chain",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T22:37:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da8087c0cf28ee8d40fa837258b253eb12307330",
          "body": "The first cut used build-mode: none, but CodeQL 2.25.x rejects that for\nGo (\"Go does not support the none build mode\"). autobuild is the other\noption but it runs make -> docker export -> root-owned plugin/rootfs\nfiles that break CodeQL DB bundling. So use build-mode: manual with a\nplain `go build ./...` (+ setup-go from go.mod) — CodeQL traces the\ncompile, no make/docker involved.\n\nRefs #170",
          "is_bot": false,
          "headline": "ci: CodeQL Go uses build-mode manual (none is unsupported for Go)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T22:29:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b7fcd59b2dd90409b1e0983bb12d7aca182bbc91",
          "body": "The primary language (Go) was unscanned by CodeQL — default setup ran\nonly on actions + a phantom python language. Default setup also cannot\nanalyze this repo's Go: its autobuild invokes make, whose default\ntarget builds the plugin rootfs via docker export and leaves root-owned\nfiles (plugin/rootfs/\n[…]\n export — covering all source files, and keeps the\naction SHA-pinned with the config in version control like the other\nworkflows. Default setup has been disabled so the two do not conflict.\n\nRefs #170",
          "is_bot": false,
          "headline": "ci: add CodeQL advanced setup for Go + actions",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T22:29:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "107a03f2454bb005b04fda59e026ea435bbffd3e",
          "body": "ci: Dependency Review action to gate PRs on new vulnerable deps (#171)",
          "is_bot": false,
          "headline": "Merge pull request #180 from claymore666/ci/171-dependency-review",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T22:27:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a3e02f96c5c86650b24d76e59c66f55b6c225fe8",
          "body": "ci: bump actionlint v1.7.7 → v1.7.12 (part of #177)",
          "is_bot": false,
          "headline": "Merge pull request #185 from claymore666/ci/177-actionlint-bump",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T22:27:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2cb89d79da0ae5af23e415e6dd01cac0efe66ad5",
          "body": "Switch the tag commands (rc + real) to `git tag -s` so release tags\nshow Verified, and document `git tag -v` confirmation. The dev box\nalready has tag.gpgsign=true (verified commits were set up separately);\nthis makes the runbook explicit so it holds from any checkout. Also\nrefresh the expected-step\n[…]\nhe new image-signing / SBOM /\nprovenance steps.\n\nVerified commits (the other half of #175) are already live; branch-\nprotection \"require signed commits\" enforcement stays optional/deferred.\n\nRefs #175",
          "is_bot": false,
          "headline": "docs: sign release tags in the runbook (#175)",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T21:40:34Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "823608b73ddb06cfb242cb157660b6b87f36d218",
          "body": "Extends the release supply chain (builds on #163, which signs the\nrelease tarball/checksums):\n\n- #173 image signing: resolve each published plugin's registry digest\n  (docker buildx imagetools inspect reads it despite the plugin media\n  type) and cosign-sign it keylessly on GHCR (and Docker Hub when\n[…]\n end-to-end at the next vX.Y.Z-rcN dry-run (per #163). Locally\nvalidated: actionlint+shellcheck clean, YAML parses, and plugin-digest\nextraction confirmed against the published image.\n\nRefs #173, #174",
          "is_bot": false,
          "headline": "ci: sign release images, attest provenance, attach SBOM",
          "author_name": "Chris",
          "author_login": "claymore666",
          "committed_at": "2026-06-13T21:39:03Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 28,
      "commits_last_year": 323,
      "latest_release_at": "2026-07-06T00:55:50Z",
      "latest_release_tag": "v1.3.3",
      "releases_from_tags": false,
      "days_since_last_push": 2,
      "active_weeks_last_year": 5,
      "days_since_latest_release": 16,
      "mean_days_between_releases": 2.2
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 85,
      "has_issue_template": false,
      "has_code_of_conduct": true,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": [
        {
          "name": "github.com/devplayer0/docker-net-dhcp",
          "exists": true,
          "license": null,
          "keywords": [],
          "ecosystem": "go",
          "matches_repo": false,
          "registry_url": "https://pkg.go.dev/github.com/devplayer0/docker-net-dhcp",
          "is_deprecated": false,
          "latest_version": "v0.1.4",
          "repository_url": "https://github.com/devplayer0/docker-net-dhcp",
          "versions_count": 5,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": null,
          "latest_published_at": "2021-07-15T17:57:10Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 1833
        }
      ]
    },
    "popularity": {
      "forks": 1,
      "stars": 9,
      "watchers": 1,
      "fork_history": {
        "days": [
          {
            "date": "2026-07-09",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 1,
        "total_forks": 1
      },
      "star_history": null,
      "open_issues_and_prs": 17
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [
        "Makefile"
      ],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [
        "go.mod"
      ],
      "largest_source_bytes": 41827,
      "source_files_sampled": 86,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "docs/requirements.txt",
        "go.mod",
        "scripts/requirements.txt"
      ],
      "advisories": {
        "error": null,
        "scope": "repository_graph",
        "source": "osv",
        "findings": [
          {
            "name": "github.com/docker/docker",
            "direct": true,
            "version": "v28.5.2+incompatible",
            "severity": "high",
            "ecosystem": "go",
            "cvss_score": 8.8,
            "advisory_ids": [
              "GHSA-pxq6-2prw-chj9",
              "GHSA-rg2x-37c3-w2rh",
              "GHSA-vp62-88p7-qqf5",
              "GHSA-x744-4wpc-v9h2",
              "GHSA-x86f-5xw2-fm2r",
              "GO-2026-4883",
              "GO-2026-4887",
              "GO-2026-5617",
              "GO-2026-5668",
              "GO-2026-5746"
            ],
            "fixed_version": "29.3.1",
            "advisory_count": 10,
            "oldest_advisory_days": 117
          }
        ],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {
          "high": 1
        },
        "advisory_count": 10,
        "affected_count": 1,
        "assessed_count": 65,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 2,
        "direct_affected_count": 1
      },
      "ecosystems": [
        "go",
        "pypi"
      ],
      "dependencies": [
        {
          "name": "github.com/docker/docker",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v28.5.2+incompatible"
        },
        {
          "name": "github.com/gorilla/handlers",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.5.2"
        },
        {
          "name": "github.com/mitchellh/mapstructure",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.5.0"
        },
        {
          "name": "github.com/sirupsen/logrus",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.9.4"
        },
        {
          "name": "github.com/vishvananda/netlink",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v1.3.1"
        },
        {
          "name": "github.com/vishvananda/netns",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.0.5"
        },
        {
          "name": "golang.org/x/sys",
          "manifest": "go.mod",
          "ecosystem": "go",
          "version_constraint": "v0.46.0"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "github.com/docker/docker",
            "direct": true,
            "version": "v28.5.2+incompatible",
            "ecosystem": "go"
          },
          {
            "name": "github.com/gorilla/handlers",
            "direct": true,
            "version": "v1.5.2",
            "ecosystem": "go"
          },
          {
            "name": "github.com/mitchellh/mapstructure",
            "direct": true,
            "version": "v1.5.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/sirupsen/logrus",
            "direct": true,
            "version": "v1.9.4",
            "ecosystem": "go"
          },
          {
            "name": "github.com/vishvananda/netlink",
            "direct": true,
            "version": "v1.3.1",
            "ecosystem": "go"
          },
          {
            "name": "github.com/vishvananda/netns",
            "direct": true,
            "version": "v0.0.5",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/sys",
            "direct": true,
            "version": "v0.46.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/cespare/xxhash/v2",
            "direct": false,
            "version": "v2.3.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/containerd/errdefs",
            "direct": false,
            "version": "v1.0.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/containerd/errdefs/pkg",
            "direct": false,
            "version": "v0.3.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/containerd/log",
            "direct": false,
            "version": "v0.1.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/distribution/reference",
            "direct": false,
            "version": "v0.6.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/docker/go-connections",
            "direct": false,
            "version": "v0.7.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/docker/go-units",
            "direct": false,
            "version": "v0.5.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/felixge/httpsnoop",
            "direct": false,
            "version": "v1.0.4",
            "ecosystem": "go"
          },
          {
            "name": "github.com/go-logr/logr",
            "direct": false,
            "version": "v1.4.3",
            "ecosystem": "go"
          },
          {
            "name": "github.com/go-logr/stdr",
            "direct": false,
            "version": "v1.2.2",
            "ecosystem": "go"
          },
          {
            "name": "github.com/microsoft/go-winio",
            "direct": false,
            "version": "v0.6.2",
            "ecosystem": "go"
          },
          {
            "name": "github.com/moby/docker-image-spec",
            "direct": false,
            "version": "v1.3.1",
            "ecosystem": "go"
          },
          {
            "name": "github.com/moby/sys/atomicwriter",
            "direct": false,
            "version": "v0.1.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/moby/term",
            "direct": false,
            "version": "v0.5.2",
            "ecosystem": "go"
          },
          {
            "name": "github.com/morikuni/aec",
            "direct": false,
            "version": "v1.1.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/opencontainers/go-digest",
            "direct": false,
            "version": "v1.0.0",
            "ecosystem": "go"
          },
          {
            "name": "github.com/opencontainers/image-spec",
            "direct": false,
            "version": "v1.1.1",
            "ecosystem": "go"
          },
          {
            "name": "github.com/pkg/errors",
            "direct": false,
            "version": "v0.9.1",
            "ecosystem": "go"
          },
          {
            "name": "go.opentelemetry.io/auto/sdk",
            "direct": false,
            "version": "v1.2.1",
            "ecosystem": "go"
          },
          {
            "name": "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp",
            "direct": false,
            "version": "v0.68.0",
            "ecosystem": "go"
          },
          {
            "name": "go.opentelemetry.io/otel",
            "direct": false,
            "version": "v1.43.0",
            "ecosystem": "go"
          },
          {
            "name": "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp",
            "direct": false,
            "version": "v1.43.0",
            "ecosystem": "go"
          },
          {
            "name": "go.opentelemetry.io/otel/metric",
            "direct": false,
            "version": "v1.43.0",
            "ecosystem": "go"
          },
          {
            "name": "go.opentelemetry.io/otel/trace",
            "direct": false,
            "version": "v1.43.0",
            "ecosystem": "go"
          },
          {
            "name": "golang.org/x/time",
            "direct": false,
            "version": "v0.15.0",
            "ecosystem": "go"
          },
          {
            "name": "gotest.tools/v3",
            "direct": false,
            "version": "v3.5.2",
            "ecosystem": "go"
          },
          {
            "name": "babel",
            "direct": false,
            "version": "2.18.0",
            "ecosystem": "pypi"
          },
          {
            "name": "backrefs",
            "direct": false,
            "version": "7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "certifi",
            "direct": false,
            "version": "2026.5.20",
            "ecosystem": "pypi"
          },
          {
            "name": "charset-normalizer",
            "direct": false,
            "version": "3.4.7",
            "ecosystem": "pypi"
          },
          {
            "name": "click",
            "direct": false,
            "version": "8.4.1",
            "ecosystem": "pypi"
          },
          {
            "name": "colorama",
            "direct": false,
            "version": "0.4.6",
            "ecosystem": "pypi"
          },
          {
            "name": "docker-image-py",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "ghp-import",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "idna",
            "direct": false,
            "version": "3.18",
            "ecosystem": "pypi"
          },
          {
            "name": "jinja2",
            "direct": false,
            "version": "3.1.6",
            "ecosystem": "pypi"
          },
          {
            "name": "markdown",
            "direct": false,
            "version": "3.10.2",
            "ecosystem": "pypi"
          },
          {
            "name": "markupsafe",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "mergedeep",
            "direct": false,
            "version": "1.3.4",
            "ecosystem": "pypi"
          },
          {
            "name": "mike",
            "direct": false,
            "version": "2.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs",
            "direct": false,
            "version": "1.6.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs-get-deps",
            "direct": false,
            "version": "0.2.2",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs-material",
            "direct": false,
            "version": "9.7.6",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs-material-extensions",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "packaging",
            "direct": false,
            "version": "26.2",
            "ecosystem": "pypi"
          },
          {
            "name": "paginate",
            "direct": false,
            "version": "0.5.7",
            "ecosystem": "pypi"
          },
          {
            "name": "pathspec",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "platformdirs",
            "direct": false,
            "version": "4.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pygments",
            "direct": false,
            "version": "2.20.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pymdown-extensions",
            "direct": false,
            "version": "10.21.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pyparsing",
            "direct": false,
            "version": "3.3.2",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dateutil",
            "direct": false,
            "version": "2.9.0.post0",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dxf",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "pyyaml",
            "direct": false,
            "version": "6.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pyyaml-env-tag",
            "direct": false,
            "version": "1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "requests",
            "direct": false,
            "version": "2.34.2",
            "ecosystem": "pypi"
          },
          {
            "name": "six",
            "direct": false,
            "version": "1.17.0",
            "ecosystem": "pypi"
          },
          {
            "name": "urllib3",
            "direct": false,
            "version": "2.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "verspec",
            "direct": false,
            "version": "0.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "watchdog",
            "direct": false,
            "version": "6.0.0",
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 67,
        "direct_count": 7,
        "indirect_count": 60
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 5,
        "merged_prs": 147,
        "open_issues": 12,
        "closed_ratio": 0.928,
        "closed_issues": 155,
        "closed_unmerged_prs": 9
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "claymore666",
          "commits": 170,
          "avatar_url": "https://avatars.githubusercontent.com/u/11246284?v=4"
        },
        {
          "type": "User",
          "login": "devplayer0",
          "commits": 86,
          "avatar_url": "https://avatars.githubusercontent.com/u/1427254?v=4"
        },
        {
          "type": "User",
          "login": "200success",
          "commits": 1,
          "avatar_url": "https://avatars.githubusercontent.com/u/7194866?v=4"
        }
      ],
      "contributors_sampled": 3,
      "top_contributor_share": 0.661
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "apk-pin-check.yml",
        "codeql.yml",
        "coverage.yml",
        "dependency-review.yml",
        "integration-hosted.yml",
        "integration.yml",
        "pages.yml",
        "release.yml",
        "runner-image.yml",
        "scorecard.yml",
        "test.yaml",
        "trivy.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": 3,
            "reason": "branch protection is not maximal on development and all release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "28 out of 28 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": 5,
            "reason": "badge detected: Passing",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/25 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 3 contributing companies or organizations -- score normalized to 10",
            "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": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 10,
            "reason": "project is fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "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": 10,
            "reason": "all dependencies are pinned",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 10,
            "reason": "SAST tool is run on all commits",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 10,
            "reason": "security policy file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 8,
            "reason": "5 out of the last 5 releases have a total of 5 signed artifacts.",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 10,
            "reason": "GitHub workflow tokens follow principle of least privilege",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 5,
            "reason": "5 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "c2baff17ebabee144c0d182945c58a22ba84639e",
        "ran_at": "2026-07-22T19:24:55Z",
        "aggregate_score": 7.5,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": true,
      "has_security_policy": true,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-22T09:55:49Z",
      "oldest_open_prs": [
        {
          "number": 221,
          "created_at": "2026-06-14T17:53:11Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 325,
          "created_at": "2026-07-09T05:22:21Z",
          "last_comment_at": "2026-07-17T15:15:19Z",
          "last_comment_author": "claymore666"
        },
        {
          "number": 326,
          "created_at": "2026-07-12T23:04:55Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 327,
          "created_at": "2026-07-12T23:04:56Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 329,
          "created_at": "2026-07-19T23:06:05Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-06T00:50:36Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 110,
          "created_at": "2026-05-05T13:35:25Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 111,
          "created_at": "2026-05-05T13:35:25Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 125,
          "created_at": "2026-06-02T18:17:52Z",
          "last_comment_at": "2026-06-13T19:35:43Z",
          "last_comment_author": "claymore666"
        },
        {
          "number": 178,
          "created_at": "2026-06-13T20:01:35Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 214,
          "created_at": "2026-06-14T15:07:44Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 218,
          "created_at": "2026-06-14T15:28:35Z",
          "last_comment_at": "2026-06-14T23:10:39Z",
          "last_comment_author": "claymore666"
        },
        {
          "number": 219,
          "created_at": "2026-06-14T17:07:45Z",
          "last_comment_at": "2026-07-04T01:10:31Z",
          "last_comment_author": "claymore666"
        },
        {
          "number": 248,
          "created_at": "2026-06-15T14:40:16Z",
          "last_comment_at": "2026-07-04T21:54:43Z",
          "last_comment_author": "claymore666"
        },
        {
          "number": 275,
          "created_at": "2026-06-16T16:31:53Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 278,
          "created_at": "2026-06-16T17:23:38Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 279,
          "created_at": "2026-06-16T17:29:04Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 324,
          "created_at": "2026-07-06T00:51:20Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/claymore666/docker-net-dhcp",
    "host": "github.com",
    "name": "docker-net-dhcp",
    "owner": "claymore666"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 62,
      "inputs": {
        "security": 71,
        "vitality": 74,
        "community": 42,
        "governance": 51,
        "engineering": 71
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 74,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 58,
            "inputs": {
              "commits_last_year": 323,
              "human_commit_share": 0.97,
              "days_since_last_push": 2,
              "active_weeks_last_year": 5
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 2 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 2
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "5/52 weeks with commits",
                "points": 3.5,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 5
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "323 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 323
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 98,
            "inputs": {
              "releases_count": 28,
              "latest_release_tag": "v1.3.3",
              "releases_from_tags": false,
              "days_since_latest_release": 16,
              "mean_days_between_releases": 2.2
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "28 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 28
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 16 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 16
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~2.2 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 2.2
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "5 out of the last 5 releases have a total of 5 signed artifacts.",
                "points": 8,
                "status": "partial",
                "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": "at_risk",
        "name": "Community & Adoption",
        "value": 42,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 15,
            "inputs": {
              "forks": 1,
              "stars": 9,
              "watchers": 1,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "9 stars",
                "points": 14.6,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 9
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "1 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "1 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 72,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": true,
              "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": "recognized license (GPL-3.0)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "GPL-3.0"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 13.5,
                "status": "met",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 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": 51,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "at_risk",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 31,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 3,
              "top_contributor_share": 0.661
            },
            "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 66% of commits",
                "points": 7.6,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 66
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "3 contributors",
                "points": 4.1,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 3
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 3 contributing companies or organizations -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 79,
            "inputs": {
              "merged_prs": 147,
              "open_issues": 12,
              "closed_issues": 155,
              "issue_closed_ratio": 0.928,
              "closed_unmerged_prs": 9
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "93% of issues closed",
                "points": 43.4,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 93
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "147/156 decided PRs merged",
                "points": 36,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 147,
                      "decided": 156
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/25 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "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": 46,
            "inputs": {
              "followers": 4,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "claymore666",
              "public_repos": 23,
              "account_age_days": 4162
            },
            "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": "4 followers of claymore666",
                "points": 5,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 4,
                      "login": "claymore666"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "23 public repos, account ~11 yr old",
                "points": 22.1,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 23
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 11
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "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": "12 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 12
                    }
                  }
                ],
                "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": "28 out of 28 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": "good",
        "name": "Security",
        "value": 71,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "good",
            "name": "Security posture",
            "note": null,
            "notes": [],
            "value": 74,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 18,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 0,
              "scorecard_aggregate": 7.5
            },
            "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 is not maximal on development and all release branches",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "28 out of 28 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": "badge detected: Passing",
                "points": 1.2,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/25 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 3 contributing companies or organizations -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is fuzzed",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "all dependencies are pinned",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is run on all commits",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "5 out of the last 5 releases have a total of 5 signed artifacts.",
                "points": 6,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "GitHub workflow tokens follow principle of least privilege",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "5 existing vulnerabilities detected",
                "points": 3.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "moderate",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories. Remaining weights renormalized. Matched 65 resolved dependencies against OSV; 2 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "indirect_dependencies_free_of_known_advisories"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_repository",
                "params": {
                  "assessed": 65
                }
              },
              {
                "code": "advisories_unassessed",
                "params": {
                  "count": 2
                }
              },
              {
                "code": "advisories_repo_graph_caveat",
                "params": {}
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 58,
            "inputs": {
              "source": "osv",
              "advisories": 10,
              "affected_packages": 1,
              "assessed_packages": 65,
              "unassessed_packages": 2,
              "affected_by_severity": "high 1",
              "direct_affected_packages": 1
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "1 affected: github.com/docker/docker v28.5.2+incompatible (high 8.8)",
                "points": 10.4,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_affected",
                    "params": {
                      "count": 1,
                      "packages": "github.com/docker/docker v28.5.2+incompatible (high 8.8)"
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "transitive set not separable from development and test dependencies in this scope",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_scope_not_separable",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "1 advisory-carrying package(s) unaddressed past 90 days; oldest published 117 days ago",
                "points": 32.8,
                "status": "partial",
                "details": [
                  {
                    "code": "advisories_stale",
                    "params": {
                      "days": 90,
                      "count": 1,
                      "oldest": 117
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 65,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 5
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 69,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "97 of 97 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 97,
                      "sampled": 97
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "good",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 79,
            "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.03
            },
            "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": "3 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 3,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "all dependencies are pinned",
                "points": 10,
                "status": "met",
                "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": 41827,
              "source_files_sampled": 86,
              "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/86 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 86,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "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": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "go package 'github.com/devplayer0/docker-net-dhcp' points at a different repository (https://github.com/devplayer0/docker-net-dhcp); excluded from ecosystem scoring"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-22T19:25:12.467627Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/c/claymore666/docker-net-dhcp.svg",
  "full_name": "claymore666/docker-net-dhcp",
  "license_state": "standard",
  "license_spdx": "GPL-3.0"
}

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

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

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