Registro público
Informe de salud del softwareesquema 0.27.0 · métricas 1.13.0 · 2026-07-28 12:15 UTC

rmccann-hub / Platterpus

Bit-perfect CD → FLAC ripping via the cyanrip backend

PythonGPL-3.0★ 0 estrellas⑂ 0 forksdesde may 2026Ver en GitHub ↗

rmccann-hub/Platterpus tiene un índice de salud de 61 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Vitality (80/100) y la más baja, Community & Adoption (33/100). Se actualizó por última vez hoy. Una sola persona concentra la mayor parte del trabajo reciente.

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

61
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

rmccann-hubCuenta personal
1 seguidor2 repositorios públicosdesde dic 2025

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ónEtiquetas
PyPIplatterpus0.5.12437934hace 0 díasaudiocdripflacwavpackmp3musicbrainzaccurateripwhippercyanripqt

Métricas por categoría

Vitalidad

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

80Bueno · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 0 días
6.2/36Cadencia de commits — 9/52 semanas con commits
18/18Volumen de commits — 493 commits en el último año
0/10OpenSSF Scorecard: Maintained — sin datos
Datos de entrada utilizados
commits_last_year493
human_commit_share0,93
days_since_last_push0
active_weeks_last_year9
Cómo se puntúa
27/27Publica versiones — 55 versiones publicadas
36/36Recencia de las versiones — última versión hace 0 días
27/27Cadencia de publicación — una versión cada ~0,7 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count55
latest_release_tagv0.5.13
releases_from_tagsno
days_since_latest_release0
mean_days_between_releases0,7

Comunidad y Adopción

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

33En riesgo · 18% del índice global
Cómo se puntúa
0/60Estrellas — 0 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars0
watchers0
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
0/13.5Código de conducta
0/7.2Plantilla de issues
0/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
has_contributingno
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno
Cómo se puntúa
48.6/80Descargas mensuales — 4379 descargas/mes en pypi
0/20Dependientes en el registro — no lo informa este ecosistema
Datos de entrada utilizados
packagesplatterpus
dependents
ecosystemspypi
total_downloads
monthly_downloads4379
Excluidos de la puntuación (sin datos o no aplicable): Dependientes en el registro. Los pesos restantes se han renormalizado.

Sostenibilidad y Gobernanza

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

55Moderado · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
4.2/22.5Distribución de commits — el principal contribuyente firma el 81% de los commits
2.7/13.5Amplitud de contribuyentes — 2 contribuyentes
0/10OpenSSF Scorecard: Contributors — sin datos
Datos de entrada utilizados
bus_factor1
contributors_sampled2
top_contributor_share0,814
Cómo se puntúa
0/46.8Resolución de issues — sin issues o sin datos
36.8/38.3Aceptación de PR — 98/102 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — sin datos
Datos de entrada utilizados
merged_prs98
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs4
Excluidos de la puntuación (sin datos o no aplicable): Resolución de issues. Los pesos restantes se han renormalizado.
Cómo se puntúa
10/30Respaldo de la propiedad — cuenta personal (usuario)
0/20Dominio verificado — no aplicable a cuentas de usuario
2.2/25Alcance del propietario — 1 seguidores de rmccann-hub
4.8/25Trayectoria — 2 repos públicos, cuenta de ~0 años
Datos de entrada utilizados
followers1
owner_typeUser
is_verified
owner_loginrmccann-hub
public_repos2
account_age_days235
Excluidos de la puntuación (sin datos o no aplicable): Dominio verificado. Los pesos restantes se han renormalizado.
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en pypi
35/35Recencia de publicación — última publicación hace 0 días
20/20Historial de versiones — 34 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packagesplatterpus
ecosystemspypi
any_deprecatedno
min_days_since_publish0

Calidad de Ingeniería

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

62Moderado · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 5 flujo(s) de trabajo
24/24Pruebas presentes
0/16Configuración de linter
0/9.6Hooks de pre-commit
0/6.4.editorconfig
0/20OpenSSF Scorecard: CI-Tests — sin datos
Datos de entrada utilizados
has_ci
has_tests
has_editorconfigno
has_linter_configno
has_precommit_configno

Documentación

65Moderado
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
0/10Wiki
Datos de entrada utilizados
topics
has_wikino
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?

73Bueno · 16% del índice global
Cómo se puntúa
30/30Política de seguridad (SECURITY.md)
25/25Configuración de Dependabot
0/25Lockfiles de dependencias — biblioteca publicada — los lockfiles son cosa de las aplicaciones, no se esperan aquí
0/20Flujo de trabajo de CodeQL
Datos de entrada utilizados
sourcefile_signals
lockfiles
manifestspyproject.toml
has_codeql_workflowno
has_security_policy
has_dependabot_config
Excluidos de la puntuación (sin datos o no aplicable): Lockfiles de dependencias. Los pesos restantes se han renormalizado.

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.

60Moderado · 0% del índice global
Cómo se puntúa
45/45Instrucciones para agentes — CLAUDE.md
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 93 de 93 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share1
agent_instruction_filesCLAUDE.md
agent_instruction_max_bytes30.877
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
0/11Configuración de lint / formato
0/11Verificación estática de tipos
0/10Entorno reproducible
10/10Práctica demostrada con agentes — 77 de los últimos 100 commits con autoría o crédito de agente
8/8Mantenimiento automatizado — 7 de los últimos 100 commits son actualizaciones automáticas de dependencias
0/10OpenSSF Scorecard: Pinned-Dependencies — sin datos
Datos de entrada utilizados
has_nixno
has_tests
lockfiles
has_dockerfileno
typed_languageno
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0,77
toolchain_manifests
dependency_bot_commit_share0,07
Cómo se puntúa
0/45Código verificable por tipos — Python sin configuración de verificación de tipos
54.1/55Tamaños de archivo manejables — 4/239 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languagePython
largest_source_bytes199.184
source_files_sampled239
oversized_source_files4

Datos clave

0estrellas de GitHub
2contribuidores
493commits en los últimos 12 meses
0días desde el último push
55versiones publicadas
1factor bus
0issues abiertas
PyPIecosistemas de paquetes

Advertencias de recopilación de datos

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository
  • deps.dev does not index pypi:platterpus@0.5.12; advisories assessed against the repository dependency graph instead
  • OpenSSF Scorecard did not return a usable result (2026/07/28 12:15:15 Warning: PATs stored in env variables GITHUB_AUTH_TOKEN and GITHUB_TOKEN differ. Scorecard will use the former.); skipping Scorecard checks

Más detalle

Dependencias directas 4
RegistroPaqueteRestricción de versiónManifiesto
PyPIPySide6>=6.7,<7pyproject.toml
PyPImusicbrainzngs==0.7.1pyproject.toml
PyPItomli-w>=1.0,<2pyproject.toml
PyPIcryptography>=48.0.1,<50pyproject.toml
Todas las dependencias no recopilado

No fue posible recopilar el conjunto de dependencias resuelto para este informe: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 5277,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "C": 5588,
        "Shell": 72261,
        "Python": 2815651
      },
      "pushed_at": "2026-07-28T12:13:42Z",
      "created_at": "2026-05-28T01:59:43Z",
      "owner_type": "User",
      "updated_at": "2026-07-28T12:13:15Z",
      "description": "Bit-perfect CD → FLAC ripping via the cyanrip backend",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "GPL-3.0",
      "default_branch": "main",
      "license_spdx_raw": "GPL-3.0",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": null,
      "name": null,
      "type": "User",
      "login": "rmccann-hub",
      "company": null,
      "location": null,
      "followers": 1,
      "avatar_url": "https://avatars.githubusercontent.com/u/247853511?v=4",
      "created_at": "2025-12-04T17:48:36Z",
      "is_verified": null,
      "public_repos": 2,
      "account_age_days": 235
    },
    "license": {
      "state": "standard",
      "spdx_id": "GPL-3.0",
      "raw_spdx": "GPL-3.0",
      "file_present": true,
      "scorecard_found": null,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.5.13",
          "kind": "patch",
          "published_at": "2026-07-28T12:13:42Z"
        },
        {
          "tag": "v0.5.12",
          "kind": "patch",
          "published_at": "2026-07-28T03:18:23Z"
        },
        {
          "tag": "v0.5.11",
          "kind": "patch",
          "published_at": "2026-07-27T22:41:39Z"
        },
        {
          "tag": "v0.5.10",
          "kind": "patch",
          "published_at": "2026-07-26T22:35:44Z"
        },
        {
          "tag": "v0.5.9",
          "kind": "patch",
          "published_at": "2026-07-26T20:03:53Z"
        },
        {
          "tag": "v0.5.8",
          "kind": "patch",
          "published_at": "2026-07-24T18:20:36Z"
        },
        {
          "tag": "v0.5.7",
          "kind": "patch",
          "published_at": "2026-07-24T15:46:16Z"
        },
        {
          "tag": "v0.5.6",
          "kind": "patch",
          "published_at": "2026-07-22T13:20:11Z"
        },
        {
          "tag": "v0.5.5",
          "kind": "patch",
          "published_at": "2026-07-21T22:13:44Z"
        },
        {
          "tag": "v0.5.0",
          "kind": "minor",
          "published_at": "2026-07-21T19:23:51Z"
        },
        {
          "tag": "v0.4.24",
          "kind": "patch",
          "published_at": "2026-07-09T21:02:34Z"
        },
        {
          "tag": "v0.4.23",
          "kind": "patch",
          "published_at": "2026-07-08T17:08:26Z"
        },
        {
          "tag": "v0.4.22",
          "kind": "patch",
          "published_at": "2026-07-08T02:23:16Z"
        },
        {
          "tag": "v0.4.21",
          "kind": "patch",
          "published_at": "2026-07-08T01:04:32Z"
        },
        {
          "tag": "v0.4.20",
          "kind": "patch",
          "published_at": "2026-07-07T23:56:03Z"
        },
        {
          "tag": "v0.4.19",
          "kind": "patch",
          "published_at": "2026-07-07T07:37:25Z"
        },
        {
          "tag": "v0.4.18",
          "kind": "patch",
          "published_at": "2026-07-07T04:15:04Z"
        },
        {
          "tag": "v0.4.17",
          "kind": "patch",
          "published_at": "2026-07-07T01:29:38Z"
        },
        {
          "tag": "v0.4.16",
          "kind": "patch",
          "published_at": "2026-07-07T00:03:16Z"
        },
        {
          "tag": "v0.4.15",
          "kind": "patch",
          "published_at": "2026-07-06T13:48:02Z"
        },
        {
          "tag": "v0.4.14",
          "kind": "patch",
          "published_at": "2026-07-05T23:53:09Z"
        },
        {
          "tag": "v0.4.13",
          "kind": "patch",
          "published_at": "2026-07-05T22:27:16Z"
        },
        {
          "tag": "v0.4.12",
          "kind": "patch",
          "published_at": "2026-07-05T21:06:01Z"
        },
        {
          "tag": "v0.4.11",
          "kind": "patch",
          "published_at": "2026-07-05T19:12:59Z"
        },
        {
          "tag": "v0.4.10",
          "kind": "patch",
          "published_at": "2026-07-03T13:04:38Z"
        },
        {
          "tag": "v0.4.9",
          "kind": "patch",
          "published_at": "2026-07-03T00:02:34Z"
        },
        {
          "tag": "v0.4.8",
          "kind": "patch",
          "published_at": "2026-07-01T15:39:37Z"
        },
        {
          "tag": "v0.4.7",
          "kind": "patch",
          "published_at": "2026-07-01T11:58:30Z"
        },
        {
          "tag": "v0.4.6",
          "kind": "patch",
          "published_at": "2026-07-01T04:16:13Z"
        },
        {
          "tag": "v0.4.5",
          "kind": "patch",
          "published_at": "2026-07-01T01:47:58Z"
        },
        {
          "tag": "v0.4.4",
          "kind": "patch",
          "published_at": "2026-06-30T05:09:58Z"
        },
        {
          "tag": "v0.4.2",
          "kind": "patch",
          "published_at": "2026-06-30T03:01:50Z"
        },
        {
          "tag": "v0.4.1",
          "kind": "patch",
          "published_at": "2026-06-30T02:24:15Z"
        },
        {
          "tag": "v0.4.1a1",
          "kind": "other",
          "published_at": "2026-06-29T22:36:39Z"
        },
        {
          "tag": "v0.4.0",
          "kind": "minor",
          "published_at": "2026-06-29T19:27:53Z"
        },
        {
          "tag": "v0.3.10",
          "kind": "patch",
          "published_at": "2026-06-27T15:32:46Z"
        },
        {
          "tag": "v0.3.9",
          "kind": "patch",
          "published_at": "2026-06-27T15:18:08Z"
        },
        {
          "tag": "v0.3.8",
          "kind": "patch",
          "published_at": "2026-06-27T14:11:19Z"
        },
        {
          "tag": "v0.3.7",
          "kind": "patch",
          "published_at": "2026-06-27T13:52:14Z"
        },
        {
          "tag": "v0.3.6",
          "kind": "patch",
          "published_at": "2026-06-27T13:43:04Z"
        },
        {
          "tag": "v0.3.5",
          "kind": "patch",
          "published_at": "2026-06-27T13:24:38Z"
        },
        {
          "tag": "v0.3.4",
          "kind": "patch",
          "published_at": "2026-06-27T12:44:12Z"
        },
        {
          "tag": "v0.3.3",
          "kind": "patch",
          "published_at": "2026-06-27T12:32:45Z"
        },
        {
          "tag": "v0.3.2",
          "kind": "patch",
          "published_at": "2026-06-27T12:07:07Z"
        },
        {
          "tag": "v0.3.1",
          "kind": "patch",
          "published_at": "2026-06-26T23:00:56Z"
        },
        {
          "tag": "v0.3.0",
          "kind": "minor",
          "published_at": "2026-06-26T20:07:46Z"
        },
        {
          "tag": "v0.2.8",
          "kind": "patch",
          "published_at": "2026-06-18T14:29:20Z"
        },
        {
          "tag": "v0.2.7",
          "kind": "patch",
          "published_at": "2026-06-18T05:02:23Z"
        },
        {
          "tag": "v0.2.6",
          "kind": "patch",
          "published_at": "2026-06-17T13:49:19Z"
        },
        {
          "tag": "v0.2.5",
          "kind": "patch",
          "published_at": "2026-06-13T13:12:33Z"
        },
        {
          "tag": "v0.2.4",
          "kind": "patch",
          "published_at": "2026-06-13T01:25:51Z"
        },
        {
          "tag": "v0.2.3",
          "kind": "patch",
          "published_at": "2026-06-11T22:30:17Z"
        },
        {
          "tag": "v0.2.2",
          "kind": "patch",
          "published_at": "2026-06-11T21:56:39Z"
        },
        {
          "tag": "v0.2.1",
          "kind": "patch",
          "published_at": "2026-06-10T22:14:10Z"
        },
        {
          "tag": "v0.1.0",
          "kind": "minor",
          "published_at": "2026-06-01T20:46:56Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "34eef5083f8191557b21a479ed88cd5873227357",
          "body": "Every completed rip raised AttributeError inside `_ensure_tray_icon`, swallowed\nbecause notifications are best-effort — so the desktop notification silently\nnever fired for anyone with the setting enabled.\n\nv0.5.12 replaced `getattr(self, \"_tray_icon\", None)` with a plain attribute read\nto satisfy m\n[…]\ne's. Track 3 is\nno longer a problem child. Test A4 is retired as passed; A1 stays, marked not\nexercised, since nothing failed to converge.\n\n2,061 tests green, branch coverage 93%, ruff and mypy clean.",
          "is_bot": false,
          "headline": "release: v0.5.13 — the rip-complete notification actually fires (#102)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-28T12:11:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4721f3cc2570c1bbde667487226f83d2751c5b87",
          "body": "The suite could segfault at any point and had been able to for most of the\nproject's life: unmodified `main` died with SIGSEGV on 5 runs out of 5.\n\nThe detector came first, deliberately. `tests/test_qt_teardown_fitness.py`\nforces a full all-generations collection every run and asserts no worker thre\n[…]\n leaking a 120-second `compute_digests` over a deleted\ntmp_path — was corrected.\n\nVerified: 0 crashes in 10 randomized runs, 0 in 8 under --cov. Test\ninfrastructure only; no shipped code path changes.",
          "is_bot": false,
          "headline": "test: stop the cyclic collector from running on a worker thread (#101)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-28T04:58:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4a074919e884e81b8c79e9a162e5c1e2927280ad",
          "body": "Two batches in one release. The EAC-layout work was prepared as v0.5.12 and\nnever tagged; the audit that followed landed on top of it, so both ship\ntogether rather than leaving a phantom version behind.\n\nEAC layout parity, measured against a genuine EAC V1.8 log of the same disc on\nthe same drive: t\n[…]\nof ~11,759 valid alignments); mypy can no longer silently lose sight\nof PySide6; and a failing test run prints which test failed again.\n\nVerified: 2056 tests, 93% branch coverage, ruff and mypy clean.",
          "is_bot": false,
          "headline": "release: v0.5.12 — EAC-log parity + whole-application audit (#100)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-28T03:16:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8364a3ff5a2a3579aae9fa9cd5d844e11e6461c1",
          "body": "…IPE race (#99)\n\n* fix(cache,eac-log): six defects found by the first v0.5.8 hardware run\n\nThe maintainer ran the released v0.5.8 on the Bazzite + BDR-209D rig.\nThree gates closed and six defects found — all fixed here. The verdict\nlogic was right all along; what was wrong was a guessed timeout and \n[…]\nrt-circuiting.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DQSpvvuwnQzxc5NKFjFyx3\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(test-plan): trim the run sheet; fix the CI changelog gate's SIGP…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-27T22:58:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f0879dc6534a95ba2347b5b77f6fd72a5da80656",
          "body": "* fix(cache,eac-log): six defects found by the first v0.5.8 hardware run\n\nThe maintainer ran the released v0.5.8 on the Bazzite + BDR-209D rig.\nThree gates closed and six defects found — all fixed here. The verdict\nlogic was right all along; what was wrong was a guessed timeout and a\nset of surfaces\n[…]\n is not a fix.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DQSpvvuwnQzxc5NKFjFyx3\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.5.11 — a swapped-in re-rip's CRC named the wrong bytes (#98)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-27T22:39:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c5e7f38d492ef07d82786daf37e05a91420cc072",
          "body": "* fix(cache,eac-log): six defects found by the first v0.5.8 hardware run\n\nThe maintainer ran the released v0.5.8 on the Bazzite + BDR-209D rig.\nThree gates closed and six defects found — all fixed here. The verdict\nlogic was right all along; what was wrong was a guessed timeout and a\nset of surfaces\n[…]\ned final part.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DQSpvvuwnQzxc5NKFjFyx3\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.5.10 — the second hardware run's two honesty fixes (#97)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-26T22:33:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a6c9512da9e8c599846bc89385f57f0909450dd3",
          "body": "…nd (#96)\n\nEvery fix here came out of one real-hardware run of v0.5.8 on the Bazzite +\nBDR-209D rig. Three gates closed (log checksum verified end-to-end, the\nwizard's cd-paranoia provides-install worked on real Fedora, and the\ncd-paranoia -A output was captured as a fixture), and eight defects foun\n[…]\nbove the checksum, so\n  it is covered by it and cannot be stripped silently.\n\n13 regression tests, each naming the hardware finding it guards. Suite\n1960 green, ruff + mypy clean, coverage floor held.",
          "is_bot": false,
          "headline": "release: v0.5.9 — the eight defects the first v0.5.8 hardware run fou…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-26T20:01:57Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "95cf0b50df28a768d41ffe9de1edfad23cf61e61",
          "body": "…gor (#95)\n\nCloses the four remaining Exact Audio Copy gaps, each with equal-or-stronger\nrigor than EAC and honestly labelled as Platterpus's own — never forged:\n\n- Openly-verifiable SHA-256 log checksum, checkable with sha256sum and no\n  secret key, never EAC's own marker (KDD-28).\n- Measured cache\n[…]\nst). Adds cd-paranoia as an optional dependency installed by the\nwizard as a non-blocking final step. Documentation sweep corrects a stale\nREADME claim that cache-defeat was \"attempted, not measured\".",
          "is_bot": false,
          "headline": "release: v0.5.8 — EAC parity closed with honest, equal-or-stronger ri…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-24T18:18:32Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "34ed7b54f5ea336ca29c5f7427986011afc40ccd",
          "body": "The v0.5.7 release build aborted: python-appimage, given no\n--python-version, downloaded the newest CPython base image — which had\nbecome a 3.15 beta that no PySide6 wheel supports, so the recipe's\n`PySide6~=6.7` install failed with \"No matching distribution found\".\n\nPin the bundled interpreter to a\n[…]\n; the bullet goes\nunder the [0.5.7] Fixed section (the release never shipped).\n\n\nClaude-Session: https://claude.ai/code/session_01DQSpvvuwnQzxc5NKFjFyx3\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(build): pin bundled CPython version (unblock v0.5.7 release) (#94)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-24T15:43:59Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7e39ac28d1aba50a05887f950bcc5d200796d0db",
          "body": "…ant re-read (#93)\n\nBump __version__ to 0.5.7, roll the CHANGELOG [Unreleased] entries under\nthe [0.5.7] heading with its compare link, and restamp the docs edited\nthis cycle (CHANGELOG, PLANNING, session-log) to v0.5.7.\n\nThis release ships: per-track \"Rip?\" selection (checkbox column +\nright-click)\n[…]\nd the opt-in\n\"re-read offset-variant tracks\" reproducibility setting (KDD-27).\n\n\nClaude-Session: https://claude.ai/code/session_01DQSpvvuwnQzxc5NKFjFyx3\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.5.7 — per-track selection, Settings tooltips, offset-vari…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-24T15:17:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "50d55c59728e001e40add2d29313e9ce150c4cdf",
          "body": "… re-read (#92)\n\n* feat(ui): per-track Rip? selection + complete, enforced Settings tooltips\n\nTwo maintainer-requested features from the v0.5.6 hardware session.\n\nPer-track selection: the track table gains a leading \"Rip?\" checkbox\ncolumn (all ticked by default) and a right-click menu on highlighted\n[…]\n+\nmypy clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DQSpvvuwnQzxc5NKFjFyx3\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(ui): per-track Rip? selection, Settings tooltips, offset-variant…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-24T14:10:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4877acef210fd7453d59bcd6d185782ff02d9c47",
          "body": "Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6.3.0 to 7.0.0.\n- [Release notes](https://github.com/actions/setup-python/releases)\n- [Commits](https://github.com/actions/setup-python/compare/ece7cb06caefa5fff74198d8649806c4678c61a1...5fda3b95a4ea91299a34e894583c3862153e4b\n[…]\nirect:production\n  update-type: version-update:semver-major\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 actions/setup-python from 6.3.0 to 7.0.0 (#91)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-24T14:10:24Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "81e750a379074b4af20a01610f9f1ce32b22c6c4",
          "body": "Bumps [actions/checkout](https://github.com/actions/checkout) from 7.0.0 to 7.0.1.\n- [Release notes](https://github.com/actions/checkout/releases)\n- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb9\n[…]\nirect:production\n  update-type: version-update:semver-patch\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 actions/checkout from 7.0.0 to 7.0.1 (#90)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-24T13:59:06Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ba1debb07a1ac5d34560cc40438add088a465218",
          "body": "…#89)\n\nBumps [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) from 1.14.0 to 1.14.1.\n- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)\n- [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/cef221092ed1bacb1cc03d23a2d87d1d172e277b...b\n[…]\nirect:production\n  update-type: version-update:semver-patch\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 pypa/gh-action-pypi-publish from 1.14.0 to 1.14.1 (…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-24T13:58:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0cd01128dff1ec4f0344c0985b596c968b0b4619",
          "body": "…r, guide currency (#88)\n\nReal-hardware fixes and polish from a v0.5.5 BDR-209D session, plus v0.5.6 release prep.\n\n- Freeze recovery: real-time logs + access buttons during a rip, GUI-thread stall/liveness watchdog, Open-rip-folder after cancel/partial.\n- Drive identity (make/model/firmware) in the disc panel; removed the duplicate per-track progress bar; in-app User Guide gaps filled with enforced currency.\n- __version__ 0.5.6, CHANGELOG rollover, doc restamps.",
          "is_bot": false,
          "headline": "release: v0.5.6 — freeze recovery, drive identity, single progress ba…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-22T13:17:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4654b2fad346a66c60d63b6f222e79c1bb98e93b",
          "body": "…nob, cue button (#87)\n\nv0.5.5 — everything since the v0.5.0 merge.\n\nSecurity:\n- Ed25519/minisign release-signature verification in the in-app updater,\n  fail-closed, ships dormant until an offline maintainer key is baked into\n  PUBLIC_KEY_B64. Adds cryptography (floored at 48.0.1 for GHSA-537c-gmf6\n[…]\nlogged;\n  stale whipper-era rows closed; upstream checklist re-verified.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DQSpvvuwnQzxc5NKFjFyx3",
          "is_bot": false,
          "headline": "release: v0.5.5 — release signing, reproducible-build plumbing, MP3 k…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-21T22:11:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c0bc945bd5245f1a3c9f07f23e600f75828bd494",
          "body": "…rs, cross-FS warning (#86)\n\nFeature batch merged ahead of the v0.5.0 release:\n\n- opt-in cyanrip overread toggle (-O) in Settings, with docs corrected\n  from the nonexistent -x flag and a regression test pinning the argv\n- automatic move of finished rips into a configurable library folder,\n  settled\n[…]\nlready delivered\n- version bumped to 0.5.0 and CHANGELOG cut for release\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DQSpvvuwnQzxc5NKFjFyx3",
          "is_bot": false,
          "headline": "feat: v0.5.0 batch — overread toggle, library auto-move, per-track ba…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-21T19:21:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "aa5de07005332ce3b45d4ad034b46d00fb8ac7f6",
          "body": "…ers (#85)\n\nExecutes the two approved 2026-07-21 work items: (1) the docs-audit\nconsolidation plan's remaining sub-items — START-HERE re-ranked around\nopen work (2026-06-09 list preserved as ranked history, numbering\nintact), UX gap backlog single-homed, four single-home cleanups, the\nmanual CUETool\n[…]\n seams. Suite\n1798 green (+32 a11y regression tests); ruff + mypy clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01DQSpvvuwnQzxc5NKFjFyx3",
          "is_bot": false,
          "headline": "feat(a11y): accessibility gap #4 complete + docs-consolidation leftov…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-21T18:29:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1468a9bdd34e6cb298329ce3f106d53c32095199",
          "body": "…tainer rulings (#84)\n\n239-finding audit of every Markdown file against the code, CI, and tag\nhistory; ~160 easy-tier fixes; maintainer-approved consolidation (dated\naudits archived, cyanrip cluster deduped, test-plan rewritten for\ncyanrip-only with new Tests 12-14, CLAUDE.md companion list slimmed)\n[…]\n0 section\nrestored from the tag). Full record: docs/audit-2026-07-21.md.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01QuT1CkgCBw6EsT7RQtCKce",
          "is_bot": false,
          "headline": "docs: full documentation audit — corrections, consolidation, and main…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-21T15:44:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8b103f32bbc2416705e97eb16e9339fea315ef4a",
          "body": "…age now strict (#83)\n\nBring the last six modules (the MainWindow god-object + its five mixins)\ninto the strict mypy gate via a new type-only seam,\nui/main_window_shared.py::MainWindowShared. disallow_untyped_defs now\ncovers the entire package with no ignore_errors exclusions left.\n\nRuntime-neutral \n[…]\n by three independent adversarial reviewers (no bugs, all\ncross-mixin stubs match, retypes truthful). Docs updated (TASKS,\nsession-log, architecture.md 3.6, pyproject mypy comments).\n\n[skip changelog]",
          "is_bot": false,
          "headline": "build(mypy): type the MainWindow mixins via a shared seam; whole pack…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-20T03:14:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "103a2ad63dea154e3f3e6fa0c3fd50871f6a6921",
          "body": "Narrow the mypy ignore_errors override from all of platterpus.ui.* to\njust the six main_window* god-object modules, so the ~14 standalone UI\nwidget/dialog modules are now type-checked at strict def-typing. Fixes\nthe 8 residual errors there (track_table Qt-override LSP signatures\nwidened via an _Inde\n[…]\ntings_dialog; a\nmissing build_teardown annotation in uninstall_dialog). The UI layer is\nno longer a total type-checking blind spot.\n\n[skip changelog] — a contributor/CI-facing change, not user-facing.",
          "is_bot": false,
          "headline": "build(mypy): bring the standalone UI modules into the strict gate (#82)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-10T23:46:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ce631a8ad72da015544b0e9caf4757d12dc5216c",
          "body": "Tighten the mypy gate from the non-strict v0.4.22 baseline to enforce\ndisallow_untyped_defs + disallow_incomplete_defs across the whole package\nexcept the Qt UI mixin layer (platterpus.ui.*). Zero-code-change config\ntighten — every non-UI package already carried full annotations, so it\nconverts the \n[…]\nd.\n\nAlso corrects a stale TASKS note: the config-file input surface is\nalready validated at load via config.load() -> _sanitized().\n\n[skip changelog] — a contributor/CI-facing change, not user-facing.",
          "is_bot": false,
          "headline": "build(mypy): enforce disallow_untyped_defs outside the ui layer (#81)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-10T23:33:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "96f8112edd6f2a6dd500bfe3ecd3056ae68865f1",
          "body": "…r + PR artifacts (#80)\n\n* feat(compare): re-rip comparison, best-of assembler, read-effort + AR/CTDB honesty\n\nAdds a re-rip comparison subsystem so Platterpus can catch a track that\nsilently changed across two rips of the same disc — the gap a stateless\nper-rip tool otherwise can't see. Found while\n[…]\np changelog]\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(cyanrip): upstream contribution kit — verified colon-fix patche…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-09T22:09:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "edb31e605f05375f025c222e3df05e1aeaf677e3",
          "body": "* feat(compare): re-rip comparison, best-of assembler, read-effort + AR/CTDB honesty\n\nAdds a re-rip comparison subsystem so Platterpus can catch a track that\nsilently changed across two rips of the same disc — the gap a stateless\nper-rip tool otherwise can't see. Found while auditing a v0.4.23 re-ri\n[…]\n schema v9).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.4.24 — re-rip comparison + trust improvements (#79)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-09T21:00:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "35e41b7d3690d4b51f1588a79df6204f4fd857b9",
          "body": "… (#78)\n\nAdds docs/cyanrip-soft-fork-verify-meta-colon.c: transcribes append_missing_keys\n1:1 (av_* -> libc) for the current and fixed forms and asserts all four cases\n(the bug, positional shorthand, explicit multi-key, and the escaped \\:). Built\nand run clean under -fsanitize=address,undefined; the\n[…]\nopen the upstream PR (real build +\nsmoke rip still gate it).\n\n[skip changelog]\n\n\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(cyanrip): prove the colon fix with an ASan/UBSan-clean C harness…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T23:57:40Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e99b531604f295197a2cbb96837b46f9e0f5319c",
          "body": "…r-args PRs (#77)\n\nAdds docs/cyanrip-soft-fork.md: the soft-fork model (rmccann-hub/cyanrip =\nupstream master + rebased patch set, PR-back, drop once merged), re-merge\ndiscipline, container build/consume, and two prepared contributions grounded\nin cyanrip's verbatim source — the -a/-t colon-parsing \n[…]\nel etc.) — each with issue text.\nIndexed in docs/README; TASKS updated.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "docs(cyanrip): soft-fork runbook + prepared colon-fix and FLAC-encode…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T22:16:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "528946f322c9541ead47eb093c3814805fbfa957",
          "body": "…aster live (#76)\n\nResolves the §6 research task: cyanrip master is active (last commit\n2026-03-25) while releases are ~2yr stale; maintainer merges external PRs\nslowly. Conclusion: no fork needed for slow releases — we build from any\ncommit in the ripping container; soft-fork only if a PR is declined/stalls.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "docs(strategy): record cyanrip activity finding — releases stalled, m…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T22:05:48Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7b74c3be8652eb56eec818b29f058fb6d758687f",
          "body": "…cyanrip PRs (#75)\n\nTracker maintenance after v0.4.23: close the shipped cyanrip FLAC\nencode-verify (adapters/flac_verify.py) and PyPI-publish items, prune the\nstale whipper drive-analyze/offset-find doc entry, and add a \"cyanrip upstream\ncontributions\" subsection scoping the help-them-and-us PRs (l\n[…]\n the\nconfirmed append_missing_keys colon-parsing bug). Stamp → v0.4.23.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "docs(tasks): close shipped items, prune stale whipper entries, scope …",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T19:14:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0d3a9f27a9627744c2fd1c55b1aec7eef40f50a1",
          "body": "The changelog gate was a guaranteed false-positive on every Dependabot PR.\nSkip it when the actor is dependabot[bot], the head branch is dependabot/*,\nor the pushed merge commit's author is dependabot[bot] (preserved by squash).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "ci: exempt Dependabot dependency bumps from the CHANGELOG gate (#74)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T17:30:06Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d6a8bc7a21bafb2cf2dedc180d20003ca3aac632",
          "body": "Applies Dependabot #69 directly (it conflicted after the checkout bump #68).\nsetup-python → SHA ece7cb06… (# v6.3.0) across all six workflow files.\nSupersedes #69.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "ci(deps): bump actions/setup-python 5 → 6.3.0 (pinned SHA) (#73)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T17:21:17Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f1d8311420ae3ce5f78b0876b56a3a99b3ac8a18",
          "body": "…(#70)\n\nUpdates the requirements on [mypy](https://github.com/python/mypy) to permit the latest version.\n- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)\n- [Commits](https://github.com/python/mypy/compare/v1.13.0...v2.2.0)\n\n---\nupdated-dependencies:\n- dependency-name: mypy\n  de\n[…]\nndency-version: 2.2.0\n  dependency-type: direct:development\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-dev): update mypy requirement from <2,>=1.13 to >=1.13,<3 …",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-08T17:15:48Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cf05119b19019e774a2ed87c7116a569b4fdf598",
          "body": "Bumps [actions/checkout](https://github.com/actions/checkout) from 4.3.1 to 7.0.0.\n- [Release notes](https://github.com/actions/checkout/releases)\n- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/actions/checkout/compare/34e114876b0b11c390a5638\n[…]\nirect:production\n  update-type: version-update:semver-major\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 actions/checkout from 4.3.1 to 7.0.0 (#68)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-08T17:15:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4439479160512356fb0492827810a89d22f6c796",
          "body": "Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 7.0.1.\n- [Release notes](https://github.com/actions/upload-artifact/releases)\n- [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...043fb46d1a93c77aae656e7c1c\n[…]\nirect:production\n  update-type: version-update:semver-major\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 actions/upload-artifact from 4.6.2 to 7.0.1 (#67)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-08T17:15:18Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "bdcc1a30d01fddd441712585a0bcf7123323d826",
          "body": "Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 78e6cbd37d0ac1a40113c04f2037dacf1ea3f12e to 0f67c3f4856b2e3261c31976d6725780e5e4c373.\n- [Release notes](https://github.com/actions/attest-build-provenance/releases)\n- [Changelog](https://github.com/actio\n[…]\nc31976d6725780e5e4c373\n  dependency-type: direct:production\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 actions/attest-build-provenance (#66)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-07-08T17:15:04Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6b46c7643e4a216d3af2d4e0a0c18d475b8d19ad",
          "body": "…chain (#72)\n\nBump __version__ to 0.4.23 and roll the CHANGELOG [Unreleased] entries under\nthe dated heading. Gathers the 2026-07-08 trust-audit follow-ups (#60-#65,\n#71): trust-claim honesty sweep, known-disc overwrite confirm, mypy in CI,\nbuild-provenance attestation, SHA-pinned actions, pip-audit, mutmut, and\nSOURCE_DATE_EPOCH reproducible-build timestamps.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "release: v0.4.23 — trust-copy honesty, overwrite guard, mypy, supply-…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T17:06:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8608b7d2c84a80e5158162fcd2c76bd963679de7",
          "body": "build_appimage.sh pins every embedded timestamp (wheel zip entries + AppImage\nsquashfs) to the HEAD commit time, so rebuilding the same commit yields\nbyte-identical output — verified for the wheel (identical sha256 across runs).\nWith the build-provenance attestation, a release can be both verified a\n[…]\nython-appimage/requirements.txt and TASKS.md. Build-script + docs only.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "build: pin SOURCE_DATE_EPOCH for a reproducible AppImage build (#71)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T16:55:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "48823fab8cbfe6e2a489ac11255f0a2317df9518",
          "body": "…#65)\n\nA known-disc rip whose target album folder already holds audio now shows a\nReplace / Rip to a new folder / Cancel dialog instead of silently overwriting\n(completes the overwrite-safety work started for unknown discs in v0.4.22).\n\nPure, tested helpers: known_album_folder reproduces cyanrip's f\n[…]\no blocking I/O on the GUI thread. +7 tests; 1682 pass, ruff+mypy clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "feat: confirm before a known-disc re-rip overwrites an existing rip (…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T16:47:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "aebbdc1058c0476cb9924aac9ceb279b72c39b79",
          "body": "…ts (#64)\n\nTwo-phase adversarial sweep (verify 6 findings + diverse-lens find-more) of\nevery trust/verification claim rendered to the user found 11 copy defects.\nThe trust engine is sound (verdict.py, track_accuraterip_verified conf>=1, AR\ncells, disc panel, JSON report, never-signing EAC-log render\n[…]\ny. 1675 pass, ruff + mypy clean. Copy + comments only, no logic change.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "fix: trust-claim honesty sweep — remove overclaims + stale CTDB cavea…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T16:35:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2b4eea580f51eba52c491560808c7db89eb5e744",
          "body": "…ps (#63)\n\nAdd mypy to the dev extra + a gating `typecheck` CI job. Baseline excludes\nthe Qt UI mixin layer (platterpus.ui.*) via [tool.mypy] with a documented\nratchet — 309 of 326 errors were the MainWindow mixin god-object pattern —\nand checks everything else. Fixed the 17 non-UI errors properly (\n[…]\n0 tests pass, ruff\n+ mypy clean. mypy approved as a new dev dependency.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "ci: add mypy static type-checking (non-strict baseline) + fix type ga…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T16:07:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e222ae1c7c3d8232cf41f1d19ebfee59b0c8f54a",
          "body": "… audit) (#62)\n\nCompletes the naming-scheme cross-filesystem safety category deferred from\nthe 2026-07-08 trust audit. Audited directly (naming.py,\nsettings_validation.py, cyanrip contract): no shippable bug on the Linux\ntarget — cyanrip maps the only path-illegal chars, the Settings/config\nboundary\n[…]\nnal non-blocking Settings warning (maintainer feature call). Docs only.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "docs: document cyanrip's cross-filesystem filename limitation (naming…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T14:53:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e709d59b35a74d05ddc1ac7e472c2ebbc036509b",
          "body": "…re) (#61)\n\nrelease.yml now runs actions/attest-build-provenance over the released\nAppImage — a signed SLSA provenance statement binding the binary's SHA-256\nto the workflow + commit that built it (GitHub OIDC + Sigstore; no\nmaintainer key, no new runtime dependency). Verify with:\n\n  gh attestation \n[…]\nestation + minisign signing\n(needs a crypto dep + maintainer-held key).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "ci(release): attest AppImage build provenance (SLSA via OIDC + Sigsto…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T14:42:27Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0cbe397c4a6153a0d2bbaffb6a48af2b921c8250",
          "body": "…-efficacy signals (#60)\n\nDeferred 2026-07-08 trust-audit follow-ups (CI/release plumbing only, no\nsource change, no version bump — rides the next release):\n\n- Pin every GitHub Action to a full commit SHA (+ `# vN` comment) across\n  ci/release/publish-pypi/appimage/mutation workflows; add dependabot\n[…]\nlow over the parsers,\n  verdict, and CTDB CRC for test-efficacy signal.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh",
          "is_bot": false,
          "headline": "ci: supply-chain hardening round 2 — SHA-pin actions, pip-audit, test…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T14:31:46Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8d4258bc276500fc0b61122c2eda23e5708f0e1d",
          "body": "…#59)\n\nVerified against PyPI: the wheel has been publishing on every tagged release via\nTrusted Publishing, and `platterpus` is live on PyPI through v0.4.22 — so\n`pipx install platterpus` works. The install docs still carried \"if it's not on\nPyPI yet, install from a checkout\" caveats and TASKS/test-\n[…]\n, and test-plan Test 7 (marked done);\nbumped the touched docs' version stamps.\n\n\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: correct stale \"not on PyPI yet\" claims — pipx install is live (…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T12:45:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "44a9dcd2fbdbe8aae45344bb6052b9ba1cca0842",
          "body": "…(#55)\n\n* feat: trust & supply-chain hardening (2026-07-08 audit)\n\nFrom a trust/quality deep audit (docs/trust-audit-2026-07-08.md). Confirmed,\ncode-verified fixes:\n\n- Unknown-disc overwrite guard: two unrecognized discs both default to\n  \"Unknown Artist/Unknown Album/\" and the second silently overw\n[…]\n → [0.4.22].\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.4.22 — trust & supply-chain hardening (2026-07-08 audit) …",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T02:21:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "348e84250cd363c36f226a425ce645f2f089008e",
          "body": "…#54)\n\n* fix(help): show the running version in the in-app User Guide + add file-versions script\n\nThe doc version-stamp pass only covered Markdown files, so the in-app User\nGuide (Help → User Guide) — which lives in help_content.py — carried no version\nat all. HelpDialog now appends a footer stamped\n[…]\nracked file.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.4.21 — in-app User Guide version + file-versions script (…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-08T01:02:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cd2fb9d7831370fa377052ded12c2d0ed623484f",
          "body": "* docs(session-log): record v0.4.19 re-rip trust audit (Police disc)\n\nFull trust audit of the maintainer's v0.4.19 re-rip of The Police —\nEvery Breath You Take: The Classics (Pioneer BDR-209D, offset +667).\nCross-checked the cyanrip .log, .platterpus.json, EAC-compatible log,\n.cue, and app log.txt a\n[…]\narkdown doc.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_014GVaHVCexqAme1MvDE1qAh\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: v0.4.20 — CTDB CRC hardware-validated (KDD-16) (#53)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-07T23:53:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f50258c97f1be7302980dc7fdeb601494db590f2",
          "body": "…lake root fix (#52)\n\nFixes the read-offset trust chain (a wrong offset silently ruins every rip):\nremoved cyanrip's fabricated offset \"finder\" (its -f is force-overread), added\nagreement-based confidence (reconcile_offset/CONFIRMED), stopped whipper.conf\nfrom falsely satisfying the offset gate, add\n[…]\n-identical, and it removes a coverage-time CI stall. 1659 tests, 93% coverage.\n\nNo copyrighted media touched. CTDB stays behind CRC_VALIDATED=False until a\nhardware --ctdb-calibrate confirms offset-0.",
          "is_bot": false,
          "headline": "release: v0.4.19 — read-offset trust chain, CTDB calibrate perf, CI-f…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-07T07:35:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f89875b1de429d2ef5cc691e3240cdf692163beb",
          "body": "…fix (#51)\n\nSoftware-version provenance in the EAC-compatible log, a per-track EAC\nresults column, and the real CTDB calibration fix (offset sweep widened\nto CTDB's ±5879 range, KDD-16). Docs: README capability/EAC-parity\nmatrix + point-by-point EAC checklist, cyanrip upstream survey, license\naudit,\n[…]\nen-Qt flake, never on a real failure.\n\nCTDB stays behind the fail-safe (CRC_VALIDATED=False, \"experimental\")\nuntil a hardware --ctdb-calibrate confirms an offset-0 match. No\ncopyrighted media touched.",
          "is_bot": false,
          "headline": "release: v0.4.18 — version provenance, EAC column, CTDB offset-range …",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-07T04:12:50Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "032117b3c2d7fb7b13ae151ecd40cae89476a1b2",
          "body": "CTDB CRC algorithm corrected bit-for-bit from the CueTools LGPL source\n(KDD-16); honest tracker/cache-defeat gap docs (KDD-24/25); ordered\nupstream-PR roadmap + GitHub SOP; commit/PR hygiene codified in CLAUDE.md;\nci.yml gains a workflow_dispatch escape hatch. CI green on the branch\n(lint, changelog, full test suite); local suite 1640 passed, 0 failed.",
          "is_bot": false,
          "headline": "release: v0.4.17 — CTDB CRC correction + honest gap docs (#50)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-07T01:27:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6a34f52dd2ca7e87153883474d78479abfc5c4f8",
          "body": "* feat(progress): show \"track N of M\" in the rip status line\n\nThe live status read \"Ripping track 12…\" with no total; the worker already\nknows the disc's track count (from the MusicBrainz metadata and cyanrip's disc\nbanner) but never surfaced it. Thread that total into _describe_activity so the\nlabe\n[…]\nm findings).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012HSe4fg84aD8vWqLYg3jmU\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Release v0.4.16 — QoL + reporting batch (#49)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-07T00:01:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ea9593240d7666f921f1bab82dfef937636ed792",
          "body": "…\"bad rip\" (#48)\n\nOffset-variant tracks (matched only at the +450 pressing offset) now read \"offset-variant match (N)\" in the AR v1/v2 cells instead of cyanrip's alarming \"not found, either a new pressing, or bad rip\"; genuine no-matches read a plain \"not in DB\"; plain matches render \"OK (N)\" consistently. Trust-first wording, mirrors the CTDB honesty fix; surfaced by the real-hardware Roots compilation. Full suite green, coverage >=91%, ruff clean.",
          "is_bot": false,
          "headline": "Release v0.4.15 — offset-variant tracks read as partial matches, not …",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-06T13:45:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "05eb7a7a213c0a722fb602a17983000b0d61719f",
          "body": "Weight each track's slice of the overall progress bar by its MusicBrainz duration so the bar tracks audio position (and thus wall-clock at steady read speed) — the ETA stops oscillating ~10 min per track. Strict fallback to equal-slice when durations are unknown/incomplete. Tests + docs; full suite green, coverage >=91%, ruff clean.",
          "is_bot": false,
          "headline": "Release v0.4.14 — duration-weighted ETA (#47)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-05T23:51:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e65768bc809e4fc6cbde18dce9b1087cdd0c3541",
          "body": "…t, versioned logs (#46)\n\nStall-aware ETA (recorded to log + report), \"Ripping track N\" label fix (was misleadingly \"Encoding\" for the whole read), always-verbose JSON report, app+version banner in every log file, build fingerprint in --version/About/startup, and a quiet report-write on a vanished folder. Driven by the real-hardware Police rip + Roots cancel logs. Full suite green, coverage gate >=91%, ruff clean.",
          "is_bot": false,
          "headline": "Release v0.4.13 — stall-aware ETA, \"Ripping\" label fix, verbose repor…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-05T22:25:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "009060dac98075c7176f58d30592c4856cd31147",
          "body": "…tamped status (#45)\n\nRip-robustness batch from the real Roots box-set session:\n\n- Incremental .platterpus.json: the worker snapshots a partial report\n  (outcome in_progress) beside the growing cyanrip .log after each track, off\n  the GUI thread + atomic — a hard kill/power-loss now leaves tracks-so\n[…]\nhe CDROM ioctl is hardware-gated and degrades\nto a no-op. Coverage 93%.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012HSe4fg84aD8vWqLYg3jmU",
          "is_bot": false,
          "headline": "Release v0.4.12 — incremental rip report, new-disc auto-detect, times…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-05T21:03:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6cc5b6dbfb74a8786e8b76a690655a336a3a7825",
          "body": "…calibrate (#44)\n\nTriggered by the real-hardware v0.4.10 Police rip: CTDB no_match (disc in DB,\nconfidence 1347) against an AccurateRip-confidence-200 rip = the documented\nplaceholder-CRC signature (KDD-16), not a bad rip.\n\n- Honesty: ctdb_verdict_line + verify._match_verdict branch on crc_validated\n[…]\n note.\n\nCRC_VALIDATED stays False until the trim is pinned on hardware.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012HSe4fg84aD8vWqLYg3jmU",
          "is_bot": false,
          "headline": "Release v0.4.11 — CTDB honesty fix + self-diagnosing report + --ctdb-…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-05T19:11:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "63ba478f2dee3d1163b6733a07a9b5bc5e291558",
          "body": "…ch-debt, in-app viewer (#43)\n\nExecutes the handoff20260703.md work end-to-end (Sections A–G) and cuts it as\nrelease v0.4.10.\n\n- A/B: rip report .platterpus.json schema v7 (outcome, settings, disc,\n  environment + per-dependency versions/paths, build fingerprint, gates,\n  cover_art, secure_rerip pro\n[…]\n (god-object mixin split) and IMP-2\n(quit-during-rip drive-stop bound).\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_012HSe4fg84aD8vWqLYg3jmU",
          "is_bot": false,
          "headline": "Release v0.4.10 — rip-report v7, confirmed bugs, KDD-18 doc sweep, te…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-03T13:02:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "25f21b6cec06515d8d304174fbde4915d7a4ef42",
          "body": "… flake fix (#42)\n\n* test(update): lock the relaunch/restart failure modes so they stop recurring\n\nThe AppImage update-restart flow (main_window_update.UpdateMixin) is a proven\nrecurring battleground — the \"updated but didn't restart / closed but didn't\nreopen\" class of bug (env whack-a-mole 2026-06\n[…]\ncreen tail.)\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG\n\n---------\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Proactive follow-ups: update-restart heads-up + Phase-6 backfill + CI…",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-03T01:04:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f6ed20e143efed0367c1cd38df6ec086507def42",
          "body": "The AppImage update-restart flow (main_window_update.UpdateMixin) is a proven\nrecurring battleground — the \"updated but didn't restart / closed but didn't\nreopen\" class of bug (env whack-a-mole 2026-06-27 & 0.4.6, and a fresh\n0.4.8→0.4.9 restart report). Only the happy path + _relaunch_env in isolat\n[…]\ntes (0.4.9 onward), not the already-shipped 0.4.8→0.4.9 run.\n\n[skip changelog]\n\n\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG\n\nCo-authored-by: Claude <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(update): regression-lock the relaunch/restart failure modes (#41)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-03T00:18:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "43a95ed08d796421150f6042d8b20eb479cd52f1",
          "body": "Full-power audit of code/docs/rules/dependencies. Every High- and Medium-severity finding fixed with a regression test; PEP 639 migration; Python 3.14 in CI. 1487 tests green, 93% coverage, all CI checks passing.",
          "is_bot": false,
          "headline": "Release 0.4.9 — full end-to-end audit (#40)",
          "author_name": "rmccann-hub",
          "author_login": "rmccann-hub",
          "committed_at": "2026-07-03T00:00:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4e318bc40a2f8f10f47475173144c827a4db6407",
          "body": "Bump __version__ 0.4.8 → 0.4.9 (the single source; pyproject reads it\ndynamically) and move the [Unreleased] entries under a dated ## [0.4.9] heading\nwith its compare link, per the release process in CLAUDE.md.\n\n0.4.9 collects this session's full-audit work: the GUI-thread correctness pass,\nrip-resu\n[…]\n hardening, the PEP 639 license migration, and the dependency/packaging\ncleanup.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "release: 0.4.9 — bump version + finalize CHANGELOG",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T23:56:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "be73e9ec85c06554ca54a9b6b7d66d1ea8c6b5d3",
          "body": "Record #33 (dead resolve_missing cascade removed), the pytest-pin/Python-3.14\nCI changes, and the low-sev batch outcome (download cap + install-script\ncurrency done; %%Y / run_capture / temp-file-TOCTOU deliberately left with\nrationale) in the audit §E status and the session-log entry.\n\n[skip changelog]\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "docs: update audit + session-log status (#33 + CI + low-sev batch done)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T23:47:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8284692f06aae22a1417d480980302c7c8dd8ca2",
          "body": "…abel\n\ncyanrip is the sole backend (KDD-18), but the install scripts still wrote\n\"whipper\" into user-facing text: the menu-entry Comment (\"Rip audio CDs to\nFLAC with whipper\"), the Keywords, the uninstaller entry's \"Distrobox/whipper\nstack\" wording, and install.sh's \"Uninstall Whipper GUI\" label. Up\n[…]\nipper wrapper for pre-KDD-18 installs, legacy paths) are kept.\n\n[skip changelog]\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "docs: whipper→cyanrip in install-script desktop entries + uninstall l…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T23:45:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5a56dc1ad325b579b55871632efef29a0a7f145a",
          "body": "The AppImage download was unbounded: a misbehaving/hostile server could stream\nan endless body onto the disk before the post-download SHA-256 gate could\nreject it. Now bounded by _MAX_DOWNLOAD_BYTES (1 GiB — generous over the ~240 MB\nreal artifact): a declared Content-Length over the cap is refused \n[…]\n_rejects_oversized_content_length,\ntest_download_aborts_when_stream_exceeds_cap.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(update): cap the in-app download size (low-sev security batch)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T23:44:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ecb41a309f805c4fd7e80a1d32293bcd6829c0b7",
          "body": "Per the audit's dependency review: Python 3.14 (2025-10) is a clean upgrade\nfrom 3.11+ (nothing the project uses was removed; PySide6 6.11 supports it), so\nadd it to the CI test matrix and the packaging classifiers. Widen the dev\npytest pin from <9 to <10 so the suite also runs under pytest 9 (a loc\n[…]\nrm 3.14/pytest-9 locally on a\n3.11/pytest-8 host); CI on the branch is the gate.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "build: add Python 3.14 to CI + classifiers; widen pytest pin to <10",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T23:39:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "204a98045d1495873ac9d77c6d55acb254636112",
          "body": "…olution path)\n\nDependencyManager.resolve_missing (+ _dispatch/_next_tier/_clone_with_tier) was\na second, parallel implementation of dependency-install tier routing that was\nDEAD in production: the GUI always resolves via\nmain_window_deps._resolve_missing_unified, and preflight only calls check_all.\n[…]\n\nRemoved the tests that covered the deleted cascade + wrapper.\n\n[skip changelog]\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "refactor(deps): remove the unused resolve_missing cascade (single res…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T23:38:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "74d0d11fcd79c1cb7f1f5b4c9d7602323251364a",
          "body": "…eferred)\n\nReflect #21/#35/#36 done and record #33 (dependency-subsystem dual-impl) +\nthe pytest-pin/Python-3.14 CI-matrix items as deferred with rationale.\n\n[skip changelog]\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "docs: update audit + session-log status (Phase 2 done, #33/CI-gated d…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:56:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f7e75fd1638387382ed072c044b7281487f8153b",
          "body": "… pass 2+\n\nThe `overall` progress fraction resets to 0 at the start of every rip pass,\nbut the album ETA divided the WHOLE-rip elapsed by that fresh fraction — so\nthe instant a second pass began (a read-speed retry, or a secure re-rip) it\nprojected a wildly inflated time-remaining (large elapsed ÷ t\n[…]\n tests are unchanged).\n\nRegression: test_eta_rebaselines_per_pass_not_whole_rip.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(rip): re-baseline the album ETA per pass so it doesn't balloon on…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:54:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "dede4c1f8aa7f21f964b3633b38b992030f84e2a",
          "body": "…e, not sudo\n\ninstall_argv's unknown-distro fallback piped the upstream Distrobox installer\nto a hardcoded `sudo sh`, ignoring the elevate parameter. From the GUI, elevate\nis pkexec (graphical polkit) because a GUI subprocess has no TTY for sudo to\nread a password from — so the one terminal-free fal\n[…]\nanged.\n\nRegression: test_unknown_distro_distrobox_install_uses_injected_elevate.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(setup): unknown-distro distrobox install uses the injected elevat…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:51:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "eacfd23dbf74126461c20372d6d5e48d55cc9eb3",
          "body": "…tive installs)\n\n_host_stack_ready re-implemented the cyanrip presence check inline as\nCYANRIP_BINARY_DEFAULT.exists(), missing a PATH-native cyanrip — so a user who\ninstalled cyanrip natively (no exported wrapper) was still nagged to run host\nsetup (#36). It now delegates to deps.host_setup.cyanrip\n[…]\ntical Rule #6).\n\nRegression: test_host_stack_ready_delegates_to_cyanrip_on_host.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(provision): delegate host-readiness to cyanrip_on_host (counts na…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:49:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "edb4bc4c26ca7e3fdfe3c692034340fff375fbc4",
          "body": "[skip changelog]\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "style: ruff-format normalization of new regression tests",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:47:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c59780f53993bdbc7f79aca6f84577215e8da6e4",
          "body": "…ession\n\nRecord the 15-agent adversarial audit and the staged fix execution (Phases\n0–5 + PEP 639) with a newest-first session-log entry (per Critical rule #7),\nand mark done vs. still-open findings in docs/audit-2026-07-02.md §E.\n\n[skip changelog]\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "docs: session-log entry + audit execution-status for the full-audit s…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:46:36Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "71667e3b396209185ba884296976063e84fbc9a0",
          "body": "Host setup exports cyanrip, metaflac AND flac to ~/.local/bin/, but the\nin-app uninstaller's _export_files() and uninstall.sh listed only\nwhipper/metaflac/cyanrip — so ~/.local/bin/flac was orphaned after an\nuninstall (#34). Both now include flac, so the export set is removed in full.\n\nRegression: t\n[…]\nl_uninstall_removes_everything now populates + asserts the\nflac wrapper is gone.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(uninstall): remove the exported flac wrapper too",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:45:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "52c508d5500f22e812a33df1a137ddf1533daddc",
          "body": "CTDB verify decoded every track into a list and b\"\".join'd the whole-disc\nPCM (~750 MB) before CRC'ing it — holding the album twice (~1.5 GB peak) on\nthe verify daemon thread (#39). It now folds each track into a running CRC one\nat a time (new ctdb_crc_offset0_streaming seam), so peak memory is a si\n[…]\n— documented in crc.py.\n\nRegression: test_streaming_crc_equals_whole_buffer_crc.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "perf(ctdb): stream the whole-disc CRC instead of buffering the album",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:40:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1f06a5043b620492da099cdb4544288907aa40ce",
          "body": "The EAC-layout export hardcoded \"Read mode: Secure\" and \"Make use of C2\npointers: No\" on every log, but RippingInfo has no field behind either and\ncyanrip doesn't report them — so both were invented rip facts, the very thing\nthe export's own banner disclaims (#32). Both lines are now omitted; only\nf\n[…]\nwhen unreported).\n\nRegression: test_does_not_fabricate_read_mode_or_c2_pointers.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(eac-log): stop fabricating \"Read mode: Secure\" / \"C2 pointers: No\"",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:37:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2d480d5591d63c6f7579ae243b77371466c8fcd0",
          "body": "The #29 change made _metadata_has_colon read the assembled RipMetadata\n(_active_rip_params.metadata) instead of re-deriving from the track table.\nThese two standalone tests set the track table directly, so they now set\n_active_rip_params with a RipMetadata carrying the colon instead.\n\n[skip changelog]\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "test(rip): update the two _metadata_has_colon tests for the new source",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:35:27Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ce79a4c80c7f3e26f22b65108ad9f4212dfc1b96",
          "body": "…ated rip\n\nforce_stop_drive/free_drive began with a name-matched `pkill cyanrip`\n(cdparanoia/cdrdao too), which SIGKILLs ANY such process on the system — e.g.\na cyanrip ripping a different disc on a second drive (#23). They now try the\ndevice-scoped `fuser -k <device>` first (kills only what holds T\n[…]\ns_not_broadly_pkill_when_device_scoped_kill_works\n+ updated ordering assertions.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(drive): device-scoped force-stop first, so it can't kill an unrel…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:33:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7a10036d21c80d4afec92babe6df6c307dcdc8bf",
          "body": "…olders\n\nThe CTDB, FLAC-integrity, and derived-file verify workers globbed FLACs\nrecursively (rglob) under the album folder. A FLAC in a nested subfolder — a\nbonus disc, a leftover, or the whole music library if rip_dir ever fell back\nto the output root — was pulled into the CTDB TOC (corrupting the\n[…]\ntly the rip's files.\n\nRegression: test_nested_flacs_are_not_pulled_into_the_toc.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(verify): enumerate only the album folder's FLACs, not nested subf…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:30:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "00c9ad0e9e4c60e3d10f6cdde10712f2a7fbdce5",
          "body": "…artist\n\ncyanrip can't take a literal ':' in a tag arg, so each such value is fed as\nthe U+2236 lookalike and restored in the written tags afterward (KDD-22). The\ntrigger that decided whether to run that restore only checked album/track\ntitle+artist — but _metadata_args also substitutes the lookalik\n[…]\n received.\n\nRegression: test_metadata_contains_colon_checks_every_cyanrip_field.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(rip): restore a colon in every cyanrip tag field, not just title/…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:27:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "10b3f7eabe612ed55c8d641dd0285bc3fb8b6580",
          "body": "… .sh errexit lock\n\nThe no-shell AST guard only scanned src/platterpus, so a shell=True or\nos.system slipping into a scripts/ CLI or a build helper (both of which shell\nout) would go uncaught (audit #16). The scan now also covers scripts/ and the\ntracked build/ Python, excluding the setuptools-gener\n[…]\nified\nclean, and the shell-side analogue of the no-shell rule.\n\n[skip changelog]\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "test(security): extend the no-shell guard to scripts/ + build/, add a…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:23:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "06b2312e381e72abad333c4dcfbdb53151d55583",
          "body": "…code\n\n- #26: the .desktop Exec= line dropped the AppImage path raw between quotes.\n  A path containing a freedesktop reserved character (\" ` $ \\) would break the\n  quoting or, in a launcher that shells the line out, allow command\n  substitution. A _quote_exec_path helper now backslash-escapes those\n[…]\nscapes_reserved_characters,\ntest_default_hasher_deadline_kills_a_stalled_decode.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(security): escape .desktop Exec path; bound the derived-verify de…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:21:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1c612390f29712c7d3e3db121d30ea4426e3e6ec",
          "body": "- #30: the per-file SHA256 step joins the post-rip tagging/transcode thread\n  with a timeout, then hashes. join(timeout) returns whether or not the thread\n  finished, so if the work hadn't settled it hashed mid-rewrite files and\n  recorded the digest as integrity truth. It now checks is_alive() afte\n[…]\n_skipped_when_post_rip_work_never_settles,\ntest_start_locked_during_a_disc_scan.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(ui): don't hash unsettled files; lock Start during a disc scan",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:17:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fad98c6880bd0f8f983bbeafc2d0426f4a6fabe3",
          "body": "… to this rip\n\nTwo rip-log integrity fixes:\n\n- #19: after the auto-fix re-rips a track and swaps its FLAC in, the\n  whole-disc .log still recorded the discarded bytes' CRC, so the committed\n  durable-proof text no longer matched the audio on disk. A clearly-delimited\n  \"[Platterpus auto-fix addendum\n[…]\nds_swap_addendum_to_album_log,\ntest_find_log_path_ignores_a_previous_albums_log.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(rip): keep the album log honest after a swap; scope log discovery…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:14:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "10d9355af4f96b34a956ba82fbf20a633b5339fd",
          "body": "A MusicBrainz lookup runs asynchronously on the MB worker thread, so a\nlookup fired for disc A can return after the user swapped to disc B. The\ndisc probe already guarded staleness by device, but the MB result path had\nno such guard: a late release-candidate list or fetched release-detail from\nthe p\n[…]\npped_after_disc_change; mb_worker tests\nassert the context echo on every signal.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(mb): drop a stale MusicBrainz result for an already-swapped disc",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T22:07:48Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d0ceeaa039afb3c730eb64462f8ca1a4922a26e5",
          "body": "Close two release-workflow gaps found in the audit (#15):\n\n- Sanity-check step now asserts the built AppImage's --version matches the\n  release tag; a forgotten __version__ bump fails the build loudly instead of\n  shipping a mislabeled binary (which breaks the in-app updater's version\n  compare).\n- \n[…]\nretry re-uploading assets while the release stayed an\n  invisible draft forever.\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(release): assert version==tag and force-publish on retry",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T21:59:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "db2c02171cf87f74e167220d06e9573ab1f5d146",
          "body": "Phase 0 (audit 2026-07-02), documentation currency (Critical rule #7). whipper\nwas removed 2026-06-30 but many docs still described it as current.\n\n- Deleted leaked AI-tool tags (</content>, </invoke>) committed at the end of\n  architecture.md, docs/README.md, test-plan.md, eac-log-and-repair-feasib\n[…]\nformat-comparison \"whipper vs EAC\" → \"cyanrip vs EAC\".\n\n[skip changelog]\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "docs: correct whipper→cyanrip drift, KDD range, module map, leaked tags",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T21:56:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a392eca90466a54cca20142e40bb2248335fb339",
          "body": "Pure formatting (line-length re-wrap) of the Phase-4 config load/validate code;\nno behavior change.\n\n[skip changelog]\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "style: ruff-format normalization of the config-validation code",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T21:56:01Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d64ed76a3266d9d5f5a74eafa6e9aa4de334e33f",
          "body": "…se id\n\nPhase 4 (audit 2026-07-02), resource/injection hardening on the network lookups:\n\n- ctdb_client._default_fetcher: the CTDB transport is plain HTTP (the server has\n  no valid TLS cert), so an unbounded response.read() let a MITM/misbehaving\n  server exhaust memory before the XML parse. Bounde\n[…]\ns\npercent-encoded in the built URL. Full suite green (1477), ruff clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(adapters): cap CTDB response size; URL-encode the cover-art relea…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T21:55:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ce86ce88eb57d5ccb30334a8baa5e9d4dbfbb0d5",
          "body": "…rived-verify\n\nPhase 4 (audit 2026-07-02), the \"capture every dependency's output\" rule. These\nthree adapters ran their subprocess with stderr=DEVNULL and, on failure, returned\na result with no reason logged — so a failed `flac --test` (real corruption), a\nfailed re-encode, or a bad ffmpeg decode wa\n[…]\ner logs its stderr tail on failure. Full\nsuite green (1475), ruff clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(adapters): capture dependency stderr in flac-verify/recompress/de…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T21:48:20Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f9e681eb5249ec4f2bb292626836e6d84e62a3de",
          "body": "…undary\n\nPhase 4 (audit 2026-07-02), the \"validate every input\" rule at the config-file\nboundary:\n\n- config.load() runs at startup before the QApplication / excepthook / guarded\n  dialog exist, so a corrupt config.toml (bad TOML, a non-numeric schema_version)\n  used to crash the app with no visible \n[…]\nal track_template is reset on load. Full\nsuite green (1474), ruff clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(config): never-raise load + validate hand-edited config at the bo…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T21:43:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9c1842596e6e525db111fb67525023532e5ceb31",
          "body": "…guard)\n\nPhase 2 (audit 2026-07-02). Post-rip verifies (CTDB, FLAC-integrity, transcode,\nchecksums, derived) run on background daemons and can outlast the rip. Because\nStart re-enables while they run, a second rip could begin first — and album A's\nlate result was written unconditionally into self._l\n[…]\nes mid-run is dropped, not\napplied. Full suite green (1471), ruff clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(rip): drop a previous album's late verify result (rip-generation …",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T21:40:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9c25edf873a56ba28000531ba05758f00ca756e3",
          "body": "Phase 5 (audit 2026-07-02), maintainer-approved. PEP 639's deprecation window\nfor the `License ::` classifier has passed (setuptools warns and will reject it).\n\n- pyproject: add `license = \"GPL-3.0-only\"` + `license-files = [\"LICENSE\"]`,\n  drop the `License :: OSI Approved …` classifier, bump build \n[…]\n-only.\n\n[skip changelog check not used — CHANGELOG Changed bullet added]\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "build: migrate license metadata to PEP 639 SPDX expression",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T21:32:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "63da98afd7afe8c4fac9604d457cd28e9a012810",
          "body": "…replace\n\nPhase 2 (audit 2026-07-02):\n\n- Unknown-album mode latched True for the whole session (set when a disc can't\n  be identified, never cleared), so a later identified disc rode the unknown\n  path — MBID dropped, track-table validation skipped, generic \"Track N\"\n  filenames. _start_disc_info no\n[…]\nst: a new scan clears unknown mode. Full suite green (1470),\nruff clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(ui): reset unknown mode per scan; drop stale/blocking disc-probe …",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T16:18:25Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "28aaa91baa52e0dfb13d664af157595622214982",
          "body": "…h runs\n\nPhase 3 (audit 2026-07-02). The 0.4.9 headline — \"dynamic secure re-rip is now\nhow ripping works\" — was inert on a fresh install: the worker gates the dynamic\npath on secure_rerip_matches > 0, but the Config default and all three goal\npresets shipped it at 0. A fresh install therefore never\n[…]\nnamic). CHANGELOG bullet corrected. Full suite green\n(1469), ruff clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "feat(rip): ship secure re-rip on by default (-Z 2) so the dynamic pat…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T16:14:12Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "774c5366286fd0b48425a4a655b761cbbd638557",
          "body": "…am-error reap\n\nPhase 2 (audit 2026-07-02), rip-result integrity:\n\n- Dynamic secure re-rip now skips the targeted re-rip when the disc isn't in\n  AccurateRip at all (read_speed_ladder.disc_in_accuraterip): every track\n  \"fails\" AR for a CD-R/obscure pressing, so it used to re-rip + swap the whole\n  \n[…]\nleaves the master intact + no temp.\nFull suite green (1468), ruff clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(rip): not-in-DB re-rip skip, UTF-8-safe finish, atomic swap, stre…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T16:09:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fb501f22d2c92afee66e362ca9d80f6d7a63eeae",
          "body": "Phase 1 (audit 2026-07-02). The host-setup wizard, the uninstaller, the\ndrive-setup dialog, and MainWindow.closeEvent joined their worker threads on the\nGUI thread with waits of 120s/60s/10s (dialogs) and 2-5s (close). quit() can't\ninterrupt a run() blocked in a subprocess (dnf, podman, a disc read)\n[…]\ndetach vs already-stopped\nvs None). Full suite green (1462), ruff clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(ui): stop worker threads on close without freezing or aborting",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T16:00:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5839964daf000ca0b1baf854d04d4e5050dec78d",
          "body": "Phase 1 (audit 2026-07-02). Tools → Check dependencies, the Settings\n\"Check dependencies\" button, and the drive-picker Refresh button all ran\ncontainer-entering probes synchronously on the GUI thread — the same freeze\nclass as the launch check that was already fixed. The off-thread paths existed\nbut\n[…]\ns,\nnever the sync picker.refresh(). Full suite green (1458), ruff clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(ui): run dependency check and drive Refresh off the GUI thread",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T15:55:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f9d8de38e7ccb9283aaf69011c5b5d35dfd7af02",
          "body": "…e update-cancel\n\nThree confirmed GUI-thread freezes on common paths (audit 2026-07-02, Phase 1):\n\n- MusicBrainz queries ran on the GUI thread: the worker was moveToThread'd but\n  its slots were *called* directly, so releases_by_disc_id/release_by_mbid ran on\n  the caller (GUI) thread — freezing the\n[…]\nblocking), not the blocking cancel. Full suite green\n(1457), ruff clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "fix(ui): run MusicBrainz off the GUI thread; non-blocking cancel; liv…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T15:49:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d789a328e6fdbe7d6dcb36acbea0abeb54df3115",
          "body": "Exhaustive multi-agent review (code, docs, rules, dependencies) with\nadversarial verification and external best-practices research. Findings,\ndependency KEEP/UPGRADE decisions, the implied test plan, and a staged\nexecution plan — delivered for maintainer approval before any fixes.\n\nNo code changed; this commit adds only the review document.\n\n[skip changelog]\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Rubb5kujrw2NhbY4THHdFG",
          "is_bot": false,
          "headline": "docs: full-project audit review report (2026-07-02)",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T15:33:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "cd972c488b6b3cbf7363c3475fd1940769adbfa9",
          "body": "…-drive-on-close\n\nLive-testing batch (intended 0.4.9; merged to main, release deferred).\n\nRipping:\n- Dynamic secure re-rip is now the behaviour, not a checkbox: one fast pass,\n  then secure only the AccurateRip-failing tracks. secure_rerip_dynamic\n  defaults True (TOML-only for power users); the Set\n[…]\naction metrics.\n\n1456 tests green; coverage 93% (gate 91%); ruff clean.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Nx9Bo7V4bk1L4gbYCgifA6",
          "is_bot": false,
          "headline": "feat: dynamic-always rip, input/output validation + enforcement, stop…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-02T00:26:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d71279e2f24d2d53760566109779b1507f521548",
          "body": "… can't prove\n\nThe maintainer's ask (opt-in, default-off — their choice): with -Z on, cyanrip\nre-reads EVERY track >=2x, clean or not (~2.8x real-time, and the source of a\n\"20 min on track 1, an hour on track 2\" ETA). But a track that matches\nAccurateRip on its first read is already proven bit-perfe\n[…]\nntil I\nupload final logs\". Docs: CHANGELOG, strategy §8.1, session-log.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Nx9Bo7V4bk1L4gbYCgifA6",
          "is_bot": false,
          "headline": "feat(rip): dynamic secure re-rip — secure only the tracks AccurateRip…",
          "author_name": "Claude",
          "author_login": "claude",
          "committed_at": "2026-07-01T23:12:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 55,
      "commits_last_year": 493,
      "latest_release_at": "2026-07-28T12:13:42Z",
      "latest_release_tag": "v0.5.13",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 9,
      "days_since_latest_release": 0,
      "mean_days_between_releases": 0.7
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 57,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "platterpus",
          "exists": true,
          "license": "GPL-3.0-only",
          "keywords": [
            "audio",
            "cd",
            "rip",
            "flac",
            "wavpack",
            "mp3",
            "musicbrainz",
            "accuraterip",
            "whipper",
            "cyanrip",
            "qt",
            "Development Status :: 4 - Beta",
            "Environment :: X11 Applications :: Qt",
            "Intended Audience :: End Users/Desktop",
            "Operating System :: POSIX :: Linux",
            "Programming Language :: Python :: 3 :: Only",
            "Programming Language :: Python :: 3.11",
            "Programming Language :: Python :: 3.12",
            "Programming Language :: Python :: 3.13",
            "Programming Language :: Python :: 3.14",
            "Topic :: Multimedia :: Sound/Audio :: CD Audio :: CD Ripping"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/platterpus/",
          "is_deprecated": false,
          "latest_version": "0.5.12",
          "repository_url": "https://github.com/rmccann-hub/Platterpus",
          "versions_count": 34,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": 4379,
          "first_published_at": "2026-06-29T19:50:47.574912Z",
          "latest_published_at": "2026-07-28T03:18:57.587078Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 199184,
      "source_files_sampled": 239,
      "oversized_source_files": 4,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 30877
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml"
      ],
      "advisories": {
        "error": null,
        "scope": null,
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "PySide6",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=6.7,<7"
        },
        {
          "name": "musicbrainzngs",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": "==0.7.1"
        },
        {
          "name": "tomli-w",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=1.0,<2"
        },
        {
          "name": "cryptography",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=48.0.1,<50"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 98,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 4
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "claude",
          "commits": 398,
          "avatar_url": "https://avatars.githubusercontent.com/u/81847?v=4"
        },
        {
          "type": "User",
          "login": "rmccann-hub",
          "commits": 91,
          "avatar_url": "https://avatars.githubusercontent.com/u/247853511?v=4"
        }
      ],
      "contributors_sampled": 2,
      "top_contributor_share": 0.814
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "appimage.yml",
        "ci.yml",
        "mutation.yml",
        "publish-pypi.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": null,
      "has_codeql_workflow": false,
      "has_security_policy": true,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-28T12:14:20Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-28T12:11:05Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/rmccann-hub/Platterpus",
    "host": "github.com",
    "name": "Platterpus",
    "owner": "rmccann-hub"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 61,
      "inputs": {
        "security": 73,
        "vitality": 80,
        "community": 33,
        "governance": 55,
        "engineering": 62
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 80,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 67,
            "inputs": {
              "commits_last_year": 493,
              "human_commit_share": 0.93,
              "days_since_last_push": 0,
              "active_weeks_last_year": 9
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "9/52 weeks with commits",
                "points": 6.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 9
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "493 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 493
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "OpenSSF Scorecard unavailable",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "releases_count": 55,
              "latest_release_tag": "v0.5.13",
              "releases_from_tags": false,
              "days_since_latest_release": 0,
              "mean_days_between_releases": 0.7
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "55 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 55
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.7 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.7
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "OpenSSF Scorecard unavailable",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "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": 33,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (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": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 61,
            "inputs": {
              "packages": [
                "platterpus"
              ],
              "dependents": null,
              "ecosystems": "pypi",
              "total_downloads": null,
              "monthly_downloads": 4379
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "4,379 downloads/month across pypi",
                "points": 48.6,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 4379,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 55,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 18,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 2,
              "top_contributor_share": 0.814
            },
            "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 81% of commits",
                "points": 4.2,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 81
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "2 contributors",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "OpenSSF Scorecard unavailable",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "excellent",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 96,
            "inputs": {
              "merged_prs": 98,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 4
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "98/102 decided PRs merged",
                "points": 36.8,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 98,
                      "decided": 102
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "OpenSSF Scorecard unavailable",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "critical",
            "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": 21,
            "inputs": {
              "followers": 1,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "rmccann-hub",
              "public_repos": 2,
              "account_age_days": 235
            },
            "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": "1 followers of rmccann-hub",
                "points": 2.2,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 1,
                      "login": "rmccann-hub"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "2 public repos, account ~0 yr old",
                "points": 4.8,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 2
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 0
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "platterpus"
              ],
              "ecosystems": "pypi",
              "any_deprecated": false,
              "min_days_since_publish": 0
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on pypi",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "pypi"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 0 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "34 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 34
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 62,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 60,
            "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": "5 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "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": "OpenSSF Scorecard unavailable",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 65,
            "inputs": {
              "topics": [],
              "has_wiki": false,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "good",
        "name": "Security",
        "value": 73,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "good",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Dependency lockfiles. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "dependency_lockfiles"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 73,
            "inputs": {
              "source": "file_signals",
              "lockfiles": [],
              "manifests": [
                "pyproject.toml"
              ],
              "has_codeql_workflow": false,
              "has_security_policy": true,
              "has_dependabot_config": true
            },
            "components": [
              {
                "key": "security_policy_security_md",
                "name": "Security policy (SECURITY.md)",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "dependabot_config",
                "name": "Dependabot config",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "dependency_lockfiles",
                "name": "Dependency lockfiles",
                "detail": "published library — lockfiles are an application concern, not expected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "lockfiles_not_expected",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "codeql_workflow",
                "name": "CodeQL workflow",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 60,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "excellent",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 85,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [
                "CLAUDE.md"
              ],
              "agent_instruction_max_bytes": 30877
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "CLAUDE.md",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "CLAUDE.md"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "93 of 93 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 93,
                      "sampled": 93
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 44,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0.77,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0.07
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "77 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 77,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "7 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 7,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "OpenSSF Scorecard unavailable",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 54,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 199184,
              "source_files_sampled": 239,
              "oversized_source_files": 4
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "4/239 source files over 60KB",
                "points": 54.1,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 239,
                      "oversized": 4
                    }
                  }
                ],
                "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": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
    "deps.dev does not index pypi:platterpus@0.5.12; advisories assessed against the repository dependency graph instead",
    "OpenSSF Scorecard did not return a usable result (2026/07/28 12:15:15 Warning: PATs stored in env variables GITHUB_AUTH_TOKEN and GITHUB_TOKEN differ. Scorecard will use the former.); skipping Scorecard checks"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-28T12:15:31.929827Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/r/rmccann-hub/Platterpus.svg",
  "full_name": "rmccann-hub/Platterpus",
  "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.27.0 — metodología completa · wiki de métricas.

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