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

Query-farm / vgi-python

Python SDK for the VGI (Vector Gateway Interface) protocol — host DuckDB scalar, table, aggregate, and table-in-out functions in an external worker over Arrow IPC.

PythonLicencia propia★ 2 estrellas⑂ 0 forksdesde dic 2025Ver en GitHub ↗

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

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

60
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

Query.FarmOrganización
112 seguidores205 repositorios públicosdesde sept 2024

Este repositorio está respaldado por una organización: una custodia compartida y responsable que puede sobrevivir a cualquier mantenedor individual.

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicaciónEtiquetas
PyPIvgi-python0.19.0-25hace 0 díasanalyticsapache-arrowarrowdata-engineeringdatabaseduckdbpyarrowrpcsqludfuser-defined-functionsvgi

Métricas por categoría

Vitalidad

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

89Excelente · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 0 días
18/36Cadencia de commits — 26/52 semanas con commits
18/18Volumen de commits — 751 commits en el último año
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Datos de entrada utilizados
commits_last_year751
human_commit_share0,96
days_since_last_push0
active_weeks_last_year26
Cómo se puntúa
27/27Publica versiones — 25 versiones publicadas
36/36Recencia de las versiones — última versión hace 0 días
27/27Cadencia de publicación — una versión cada ~1,7 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count25
latest_release_tagv0.19.0
releases_from_tagsno
days_since_latest_release0
mean_days_between_releases1,7
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: Signed-Releases. Los pesos restantes se han renormalizado.

Comunidad y Adopción

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

21Crítico · 18% del índice global
Cómo se puntúa
0/60Estrellas — 2 estrellas
0/25Forks — 0 forks
0/15Observadores — 0 observadores
Datos de entrada utilizados
forks0
stars2
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
16.9/22.5Licencia — archivo de licencia presente, no es una licencia reconocida
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

Sostenibilidad y Gobernanza

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

47En riesgo · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
0/22.5Distribución de commits — el principal contribuyente firma el 100% de los commits
1.4/13.5Amplitud de contribuyentes — 1 contribuyentes
3/10OpenSSF Scorecard: Contributors — project has 1 contributing companies or organizations -- score normalized to 3
Datos de entrada utilizados
bus_factor1
contributors_sampled1
top_contributor_share1
Cómo se puntúa
0/46.8Resolución de issues — 0% de issues cerradas
33.1/38.3Aceptación de PR — 39/45 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs39
open_issues4
closed_issues0
issue_closed_ratio0
closed_unmerged_prs6
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
14.8/25Alcance del propietario — 112 seguidores de Query-farm
16.6/25Trayectoria — 205 repos públicos, cuenta de ~1 años
Datos de entrada utilizados
followers112
owner_typeOrganization
is_verified
owner_loginQuery-farm
public_repos205
account_age_days660
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 — 25 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packagesvgi-python
ecosystemspypi
any_deprecatedno
min_days_since_publish0

Calidad de Ingeniería

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

72Bueno · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 4 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
Excluidos de la puntuación (sin datos o no aplicable): OpenSSF Scorecard: CI-Tests. Los pesos restantes se han renormalizado.

Documentación

90Excelente
Cómo se puntúa
30/30README
25/25Directorio de documentación
15/15Sitio de documentación / página del proyecto — https://query.farm
10/10Descripción del repositorio
10/10Topics — 16 topics
0/10Wiki
Datos de entrada utilizados
topicsapache-arrow, arrow, data-engineering, database, duckdb, pyarrow, python, udf, user-defined-functions, vgi, aggregate-functions, arrow-ipc, query-engine, scalar-functions, sdk, table-functions
has_wikino
homepagehttps://query.farm
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?

70Bueno · 16% del índice global
Cómo se puntúa
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
0/2.5CI-Tests — sin datos
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/30 approved changesets -- score normalized to 0
0.8/2.5Contributors — project has 1 contributing companies or organizations -- score normalized to 3
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.2/2.5Licencia — license file detected
7.5/7.5Maintained — 30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
5/5Packaging — packaging workflow detected
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — no SAST tool detected
4.5/5Security-Policy — security policy file detected
0/7.5Signed-Releases — sin datos
7.5/7.5Token-Permissions — GitHub workflow tokens follow principle of least privilege
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate6,3
Excluidos de la puntuación (sin datos o no aplicable): ci_tests, signed_releases. Los pesos restantes se han renormalizado.
Cómo se puntúa
35/35Dependencias directas libres de avisos conocidos — ninguna dependencia directa tiene un aviso conocido
0/25Dependencias indirectas libres de avisos conocidos — el conjunto transitivo no es separable de las dependencias de desarrollo y prueba en este alcance
0/40Sin avisos pendientes — ningún aviso tiene fecha de publicación
Datos de entrada utilizados
sourceosv
advisories0
affected_packages0
assessed_packages113
unassessed_packages2
affected_by_severitynone
direct_affected_packages0
Excluidos de la puntuación (sin datos o no aplicable): Dependencias indirectas libres de avisos conocidos, Sin avisos pendientes. Los pesos restantes se han renormalizado. Se cotejaron 113 dependencias resueltas con OSV. 2 no pudieron evaluarse: sin versión resuelta, ecosistema no admitido o fuera de la lista de paquetes informada. Este repositorio no publica ningún paquete que el índice resuelva, por lo que se evaluó en su lugar el grafo de dependencias del repositorio. Ese grafo mezcla fijaciones de desarrollo y prueba con las dependencias distribuidas, de modo que solo se puntúan las dependencias declaradas en tiempo de ejecución; los hallazgos transitivos se informan como contexto y quedan excluidos de la puntuación. No se analiza la alcanzabilidad.

Preparación para IA

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

68Moderado · 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 — 96 de 96 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_bytes26.757
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
0/11Configuración de lint / formato
11/11Verificación estática de tipos — vgi/py.typed
10/10Entorno reproducible — Dockerfile, lockfile
10/10Práctica demostrada con agentes — 95 de los últimos 100 commits con autoría o crédito de agente
8/8Mantenimiento automatizado — 4 de los últimos 100 commits son actualizaciones automáticas de dependencias
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Datos de entrada utilizados
has_nixno
has_tests
lockfilesuv.lock
has_dockerfile
typed_languageno
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configsvgi/py.typed
agent_commit_share0,95
toolchain_manifests
dependency_bot_commit_share0,04
Cómo se puntúa
27/45Código verificable por tipos — Python con configuración de verificación de tipos (vgi/py.typed)
52.8/55Tamaños de archivo manejables — 12/305 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languagePython
largest_source_bytes212.475
source_files_sampled305
oversized_source_files12
Cómo se puntúa
0/40Esquema de API (OpenAPI/GraphQL/proto)
0/20Servidor MCP
40/40Ejemplos ejecutables — examples
Datos de entrada utilizados
example_dirsexamples
has_mcp_signalno
api_schema_files

Datos clave

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

Advertencias de recopilación de datos

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token
  • deps.dev does not index pypi:vgi-python@0.19.0; advisories assessed against the repository dependency graph instead

Más detalle

OpenSSF Scorecard 6.3 / 10
6.3agregado

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

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
n/dCI-Testsno pull request found
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/30 approved changesets -- score normalized to 0
3Contributorsproject has 1 contributing companies or organizations -- score normalized to 3
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
9Licenselicense file detected
10Maintained30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
10Packagingpackaging workflow detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTno SAST tool detected
9Security-Policysecurity policy file detected
n/dSigned-Releasesno releases found
10Token-PermissionsGitHub workflow tokens follow principle of least privilege
10Vulnerabilities0 existing vulnerabilities detected
Dependencias directas 6
RegistroPaqueteRestricción de versiónManifiesto
PyPIclickpyproject.toml
PyPIpyarrowpyproject.toml
PyPItyper>=0.9pyproject.toml
PyPIplatformdirspyproject.toml
PyPIvgi-rpc>=0.26.0pyproject.toml
PyPIhttpx>=0.24pyproject.toml
Todas las dependencias 115

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

RegistroPaqueteVersiónRelación
PyPIclick8.4.2directa
PyPIhttpx0.28.1directa
PyPIplatformdirs4.10.0directa
PyPIpyarrow24.0.0directa
PyPItyper0.26.8directa
PyPIvgi-rpc0.26.0directa
PyPIaiohappyeyeballs2.6.2indirecta
PyPIaiohttp3.14.1indirecta
PyPIaiosignal1.4.0indirecta
PyPIannotated-doc0.0.4indirecta
PyPIannotated-types0.7.0indirecta
PyPIanyio4.14.0indirecta
PyPIast-serialize0.5.0indirecta
PyPIattrs26.1.0indirecta
PyPIazure-core1.41.0indirecta
PyPIazure-identity1.25.3indirecta
PyPIbabel2.18.0indirecta
PyPIbackrefs7.0indirecta
PyPIblack26.5.1indirecta
PyPIcertifi2026.6.17indirecta
PyPIcffi2.0.0indirecta
PyPIcharset-normalizer3.4.7indirecta
PyPIcolorama0.4.6indirecta
PyPIcoverage7.14.2indirecta
PyPIcryptography49.0.0indirecta
PyPIdocstring-parser0.18.0indirecta
PyPIduckdb1.5.4indirecta
PyPIexecnet2.1.2indirecta
PyPIfalcon4.3.1indirecta
PyPIfrozenlist1.8.0indirecta
PyPIghp-import2.1.0indirecta
PyPIgriffelib2.1.0indirecta
PyPIh110.16.0indirecta
PyPIhatchlingindirecta
PyPIhaybarn1.5.4rc1indirecta
PyPIhttpcore1.0.9indirecta
PyPIidna3.18indirecta
PyPIiniconfig2.3.0indirecta
PyPIjinja23.1.6indirecta
PyPIjoserfc1.7.1indirecta
PyPIjsonschema4.26.0indirecta
PyPIjsonschema-specifications2025.9.1indirecta
PyPIlibrt0.11.0indirecta
PyPIlxml6.1.1indirecta
PyPImarkdown3.10.2indirecta
PyPImarkdown-it-py4.2.0indirecta
PyPImarkupsafe3.0.3indirecta
PyPImdurl0.1.2indirecta
PyPImergedeep1.3.4indirecta
PyPImkdocs1.6.1indirecta
PyPImkdocs-autorefs1.4.4indirecta
PyPImkdocs-d2-plugin1.7.0indirecta
PyPImkdocs-get-deps0.2.2indirecta
PyPImkdocs-material9.7.6indirecta
PyPImkdocs-material-extensions1.3.1indirecta
PyPImkdocs-section-index0.3.12indirecta
PyPImkdocstrings1.0.4indirecta
PyPImkdocstrings-python2.0.5indirecta
PyPImsal1.37.0indirecta
PyPImsal-extensions1.3.1indirecta
PyPImultidict6.7.1indirecta
PyPImypy2.1.0indirecta
PyPImypy-extensions1.1.0indirecta
PyPInumpy2.5.0indirecta
PyPIopentelemetry-api1.42.1indirecta
PyPIopentelemetry-sdk1.42.1indirecta
PyPIopentelemetry-semantic-conventions0.63b1indirecta
PyPIpackaging26.2indirecta
PyPIpaginate0.5.7indirecta
PyPIpathspec1.1.1indirecta
PyPIpluggy1.6.0indirecta
PyPIpropcache0.5.2indirecta
PyPIproperdocs1.6.7indirecta
PyPIpyarrow-stubs20.0.0.20260625indirecta
PyPIpycparser3.0indirecta
PyPIpydantic2.13.4indirecta
PyPIpydantic-core2.46.4indirecta
PyPIpygments2.20.0indirecta
PyPIpyjwt2.13.0indirecta
PyPIpymdown-extensions11.0indirecta
PyPIpymssql2.3.13indirecta
PyPIpynacl1.6.2indirecta
PyPIpytest9.1.1indirecta
PyPIpytest-cov7.1.0indirecta
PyPIpytest-examples0.0.18indirecta
PyPIpytest-ruff0.5indirecta
PyPIpytest-timeout2.4.0indirecta
PyPIpytest-xdist3.8.0indirecta
PyPIpython-dateutil2.9.0.post0indirecta
PyPIpytokens0.4.1indirecta
PyPIpywin32312indirecta
PyPIpyyaml6.0.3indirecta
PyPIpyyaml-env-tag1.1indirecta
PyPIreferencing0.37.0indirecta
PyPIrequests2.34.2indirecta
PyPIrich15.0.0indirecta
PyPIrpds-py2026.5.1indirecta
PyPIruff0.15.20indirecta
PyPIsentry-sdk2.63.0indirecta
PyPIshellingham1.5.4indirecta
PyPIsix1.17.0indirecta
PyPIsqlglot30.12.0indirecta
PyPItenacity9.1.4indirecta
PyPIty0.0.55indirecta
PyPItyping-extensions4.15.0indirecta
PyPItyping-inspection0.4.2indirecta
PyPItzdata2026.2indirecta
PyPIurllib32.7.0indirecta
PyPIvgi-fixtures0.8.2indirecta
PyPIvgi-pythonindirecta
PyPIvgi-python0.19.0indirecta
PyPIwaitress3.0.2indirecta
PyPIwatchdog6.0.0indirecta
PyPIyarl1.24.2indirecta
PyPIzstandard0.25.0indirecta
Avisos de dependencias 0

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

Ningún aviso conocido afecta a las dependencias evaluadas.

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

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [
        "apache-arrow",
        "arrow",
        "data-engineering",
        "database",
        "duckdb",
        "pyarrow",
        "python",
        "udf",
        "user-defined-functions",
        "vgi",
        "aggregate-functions",
        "arrow-ipc",
        "query-engine",
        "scalar-functions",
        "sdk",
        "table-functions"
      ],
      "is_fork": false,
      "size_kb": 10796,
      "has_wiki": false,
      "homepage": "https://query.farm",
      "languages": {
        "Awk": 1659,
        "HTML": 342480,
        "Shell": 27580,
        "Python": 4070269,
        "Dockerfile": 1971
      },
      "pushed_at": "2026-07-23T15:57:05Z",
      "created_at": "2025-12-31T04:52:33Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-23T15:44:22Z",
      "description": "Python SDK for the VGI (Vector Gateway Interface) protocol — host DuckDB scalar, table, aggregate, and table-in-out functions in an external worker over Arrow IPC.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": null,
      "default_branch": "main",
      "license_spdx_raw": "NOASSERTION",
      "primary_language": "Python",
      "significant_languages": [
        "Python"
      ]
    },
    "owner": {
      "blog": "https://query.farm",
      "name": "Query.Farm",
      "type": "Organization",
      "login": "Query-farm",
      "company": null,
      "location": "United States of America",
      "followers": 112,
      "avatar_url": "https://avatars.githubusercontent.com/u/183420031?v=4",
      "created_at": "2024-09-30T18:12:39Z",
      "is_verified": null,
      "public_repos": 205,
      "account_age_days": 660
    },
    "license": {
      "state": "custom",
      "spdx_id": null,
      "raw_spdx": "NOASSERTION",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.19.0",
          "kind": "minor",
          "published_at": "2026-07-23T15:57:05Z"
        },
        {
          "tag": "v0.18.0",
          "kind": "minor",
          "published_at": "2026-07-23T14:20:01Z"
        },
        {
          "tag": "v0.17.0",
          "kind": "minor",
          "published_at": "2026-07-21T19:03:49Z"
        },
        {
          "tag": "v0.16.1",
          "kind": "patch",
          "published_at": "2026-07-20T17:56:47Z"
        },
        {
          "tag": "v0.16.0",
          "kind": "minor",
          "published_at": "2026-07-15T19:22:41Z"
        },
        {
          "tag": "v0.15.0",
          "kind": "minor",
          "published_at": "2026-07-12T17:22:35Z"
        },
        {
          "tag": "v0.14.0",
          "kind": "minor",
          "published_at": "2026-07-09T21:38:38Z"
        },
        {
          "tag": "v0.13.0",
          "kind": "minor",
          "published_at": "2026-07-08T18:40:38Z"
        },
        {
          "tag": "v0.12.0",
          "kind": "minor",
          "published_at": "2026-07-08T15:19:12Z"
        },
        {
          "tag": "v0.11.1",
          "kind": "patch",
          "published_at": "2026-07-08T00:26:02Z"
        },
        {
          "tag": "v0.11.0",
          "kind": "minor",
          "published_at": "2026-07-07T22:34:20Z"
        },
        {
          "tag": "v0.10.0",
          "kind": "minor",
          "published_at": "2026-07-05T18:49:51Z"
        },
        {
          "tag": "v0.9.0",
          "kind": "minor",
          "published_at": "2026-06-30T15:08:23Z"
        },
        {
          "tag": "v0.8.11",
          "kind": "patch",
          "published_at": "2026-06-29T22:01:34Z"
        },
        {
          "tag": "v0.8.10",
          "kind": "patch",
          "published_at": "2026-06-29T19:27:06Z"
        },
        {
          "tag": "v0.8.9",
          "kind": "patch",
          "published_at": "2026-06-29T17:39:04Z"
        },
        {
          "tag": "v0.8.8",
          "kind": "patch",
          "published_at": "2026-06-29T14:01:57Z"
        },
        {
          "tag": "v0.8.7",
          "kind": "patch",
          "published_at": "2026-06-26T04:22:21Z"
        },
        {
          "tag": "v0.8.6",
          "kind": "patch",
          "published_at": "2026-06-25T16:33:13Z"
        },
        {
          "tag": "v0.8.5",
          "kind": "patch",
          "published_at": "2026-06-25T04:01:19Z"
        },
        {
          "tag": "v0.8.4",
          "kind": "patch",
          "published_at": "2026-06-24T16:47:06Z"
        },
        {
          "tag": "v0.8.3",
          "kind": "patch",
          "published_at": "2026-06-23T20:10:36Z"
        },
        {
          "tag": "v0.8.2",
          "kind": "patch",
          "published_at": "2026-06-22T18:43:11Z"
        },
        {
          "tag": "v0.8.1",
          "kind": "patch",
          "published_at": "2026-06-18T16:25:12Z"
        },
        {
          "tag": "v0.8.0",
          "kind": "minor",
          "published_at": "2026-06-15T17:05:15Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "e86b56bd656d67644acea4016c91d45f09a0f659",
          "body": "Minor rather than patch: the attach_opaque_data envelope format changed.\nMetaWorker now seals the catalog name into the attach plaintext\n(VGI\\0MWC\\0 || len || name || uuid(16) || catalog_bytes) instead of prefixing a\nsub-worker index outside the seal, so an attach minted by 0.18.x is not routable\nby\n[…]\ne same\nfunction name and the call carries no attach naming the catalog,\nMetaWorker raises instead of returning the first declarer.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: vgi-python 0.19.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-23T15:41:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f928ac2128c57f43997fd42e4fce70da242a3bea",
          "body": "… stripped prefix\n\nTwo catalogs served by one worker process resolved to the wrong implementation\nover HTTP: `SELECT b.main.test_same_name_catalog(1)` returned `twin_a:1`. The\nscalar path silently answered from the wrong catalog rather than failing\n(scalar/same_name_catalogs.test).\n\nMetaWorker disti\n[…]\nround-trip.\n\nVerified: same_name_catalogs.test passes on stdio and http (32 assertions each);\nfull pytest 2080 passed, 99 skipped.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(meta_worker): route by catalog name sealed into the attach, not a…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-23T15:22:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3d95e08d2b22788674b416572d9574e8310c7d41",
          "body": "The launch lane never ran the suite. SUITE_GLOB was hardcoded to\ntest/sql/integration/launcher/* — 2 files / 20 assertions / 20s against 296\nfiles on the other lanes — since the original CI commit (f17acaa). The comment\nclaiming it mirrored `make test_launcher` was wrong: that target runs the whole\n\n[…]\noth run_unittest passes, with its comment corrected to drop a\nreference to a preprocess-require.awk injection that does not exist.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(integration): run the full suite on the launch lane; move shm onto it",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-23T14:31:55Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9cb30b96e870d851b14b8f39fe7609c560f603a0",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: vgi-python 0.18.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-23T14:19:45Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3e4c4ada7d2bff016059eeb645280ca71f19f1d5",
          "body": "…in Client\n\nA function name was not a unique key: the worker's registry was a flat\nname -> classes map, so two functions registered under the same name in\ndifferent catalog schemas collided as overloads and a call raised\n\"Ambiguous function call\". Registration was already schema-aware —\ncatalog_sche\n[…]\n compliant home.\n\nAlso regenerates the landing golden, which was stale at HEAD — 42628c5\nadded cached_explode without updating it.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(protocol)!: resolve functions by (schema, name); require schema …",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-23T04:33:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "42628c5ae44d3cd3b4735ad39cc59f2725670230",
          "body": "…nterleaved output\n\nA cacheable blended 1->N fan-out (advertises vgi.cache.per_value) covering the\nper-value cardinalities the 1:1 cached_double cannot reach: n=0 is a NEGATIVE memo\n(length-0 slot), n>1 a 1:N slot. Its output is INTERLEAVED round-robin by parent, so\nwithin a chunk a given distinct v\n[…]\nks test/sql/integration/cache/per_value_{multi_batch,negative_memo}.test\nin the engine repo. A test choice, not production advice.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(fixtures): add cached_explode — per-value 1:0 / 1:1 / 1:N with i…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-22T19:22:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "23d92529028d13634f06693a098b494d9f9024d5",
          "body": "Per-value memoization is now an explicit worker advertisement in the\nengine (vgi.cache.per_value), default OFF, because it only pays when one\nworker call costs more than a cache probe + decode + assembly. Cheap maps\nwere paying ~47x the cost of the call being replaced.\n\nCacheControl(per_value=True) \n[…]\nt, since those tests exist to exercise that tier —\nnoted in each docstring as a test choice, not production advice for an\nx*2 map.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(cache): add per_value opt-in to CacheControl",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-22T13:10:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "27765dc6f19c74775aa9bf801a6a3a4cfa2d3a1e",
          "body": "Minor release: the vgi-rpc floor moves to 0.26.0, which changes what workers\nserved through this package put on the wire.\n\n- HTTP response-codec negotiation is now client-authoritative — VGI's\n  X-VGI-Accept-Encoding outranks the generic Accept-Encoding, so cpp-httplib's\n  injected `deflate, gzip, b\n[…]\nompression — distinguishable from a legacy server that omits it.\n- zstd level default drops 3 -> 1 with compression on by default.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: vgi-python 0.17.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-21T19:03:22Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "00cab64c40b71ef59e929f43dac346fa8a4f089e",
          "body": "0.26.0 makes HTTP response-codec negotiation client-authoritative (VGI's\nX-VGI-Accept-Encoding outranks the generic Accept-Encoding, so cpp-httplib's\ninjected `deflate, gzip, br, zstd` no longer drags large Arrow bodies onto\ngzip), promotes `identity` to a first-class accept token, and always emits\n\n[…]\nso that behaviour is guaranteed rather than merely permitted.\n\nFull suite green against the new library (2063 passed, 99 skipped).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "deps: require vgi-rpc >= 0.26.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-21T18:24:15Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cceaac1decb6cb745a4c1211a6cec5536864a2e3",
          "body": "…nch_ladder\n\n00aad32 added the four compute-ladder/wire-probe scalar fixtures but left CI\nred: the vgi/ tree is not covered by the embedded pytest-ruff plugin (testpaths\nis tests/ only), and the landing-conformance drift guard pins the example\nworker's describe.json.\n\n- ruff isort the new bench_ladd\n[…]\nlanding/describe.expected.json for the 4 new functions\n  (collatz_steps, hash_rounds, passthru, sha256_hex): 203 -> 207 functions.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(test-fixtures): green the lint gate + regen landing golden for be…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-21T18:24:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "00aad32637fb3889b89c5eb79ca868711e0e21d5",
          "body": "Four scalar fixtures used by the vgi-benchmarks boundary-amortization suite\nto characterize framework overhead vs per-row compute and payload:\n\n- passthru      identity string (zero-compute pure wire probe)\n- collatz_steps int64 -> int64, data-dependent CPU loop\n- sha256_hex    string -> hex, fixed \n[…]\nhash_rounds   string, const K -> hex; K is a per-row compute knob\n\nRegistered in the example worker alongside multiply/upper_case.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Add compute-ladder + wire-probe benchmark fixtures",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-21T03:57:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f9518ad39ea13114ac80b9f4789595bdd0d16db3",
          "body": "Patch release for the filter-pushdown fix in e3c50a6: an AND whose children\nall degraded rendered as `()`, producing the invalid `WHERE ()` and a\nParserException at the backend.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: vgi-python 0.16.1",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-20T17:56:37Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e3c50a6affea73964eb51e9c52e235d69323f923",
          "body": "…RE ()\n\nAn AND whose children all fail to parse produced `AndFilter(children=())`,\nwhich `_filter_to_sql` rendered as `f\"({' AND '.join([])})\"` -> `()`. Callers\nthat append `WHERE {clause}` when the clause is truthy then built the\nsyntactically invalid statement and the backend rejected it:\n\n    Par\n[…]\nFALSE. Those are the correct identities —\nnotably FALSE for OR, since an empty disjunction must not silently widen the\nresult set.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(filter-pushdown): drop fully-degraded AND instead of emitting WHE…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-20T17:39:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7d4924f8b81202e587ae5cc39ec0bddc817fbb86",
          "body": "Sort the import blocks the fixture registration added in __init__.py and\nworker.py (ruff I001).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "style: ruff isort the new cache_partition_* fixture imports",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-19T13:40:41Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "09519bc2820d6b25ab7d9b04c9e2816ad757162a",
          "body": "- ruff format cache.py; drop a now-redundant local `from typing import Any`.\n- Annotate the projection fixture's `full` dict as `dict[str, list[Any]]` so\n  `RecordBatch.from_pydict` type-checks (was inferred `dict[str, object]`).\n- Regenerate tests/landing/describe.expected.json for the 4 new\n  cache_partition_* example functions (landing-conformance drift guard).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(test-fixtures): lint/format/mypy + regen landing golden",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-19T13:36:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a8e819242502b2f353b5923779134d3aef573d2a",
          "body": "Add `CacheControl.partition_scope` (renders `vgi.cache.partition_scope`), the\nworker-side opt-in for the extension's new per-partition result cache (cache a\nSINGLE_VALUE_PARTITIONS result split by partition value so a later `=`/`IN`\nscan reuses per-partition entries).\n\nFixtures backing the extension\n[…]\nition_multicol: (region, year) multi-column SINGLE_VALUE.\n- cache_partition_proj: projection pushdown + explicit partition_values.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: per-partition result-cache opt-in + fixtures",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-19T13:23:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f807d81101ca88d82efedc02e007072bec93b2f4",
          "body": "The Integration suite has been red on main since the blended/LATERAL\ntable-in-out feature series landed. The only failing tests are\ntable_in_out/blended.test:133,139 (inline named args, `absolute := true`)\nand table_in_out/lateral_batch.test:232 (batched correlated LATERAL) —\nboth pass against a loc\n[…]\nCI validates against the extension the fixtures require.\n\nNo product-code change; the perf work in the prior commit is unaffected.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(integration): bump haybarn pin rc1 -> rc3 for blended named-args",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-17T16:11:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6b33f4d0c8db7d1c1adc0af0a898ecc8f3b6f051",
          "body": "The 0.16 scalar-cache + blended delta left the quality gates red:\n- ruff: E501 line-length in protocol.py, D-series docstring nits.\n- mypy: ScalarFunction lacked the CACHE_CONTROL attr (declared only on\n  the *Generator* base but read off ScalarFunction subclasses in\n  protocol.py); TableCardinality\n[…]\nd\n  input_from_args / substream_id without documenting them.\n- landing describe.expected.json golden stale after the new fixtures.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(lint): green the ruff/mypy/pydoclint gates + refresh landing golden",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-17T05:28:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7245913f6de50c011e4a64665a1f4300f703c6bd",
          "body": "…tch size\n\nA memray review of the DuckDB-extension integration suite (1,246 worker\nspawns) showed statistics_from_duckdb dominating Python-side allocation:\n~625 GiB of real churn suite-wide, ~73 MiB per call on a 3-column table.\nTwo causes: every .to_arrow_table() pre-allocates ArrowAppender buffers\n[…]\nration tests (subprocess), 273/273\nlauncher-transport tests, 39/39 column-statistics unit tests, 525\nfixture-dependent unit tests.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "perf(statistics): single-scan statistics_from_duckdb + small Arrow ba…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-17T01:08:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "82bc93f0eaf44efd419485483d864c11fe706b56",
          "body": "Two cacheable scalar fixtures for the extension's per-value edge-case tests:\n- CachedAddConstScalarFunction(value, addend: ConstParam) — proves the const arg is\n  folded into the per-value cache key (two calls with the same value but different\n  addend must not cross-serve).\n- CachedLabelScalarFunct\n[…]\nache.* via CACHE_CONTROL; registered in __init__ + worker.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XZMDnzigtwqubFrqbP8JEE",
          "is_bot": false,
          "headline": "test(scalar): cacheable const-param + VARCHAR/null scalar fixtures",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-15T20:23:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "13982013d116580050b93b0f37c0e491ad636e3b",
          "body": "Scalars had no way to advertise cacheability. Add a CACHE_CONTROL class attribute\nto ScalarFunction: when set, ScalarExchangeState.exchange rides its vgi.cache.* keys\non the emit path's per-batch custom_metadata (NOT the schema — the IPC stream fixes\nthe schema at open, so a per-batch schema tweak i\n[…]\nation. Backs the\nextension's scalar per-value memoization.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XZMDnzigtwqubFrqbP8JEE",
          "is_bot": false,
          "headline": "feat(scalar): result-cache opt-in for scalar functions (CACHE_CONTROL)",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-15T20:05:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c48175f5f5f79a19558705b02612c484d6dd662e",
          "body": "Includes the catalog_schema_contents RPC schema updates that the current\ncommunity vgi extension expects (published 0.15.0 predates them).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: vgi-python 0.16.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-15T19:22:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "540db11d37088bddfe101c9c64f957fd8ff246a0",
          "body": "…ating fixtures\n\nTableInOutExchangeState.exchange now reads vgi.cache.if_none_match /\nif_modified_since off the input batch's custom_metadata (attached by the C++\nWriteInputBatch) and surfaces them on ProcessParams, so an exchange-mode process()\ncan answer a 0-row CacheControl(not_modified=True) — p\n[…]\ntag from batch content). Registered in the\nfixture worker.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XZMDnzigtwqubFrqbP8JEE",
          "is_bot": false,
          "headline": "feat(exchange): surface conditional-revalidation validators + revalid…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-14T18:36:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fe4370205a8cc3c9fd4b1a27bcdca8943483d5d0",
          "body": "…ixture\n\nAlways wrap the buffered finalize() `out` in _TrackingOutputCollector (not only when\nauto-apply-filters is on), so a buffered finalize can advertise vgi.cache.* /\nmetadata= / partition_values= / batch_index= — parity with the streaming emit path.\nThis is what lets a TableBufferingFunction o\n[…]\nred exchange-cache test. Registered in the fixture worker.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XZMDnzigtwqubFrqbP8JEE",
          "is_bot": false,
          "headline": "feat(buffered): cache-control in finalize emit + cacheable buffered f…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-14T18:01:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a3d114c9357005b33f393a18657fe8425fab4ca1",
          "body": "…hed LATERAL\n\nTwo fixtures backing the batched correlated-LATERAL review coverage:\n\n- ProjectableBlendedFunction: a 1->1 blended map with TWO output columns\n  (a=x*10, b=x*100) advertising projection_pushdown. A subset projection under\n  correlated LATERAL exercises the operator's projection path (w\n[…]\nhs stay symmetric.\n\nBoth registered in the fixture worker.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XZMDnzigtwqubFrqbP8JEE",
          "is_bot": false,
          "headline": "test(blended): projectable + adversarial-provenance fixtures for batc…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-14T01:09:49Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cffce3428a38dfda20654c5cb0465bbc7dfe5695",
          "body": "Add an `out.emit(..., parent_rows=[…])` kwarg so a blended RowTransformFunction\ncan declare, per output row, which input row produced it. `_merge_parent_rows`\nfolds the indices into the emitted batch's `vgi_rpc.parent_row#b64` metadata as a\nraw little-endian int32[] (base64), mirroring the `vgi_part\n[…]\ns (range-checked against the input width on the\nC++ side).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01XZMDnzigtwqubFrqbP8JEE",
          "is_bot": false,
          "headline": "feat(blended): per-output-row provenance for batched correlated LATERAL",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-14T00:24:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c538bc6cb88ad5702d6f953a0264a79cb142bfa0",
          "body": "The C++ bind now casts a blended function's input columns to their declared arg\ntypes on every call shape, so a `latitude: float` arg arrives as a Python float\nhere regardless of literal vs column form. The float() coercion that hid the old\nDECIMAL-literal-vs-DOUBLE-column wart is no longer needed.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(blended): drop float() normalization from geo_encode fixtures",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-13T19:50:32Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ecfc1df36c40947afa0efa08c5e8babd7cba4016",
          "body": "A blended 1->0 map emitting a single 0-row output batch, to exercise the C++\nliteral scan-mode drain loop (skip the empty batch, finish at true EOS, no\ninfinite-loop). Registered in the example worker; backs the 1->0 case in\ntable_in_out/blended.test.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(blended): BlendedDropFunction 1->0 edge-case fixture (Phase B)",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-13T19:27:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c71d3f2ad65afe6d98a8868ba7732b0f8c41cdf9",
          "body": "…res (Phase B)\n\nWorker-side support for blended arity overloads and varargs.\n\n- _match_function_arguments: a blended overload's positional params ARE the input\n  columns (not on the wire), so resolve by INPUT-COLUMN count against the declared\n  positional arity — geo_encode(52,13) -> the 2-positiona\n[…]\n(a literal delivers a DECIMAL constant, a column the cast\n  DOUBLE). Foot-gun + resolution unit tests in test_blended_metadata.py.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(table-in-out): blended arity/varargs overload resolution + fixtu…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-13T18:30:04Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8f7bb4114497840ca528e79b1b48cc5620713af7",
          "body": "…ker support (Phase B)\n\nWorker-side foundation for the C++ extension's blended table-in-out functions.\n\n- RowTransformFunction base class: subclassing it (not a Meta flag — a per-arg or\n  Meta flag could be forgotten on one of N same-named overloads) IS the blended\n  signal. Positional Args are the \n[…]\negistration serving literal /\n  column / LATERAL.\n\nRegenerate cpp/go/ts schemas + the ts client after this (FunctionInfo changed).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(table-in-out): RowTransformFunction (blended \"UNNEST-style\") wor…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-13T17:58:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "59a300a878998b871c58b9e7b24c607a66fda33f",
          "body": "… distributed sum to buffered\n\nWorker-side changes for the C++ extension's Phase A parallel per-substream\nstreaming table-in-out foundation.\n\n- InitRequest.substream_id (nullable): the stable, client-minted per-substream id\n  the extension threads on every init (INPUT + FINALIZE). It is folded into \n[…]\n Sink+Combine+Source path,\n  not the streaming per-substream map path.\n\nRegenerate the TS client after this (InitRequest changed).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(table-in-out): substream_id + parallel-finalize support; migrate…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-13T17:32:38Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2aa7078c7340eef9320ed4669f007da2799fa86d",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): vgi-python 0.15.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-12T17:22:20Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b9c621a04dc946c499d5b846a8ea2eeaf10ccb3e",
          "body": "…(AND-of-ORs)\n\nReplace the flat, AND-only required_field_filter_paths with a single\nrequired_filters field in conjunctive normal form: an AND (outer list) of\nOR-groups (inner lists) of dotted-path column references. A group is satisfied\nwhen any one of its paths has a filter; every group must be sat\n[…]\n preserve prior AND behavior) plus a new rff_or OR-group\nfixture, and the catalog tests. No backward compatibility (clean rename).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(catalog): unify required_field_filter_paths -> required_filters …",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-12T17:21:14Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "43974b51399a9c608c9273f5ee3a8061dc5b19d0",
          "body": "A function-backed catalog data-table declared as\n\n    Table(function=F, arguments=Arguments(positional=(pa.scalar(7),)))\n\nderived its schema correctly but scanned with zero arguments. When F had a\nrequired positional Arg(0), the scan failed at bind with:\n\n    IndexError: Argument 0: index out of ran\n[…]\ne input, so their inlined results stay argument-free.\n\nBackward compatible: a table declaring no arguments still serializes empty.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(catalog): forward Table.arguments to the scan-time worker bind",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-09T22:50:45Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "44a3b6029ccb1f05edcd4d60298e07453bc84063",
          "body": "…press\n\nCatch2 arms signal handlers for the duration of each test case, and forked\nchildren of the extension inherit them until they exec. A signal landing in\nthat window makes the child print a \"due to a fatal error condition\" block\nplus a run summary -- the parent's counters, since it's an address\n[…]\nfore PIPESTATUS is read and overwrites it with true's 0, which would have\nsilently swallowed every real test failure in the suite.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(integration): fail on a fatal-signal report the exit code can't ex…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-09T22:26:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "418700f539f3d3e2dbc7040a88443b5b93056e30",
          "body": "Require vgi-rpc >= 0.24.0 (HTTP producer first-tick metadata) so the VGI\nextension's HTTP result-cache conditional revalidation works end to end,\nand drop the ci/run-integration.sh http-lane skip for cache/revalidate.test\nnow that it runs on both transports.\n\n- pyproject: vgi-rpc>=0.24.0; uv.lock re\n[…]\nsion needs republishing.\n\nVerified: revalidate.test passes over HTTP against published vgi-rpc 0.24.0\n+ a locally-built extension.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.13.0 -> 0.14.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-09T21:38:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "edce116de6f37784b795064f3f938c3a479f01d3",
          "body": "Update the revalidate.test http-lane skip comment: HTTP conditional\nrevalidation is now implemented (C++ /init-request validators + vgi-rpc\nsurfacing them to the producer's first process()), but this lane runs the\npublished community vgi extension + PyPI vgi-rpc, so keep the skip until\nboth ship a release carrying the change, then remove the line.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: HTTP revalidation now implemented; skip stays until releases ship",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-09T21:26:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6e0301a14a794c20dc634a97f09386a026a47c32",
          "body": "The result cache's conditional revalidation (304 / not_modified) is\nsubprocess-only by design: the if_none_match validator rides the first\nproducer tick, but over HTTP that first exchange folds into the /init\nPOST before any tick is sent, so the not_modified path never fires and\nthe worker is re-inv\n[…]\nover HTTP.\nAdd it to the http-lane EXTRA_SKIP alongside the other known-HTTP\nlimitations. The launch/stdio/shm lanes still run it.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: skip cache/revalidate.test on the http lane (subprocess-only)",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-09T20:45:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "08c25ebab30f978bfcbcf0e988065e1950d414f0",
          "body": "14f17ff (\"style(cache): satisfy ruff format + check\") shortened the\ncomment string's *content* to get the line under ruff's 120-char limit,\nrather than wrapping it. That silently dropped the \"Multi-worker \"\nprefix, diverging from both expectation files that still assert the full\ntext: tests/landing/\n[…]\nsql/integration/table/comments.test in the vgi extension repo.\n\nRestore the original text inside parens so the line wraps instead.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(fixtures): restore truncated cache_ordered table comment",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-09T19:30:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "14f17ff962d68ea02b357cbc7aea4dae5bbb4282",
          "body": "CI Lint failed on the result-cache fixtures. Fixes, no behavior change:\n- ruff format on cache_control.py, _test_fixtures/table/cache.py,\n  tests/test_cache_control.py.\n- Sort import blocks (I001) in _test_fixtures/table/__init__.py and\n  worker.py (the os/tempfile additions left worker.py's block u\n[…]\n binary that\npredates the result-cache feature. That clears once a haybarn build with\ncaching is released; nothing to change here.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "style(cache): satisfy ruff format + check on the result-cache fixtures",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-09T18:12:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "395b71d83f5a77e9139666b1d99fca16a9487d86",
          "body": "The multi_branch_* and required_field_filter_paths_native fixtures baked\n`/tmp/...` parquet/csv paths into their read_parquet/read_csv branch\ndefinitions, coupled by convention to .test files that write the same\nhardcoded `/tmp` path. Windows has no `/tmp`, so the COPY-TO in those\ntests failed (\"can\n[…]\n_BRANCH_DIR}/name\nCOPY target byte-for-byte on both platforms. The paired .test + Makefile\nchange lives in the vgi extension repo.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(fixtures): use VGI_TEST_BRANCH_DIR for native-branch scratch paths",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-09T16:44:30Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "33740fee36cd6f8d9b906fb6501fc66198bbc404",
          "body": "Add the vgi.cache.* cache-control vocabulary (vgi/cache_control.py) and\n_merge_cache_control in protocol.py so a worker can advertise a result as\ncacheable (ttl/expires/scope/no_store/etag/last_modified/revalidatable/\nstale_*) on its first emitted batch, plus ProcessParams.if_none_match for\nconditio\n[…]\nilter pushdown), cache_partitioned (partition_values).\nHTTP fixture gains optional bearer auth for cache identity-isolation tests.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(cache): result-cache worker support + example fixtures",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-09T16:00:13Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "61102fdaa6a30ae183f10952c70e0bb91d7a1304",
          "body": "feat(landing): schema descriptions + refreshed shared page (v3)\n\n- describe.json producer emits an optional per-schema `doc` (the schema\n  comment); JSON Schema updated to allow it; golden regenerated.\n- Vendored landing.html v3: Markdown tables, table/view/function/schema\n  descriptions on expand, two-tier green/blue Cupola CTA, INSTALL line\n  before LOAD, footer copyright line.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.12.0 -> 0.13.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-08T18:27:53Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0549033c7d99b592ba728a21f06c46de00330ade",
          "body": "feat(landing): surface catalog macros in describe.json + landing-page fixes\n\n- describe.json producer now collects SCALAR_MACRO/TABLE_MACRO and folds\n  them into the schema `functions` list (scalar macro -> \"scalar\", table\n  macro -> \"table\"). Defaulted macro params render as named args with\n  their\n[…]\ndocs,\n  Arrow->DuckDB column/arg type display, table/view descriptions shown\n  only on expand, footer schema-version line removed.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.11.1 -> 0.12.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-08T15:14:37Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3cbce58a80c11cdb174f029d8f16e9f7b7b45ff6",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "style: ruff-format the vendored conformance checker",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-08T00:21:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "35830c4585e6fac720f8dc2fb91ad27dc7e1ad49",
          "body": "On Windows the checker read the golden with the platform default encoding\n(cp1252), corrupting a UTF-8 em-dash in a table comment and failing the golden\ndiff on the windows-latest CI matrix. Read/write all conformance files as UTF-8.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(landing): read golden/schema as UTF-8 in conformance checker",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-08T00:17:00Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ee2f6c4880d86bce763fe5058d66cfc61fc40dcd",
          "body": "The 0.11.1 bump string-replaced the first version line in uv.lock, which was\nthe librt package (also at 0.11.0), leaving it with a wheel/version mismatch\nthat broke uv.lock parsing. Regenerate the lock so only vgi-python's own entry\nis bumped.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix: regenerate uv.lock (prior manual edit corrupted librt version)",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-08T00:11:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5f9569f3ac79a776194c3f2b1353892324941f0c",
          "body": "- Add missing generic type args (pa.Field[Any], dict[str, Any]) and use\n  schema.field(0) so `mypy vgi/` passes (the CI lint gate).\n- Emit schemas/tables/views sorted by name so describe.json — and the\n  conformance golden — is stable across platforms and Python versions\n  (the CI matrix runs 3.13/3\n[…]\nx/macOS/Windows); regenerate the\n  golden. The conformance checker now prints a unified diff on mismatch.\n- Bump 0.11.0 -> 0.11.1.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(landing): mypy-clean describe.json producer + deterministic ordering",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-08T00:04:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1ecdf093c5028cf0c75044b53b3ce919dbcf271c",
          "body": "Replace the bespoke per-worker HTML page with the shared, self-contained\nlanding.html (vendored byte-identical across all VGI languages) served at\nGET / with content negotiation. It fetches a small, versioned describe.json\ncontract that this repo produces from live catalog introspection.\n\n- vgi/http\n[…]\n + golden + page\n  marker + column-endpoint conformance guard.\n- Require vgi-rpc>=0.23.0 (identity cookie); bump 0.10.0 -> 0.11.0.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(landing): standardized worker landing page + describe.json contract",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-07T22:26:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "708ee019a8dca62c44a56e7f5a231485f8d7e39a",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: sync uv.lock to 0.10.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-06T02:57:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "501edb94b61de72311af729e4d211e2ff54e27ae",
          "body": "Per-argument constraint metadata for agent discovery + bind-time enforcement of const-argument constraints (choices/ge/le/gt/lt/pattern).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.9.0 -> 0.10.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-05T18:49:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ab6fc2375f4e5d3816843b1745b580cbe45c9d45",
          "body": "The bind-time constraint validator's docstring linked [`Arg._validate`][] (a private method with no doc page), which 'mkdocs build --strict' rejects as an unresolved cross-reference (the one failure in CI). Use a plain code span; likewise convert a stray :func: RST ref. No code change.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: drop unresolvable Arg._validate cross-ref (strict mkdocs)",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-05T17:39:46Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "1c6be0ae8908f168bf8eb074aa5c8551d2dc1558",
          "body": "Const-argument constraints (choices/ge/le/gt/lt/pattern) on the modern Param/ConstParam API were surfaced for discovery but never validated at runtime, so a violating value silently reached compute()/update(). Add a shared validate_const_arg_constraints() reused by the scalar bind() and the aggregat\n[…]\nd constraint is actually binding (matching the legacy Arg descriptor path). Columnar Param constraints stay advisory (documented).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(arguments): enforce ConstParam value constraints at bind",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-05T17:24:29Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3730ec09238b5a57ed61bbe9d8641f1eb0d10837",
          "body": "Param and ConstParam gain choices/ge/le/gt/lt/pattern; scalar_function threads\nthem through Arg, and argument_spec encodes them into Arrow field metadata\n(vgi_default/vgi_choices/vgi_range JSON+interval, vgi_pattern regex) surfaced\nby the C++ vgi_function_arguments() diagnostic. The fixture's format\n[…]\nbyte in sync with vgi_protocol_constants.hpp on the\nC++ side; these are field-metadata keys, not RPC schema, so no codegen change.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(arguments): declare per-argument constraints for agent discovery",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-05T03:01:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e6782ce872e6e36fd53edd530824abdee9b97400",
          "body": "Adds a multi_branch_iceberg Table (columns=n int64) + its\ntable_scan_branches_get case to the example worker: a VGI sequence(50) hot\narm + a native iceberg_scan('/tmp/vgi_iceberg_branch') cold arm, with\nrequired_extensions=[\"iceberg\"] so the C++ rewriter auto-loads iceberg.\nBacks the vgi extension's\n[…]\nrts the hot/cold union, filter\npushdown into the iceberg arm, and branch introspection. Dev-only fixture;\nno wire-protocol change.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(fixture): add multi_branch_iceberg example-catalog fixture",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-05T01:48:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "0df7a6a61d563261dfb7ed142b28cf61b4cd0302",
          "body": "- companion.py: single-line summary (D205); type-annotate table_scan_branches_get\n  params (mypy no-untyped-def).\n- ScanBranch docstring: order Attributes to match field order (source_* after\n  writable) — DOC604/605.\n- ReadOnlyCatalogInterface docstring: document attach_catalogs (DOC601/603).\n- __init__: sorted AttachCatalogInfo import (I001).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(catalog): CI lint/mypy/docstring for companion-catalog additions",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-04T20:10:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3f69fec3abdb4953f1c2468c755436b6d3eb30c7",
          "body": "…can branches\n\nProtocol source-of-truth for the lakehouse-federation feature consumed by the\nDuckDB VGI extension.\n\n- AttachCatalogInfo dataclass + CatalogAttachResult.attach_catalogs (nested-IPC\n  list, like settings/secret_types); registered in codegen EXTRA_RESPONSE_TYPES.\n- ScanBranch gains null\n[…]\nst_fixtures/companion.py (vgi-fixture-companion-worker).\n\nRegenerate cpp/go/ts schemas after this. Additive + backward-compatible.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(catalog): companion catalogs (attach_catalogs) + catalog-table s…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-04T18:47:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "fa17d9ea1c3af347c1d7a11fa7dd554922336766",
          "body": "…-stub versions\n\nThe prior cast to list[Buffer] passed local mypy but failed CI, whose pyarrow\nstubs type the parameter as list[Buffer | None]. list is invariant, so no single\nconcrete annotation satisfies both signatures. Type the buffers list as Any,\nwhich is assignable to either. Verified mypy vgi/ + ruff clean locally.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(worker): type from_buffers buffers as Any to satisfy both pyarrow…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-01T19:51:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "443cebc5370bd2c847cf02ed6e55bf24604fa8e7",
          "body": "…w-stub versions\n\nThe `# type: ignore[list-item]` on the from_buffers call is \"unused\" under some\npyarrow-stub versions (CI) but required under others (local), so `mypy vgi/`\nfailed on CI. Replace the ignore with a cast of the buffers list, which\ntype-checks identically regardless of whether the stub signature admits a None\nvalidity buffer. Runtime behavior is unchanged (cast is a no-op).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(worker): make _unpack_bool_mask buffers cast robust across pyarro…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-01T19:29:24Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "014a673f73986f141e06a06d330fa6b4840916f5",
          "body": "…e secret paths\n\nClose the untested secret intersections surfaced while auditing secret coverage.\n\n- catalog/descriptors.py: when a function-backed table's backing function performs\n  a two-phase secret lookup in on_bind (returns a secret-scope request), retry the\n  bind with resolved_secrets_provid\n[…]\nubs for\n  container / copy_from / copy_to / github, and a declarative unit regression for\n  the two-phase schema-derivation retry.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(secret): cover function-backed-table, table-in-out, and aggregat…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-07-01T18:00:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "811291182ade557173a13259b59d0e42bdda2b51",
          "body": null,
          "is_bot": false,
          "headline": "release: bump version 0.8.11 -> 0.9.0",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-30T15:07:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e253dc4097a4fbe6473219da0f411a0c4ccccddf",
          "body": "…iters/readers\n\nCopyToFunction/CopyFromFunction had a @final on_bind with no seam to request\nsecrets, so a worker writing to / reading from secret-backed cloud storage\n(S3/GCS/HTTP) could not receive the caller's credentials.\n\nAdd an overridable on_secrets(params) hook, called from the @final on_bin\n[…]\ns a no-op, so existing formats are\nunaffected.\n\nAdd SecretLinesCopyToFunction / SecretLinesCopyFromFunction fixtures + unit tests.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(copy): on_secrets hook to forward CREATE SECRET creds to COPY wr…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-30T04:58:16Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f9e15f2e6c7bd5e48f72d8d5bac581f69d21c09f",
          "body": "Bumps [pyarrow-stubs](https://github.com/zen-xu/pyarrow-stubs) from 20.0.0.20251215 to 20.0.0.20260625.\n- [Release notes](https://github.com/zen-xu/pyarrow-stubs/releases)\n- [Commits](https://github.com/zen-xu/pyarrow-stubs/compare/20.0.0.20251215...20.0.0.20260625)\n\n---\nupdated-dependencies:\n- depe\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": "deps: Bump pyarrow-stubs from 20.0.0.20251215 to 20.0.0.20260625 (#43)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-29T22:41:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0ed5d299a0dc4ee31861022f71ca4e6f5526139e",
          "body": "Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 10.21.3 to 11.0.\n- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)\n- [Commits](https://github.com/facelessuser/pymdown-extensions/compare/10.21.3...11.0)\n\n---\nupdated-dependencies:\n- depe\n[…]\nrect:development\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": "deps: Bump pymdown-extensions from 10.21.3 to 11.0 (#42)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-29T22:40:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "12d2006e9e7746c24a611d93c06b7542d9876917",
          "body": "One broken transport means the build is broken — cancel the sibling legs\ninstead of spending ~45 min finishing them.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(integration): fail-fast the transport matrix",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-29T22:40:12Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3063c2c0c4191a4be5ebe4d66ede759a9f2672e7",
          "body": "… updates (#44)\n\nBumps the python-minor-and-patch group with 5 updates in the / directory:\n\n| Package | From | To |\n| --- | --- | --- |\n| [click](https://github.com/pallets/click) | `8.4.1` | `8.4.2` |\n| [typer](https://github.com/fastapi/typer) | `0.26.7` | `0.26.8` |\n| [sqlglot](https://github.com\n[…]\nate:semver-patch\n  dependency-group: python-minor-and-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": "deps: Bump the python-minor-and-patch group across 1 directory with 5…",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-29T22:38:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "64266d16dca33db6eea91e69e1820c03683f2559",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore: release 0.8.11 (adds vgi-fixtures container image build)",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-29T22:01:23Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b68c13a5f2e74c16eca9be1fae34389617b5c874",
          "body": "Add a stdio fixture-worker image so the VGI DuckDB extension's container\n(oci://) transport can run the test fixtures with no local uv/Python install —\nthe container IS the worker, piped over stdin/stdout at full subprocess fidelity\n(unlike HTTP). This unblocks running the extension's integration su\n[…]\n, the base worker boots its VgiProtocol RPC server and the\nVGI_FIXTURE_WORKER override switches workers. linux/amd64 only for now.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: build & push vgi-fixtures container images to GHCR",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-29T21:59:05Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d52b6541d3fba229a2095ad3ca89639d0cecab52",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.8.9 -> 0.8.10",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-29T19:13:08Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c3aa7ec97e4dd3bea302f106bf49f18ac6e1ffed",
          "body": "copy_from/copy_to tests have DuckDB write a source file under a relative\n__TEST_DIR__ that the worker then opens by the same relative path; the worker\nonly resolves it if it shares DuckDB's cwd. The stdio lane inherits DuckDB's cwd\nfor free, but the http worker was started from the repo root, so tho\n[…]\nhe unittest binary's cwd (mirrors the vgi repo's run_http_integration.sh); exec\nkeeps the worker on the captured pid for teardown.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(ci): boot the http integration worker from the staging dir",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-29T19:13:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8ff63416c791437d833fefb6c88fc79cc7cb8ba9",
          "body": "…ed as one\n\nA ConstParam was always converted to a Python value via as_py(), so workers that\nfeed it back into pyarrow.compute (e.g. pc.multiply(value, factor)) make pyarrow\nre-infer an Arrow scalar on every batch. That inference is ~40-50x slower on\nWindows than passing a typed pa.scalar (and domin\n[…]\n_test_fixtures/scalar/arithmetic.py: MultiplyFunction.factor is now\n  Annotated[pa.Int64Scalar, ...] — the idiomatic fast pattern.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(scalar): deliver ConstParam as a typed Arrow scalar when annotat…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-29T19:12:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "43848253e328f33e0a198b94e9e4f77fc92b23c3",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.8.8 -> 0.8.9",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-29T17:39:02Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6853c4badcba893c989bdc96a72d8b70fc10eb81",
          "body": "pydoclint depends on docstring-parser-fork while vgi-rpc (a runtime dep) needs\nthe canonical docstring-parser; both own the 'docstring_parser' import\nnamespace, so installing pydoclint into the project env clobbers it\nnon-deterministically. When the canonical files lost, conftest collection broke\non\n[…]\nn't parse the repo's PEP 695 generics (spurious DOC002). Mirrors the\nstandardized fix already applied across the VGI worker repos.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(deps): run pydoclint via uvx, drop docstring-parser-fork conflict",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-29T17:09:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "3a27fedb96388ff2da90ba3ccf60e0ee7bc37ee2",
          "body": "…crets\n\nThe copy-from/to + scope/type-aware-secrets batch landed with several quality\ngates red:\n\n- mypy: ProcessParams/InitParams.secrets were typed as a plain dict, so the\n  fixtures' params.secrets.of_type()/for_scope_of_type() calls failed\n  [attr-defined]; they are ResolvedSecrets at runtime. T\n[…]\n / copy_to.\n- docs --strict: export CopyFromFormatInfo from vgi.catalog so the\n  CopyFromFormatsResponse cross-reference resolves.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(ci): satisfy mypy/ruff/pydoclint/docs gates for copy-from/to + se…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-29T14:26:54Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "847cf87e854a52c7f8e514df850afbcac8271a99",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.8.7 -> 0.8.8",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-29T14:01:55Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c1da8fad45b6588333f78b475d34dcb08a83112b",
          "body": "Extend the example_lines_out COPY-TO fixture to back the expanded shared SLT\nsuite:\n- header_repeat (int, ge=0, le=3, default 1): when header=true, write the header\n  line that many times — exercises ranged-option coercion + worker-side ge/le.\n- fail_on_value (str, default ''): write() raises mid-si\n[…]\nquals it\n  — exercises the in-flight failure/teardown path.\nOrdered variant inherits both. Unit test updated for the 6-option set.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(copy-to): add header_repeat + fail_on_value writer fixture options",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-27T18:42:31Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "6b51e61487983636d70585cbf03f7a629edfa9e7",
          "body": "Mirror the COPY FROM feature for the write direction: catalogs advertise custom\nCOPY ... TO formats and a worker writes the streamed rows to a destination.\n\n- protocol.py: CopyToContext on BindRequest (format + path; additive, no version\n  bump). Source columns ride the existing input_schema.\n- copy\n[…]\ne_lines_out + example_lines_ordered_out writers.\n- Reuses the existing table_buffering_process/combine worker handlers + dispatch.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(copy-to): worker-side COPY ... TO custom format support",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-26T20:02:23Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d5ba35e8d978c8af49f0533ebd7883df20c5e53b",
          "body": "Table-function varargs were always collected as raw pa.Scalar objects,\nwhich drops the active-member discriminator of a union value. Keyed on a\ndeclared union arrow_type, decode each vararg via _scalar_to_py() so it\narrives as a TaggedUnion (matching how non-vararg union args resolve);\nthe raw-scala\n[…]\nactive tag + value). Incidental: tidy the SecretsAccessor\n.to_dict() return annotation and reflow copy_from.py to formatter width.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: decode union-typed table varargs as TaggedUnion",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-26T18:27:53Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1cbc77796cef4f787a977983120cad27d8f2f565",
          "body": "The scope/type-aware ResolvedSecrets refactor (4351f33) left the\nprocess() method that emits {scope, found, secret_keys} attached to\nMultiSecretDemoFunction instead of ScopedSecretDemoFunction. As a result\nScopedSecretDemoFunction had no process() (abstract-instantiation\nTypeError) and MultiSecretDe\n[…]\ncretDemoFunction a correct one that emits api_key from\nMultiSecretDemoState. Fixes secret_scoped.test and secret_multi_scope.test.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(fixtures): restore process() on scoped/multi secret demo fixtures",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-26T18:27:44Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "4351f3378fbacfe7632614f0eaaf36dea0791cd2",
          "body": "Resolved secrets are now keyed by name (the connector change). Make\nSecretsAccessor.to_dict() return a ResolvedSecrets dict subclass with\nfor_scope / for_scope_of_type / of_type / secret_type / field_for, and make\nthe scalar @Secret(type) resolver match on each secret's serialized \"type\"\nfield (colu\n[…]\nlect by type via of_type, and add a multi_secret_demo fixture that\nresolves two same-type scoped secrets in one bind. Unit-tested.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(secrets): scope- and type-aware ResolvedSecrets + name-keying",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-26T18:02:26Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b61fd9d125f4f4c4195a8991f2b5226e3ed8295e",
          "body": "Add the protocol surface and worker API for catalogs to advertise custom\nCOPY ... FROM formats (FROM only):\n\n- protocol.py: CopyFromContext on BindRequest (additive, no version bump);\n  catalog_copy_from_formats RPC + CopyFromFormatsResponse.\n- catalog_interface.py: CopyFromFormatInfo + copy_from_fo\n[…]\nted reader.\n- codegen/_common.py: register CopyFromFormatInfo for schema generation.\n- tests + protocol-inventory allowlist entry.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(copy-from): worker-side COPY ... FROM custom format support",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-26T17:08:03Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "7f30117706cbce0f21c92f7c7fcda051b3a78d1c",
          "body": "TCP transport support (vgi-rpc 0.21.0): worker --tcp and\nClient.from_tcp / transport='tcp'.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.8.6 -> 0.8.7",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-26T04:22:11Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b83ab8c4a057d2309c04d33ed3147dbeebf86a1d",
          "body": "Wire up the raw Arrow-IPC TCP transport added in vgi-rpc 0.21.0:\n\n- Worker.main() gains --tcp [HOST:]PORT, mutually exclusive with\n  --http/--unix, emitting the TCP:<host>:<port> discovery line and\n  serving via serve_tcp(). The meta/fixture worker (run_server) picks\n  up --tcp directly from vgi-rpc\n[…]\n_tcp.\n\nTCP framing carries no auth/encryption (loopback/trusted networks\nonly); HTTP remains the transport for untrusted networks.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: add TCP transport support (vgi-rpc 0.21.0)",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-26T03:29:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "adb29b3e05748b6b5fc8d21fb3a28383c5676e48",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: sync uv.lock to 0.8.6",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-25T18:11:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "7038f7bdb80b3f17288c242223d499e53fca2687",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.8.5 -> 0.8.6",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-25T16:32:56Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "4743741c6f5c9ba6d4ae990c27c95ec438b9e5da",
          "body": "Empty schemas now collapse to []arrow.Field{} on one line, and there is no\ntrailing blank line at EOF — gofmt rejects both forms and vgi-go's CI runs\ngofmt -l. Surfaced by the macro arguments_schema regen.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(codegen): emit gofmt-clean Go schemas",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-25T16:17:22Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2fcf21abc8914f3fb409a7d3f0299dcc8d50ebf8",
          "body": "Macros gain an optional arguments_schema (one nullable field per parameter,\ncarrying the per-parameter description via the same vgi_doc field-metadata key\nfunctions use) on MacroCreateRequest and the macro listing/get responses, plus\na declarative Macro.parameter_docs API. Mirrors how functions carr\n[…]\nve + optional so older workers/extensions are unaffected. Closes the\ngap where macro parameters were name-only and undocumentable.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: per-parameter documentation for macros",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-25T15:29:08Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "f6ee11458d87f200914774e5f80a3c328317d227",
          "body": "Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.8.4 -> 0.8.5",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-25T04:00:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5225a79692987165fc11f5148157d761bf1c1c54",
          "body": "ArgumentSpec gains a typed doc field, emitted as the vgi_doc Arrow field-\nmetadata key (UTF-8, presence-only) and decoded on round-trip. Threads doc\nthrough every ArgumentSpec construction site in extract_argument_specs so the\ndescription is no longer silently dropped at serialization. Reserves the\nvgi_doc_* prefix for a future audience split.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat: serialize per-argument doc as vgi_doc field metadata",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-25T02:52:03Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "2e0dda9abaf1f6e0b06be4c77d01e271d4209839",
          "body": "Ships worker-settable catalog source_url + per-schema tags (declarative Catalog\ndescriptor) for vgi-lint metadata. Function tags were already supported.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: bump version 0.8.3 -> 0.8.4",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-24T16:43:05Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c98c74bc15301f8a675bdfa3153a3e5a0df042f3",
          "body": "Verifies a worker can attach arbitrary key/value tags to a function via\nMeta.tags (e.g. vgi.columns_md for VGI307), and that they flow through\nresolve_metadata -> ResolvedMetadata.tags -> FunctionInfo.tags (and the\nmetadata Arrow wire roundtrip) to DuckDB/the linter. Also asserts the\nstructured examples channel and a worker-set vgi.example_queries tag\ncoexist without either clobbering the other.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(metadata): cover arbitrary function tags flowing into FunctionInfo",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-24T16:41:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3273c8b423793071921d4bbaf3810eca7c564047",
          "body": "The metadata-quality linter's VGI004 rule expects catalogs to advertise a\nsource_url (repo/docs homepage) via the catalog_catalogs discovery record\n(CatalogInfo.source_url / duckdb_databases()). The declarative Catalog\ndescriptor had no way to set it, and the default catalogs() serializer\nalways emi\n[…]\ninfo() into\nSchemaInfo.tags, so no change was needed there.\n\nMirrors the vgi-rust fix (CatalogModel.source_url + serializer emit).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(catalog): let declarative Catalog advertise source_url",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-24T15:59:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "02c3e39310992c7119fb92667cb5f7f1ce96f247",
          "body": "CountBatchArgs.batch_size and BATCH_SIZE_FALLBACK defaulted to 1000. Align the\ncanonical batch-size default with DuckDB's default vector size (2048) so the\nstandard sequence-family generators (sequence, double_sequence, nested_sequence,\nprofiling_demo) match the Rust/TypeScript workers, which alread\n[…]\nred SLT that asserts a batch count (dynamic_to_string.test) pins batch_size\nexplicitly, so cross-language workers stay consistent.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fixtures: default batch_size to 2048 (DuckDB STANDARD_VECTOR_SIZE)",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-24T03:59:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "cb125d9db3564fdca049fbed32439c4b28ad9724",
          "body": "Cuts a release for the union-tag fix added on top of 0.8.2 (commits d0eb85f\nfeat, 56ef84b lint/mypy, 473b9e9 tests): Arguments now preserve the union tag\nwhen decoding union-typed args, exposed as vgi.TaggedUnion. This unblocks the\ndiscriminated-union grid_search in the downstream workers.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: 0.8.3 — union-tag-preserving argument decode (TaggedUnion)",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-23T16:55:51Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "473b9e9d76c3ac98c337bdc3030a2137a15ee2bc",
          "body": "…us codes, dense)\n\nAdd unit tests for _scalar_to_py/TaggedUnion exercising the previously\nuntested branches: non-contiguous type codes (tag resolved via\ntype_codes.index, not member position), dense unions (what DuckDB emits),\nand the null-valued union slot branch.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test: cover union argument boundary cases (null payload, non-contiguo…",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-22T22:02:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "56ef84ba8da4b1239e26dad78d9a222115ca0e03",
          "body": "CI lint/type gates (not run locally before the prior push) flagged the union\ndecode: drop the redundant UnionType cast, coerce type_code to int (the pyarrow\nstub types it as str though it is an int at runtime) so the type_codes lookup\ntype-checks, and add docstrings to the new union tests.\n\nruff, mypy (vgi/), and the union tests all clean locally.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(arguments): satisfy strict mypy + ruff for union-tag decode",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-22T19:48:13Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d0eb85f47a73d575a5613c32542ed2b6c6b0242d",
          "body": "A DuckDB UNION / Arrow union argument is tagged — the discriminator lives in\nUnionScalar.type_code, which plain Scalar.as_py() discards, so a union arg\narrived as just its member value with no way to tell which member was set.\n\nDecode union scalars to a new TaggedUnion(tag, value) instead: tag is th\n[…]\nnd over the RPC path (sparse union). Note: the C++ extension\nstill rejects dense unions; full union support needs a fix there too.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(arguments): preserve union tag when decoding union-typed args",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-22T19:32:51Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "34978e2ea48b60683737138f3cab3b0fe99a0246",
          "body": "Bump the vgi-rpc floor to 0.20.5 and refresh the full lock to latest\n(vgi-rpc 0.20.6, aiohttp 3.14.1, coverage 7.14.2, griffelib 2.1.0,\nmkdocstrings-python 2.0.5). Version bumped to 0.8.2 across vgi-python\nand vgi-fixtures.\n\nCo-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "release: 0.8.2 — require vgi-rpc 0.20.5, refresh all locked deps (#40)",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-22T18:42:59Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d97cd36f3262c05146d4005af1a271493edb367a",
          "body": "State is persisted only for groups whose dict entry was *assigned* during\nupdate() (plus groups carried from a prior batch). An in-place mutation of a\ngroup first seen in the current batch is silently dropped, so finalize() sees\nonly initial_state() — every result NULL for single-group/single-batch\naggregates. Spell out the immutable-reassign idiom with do/don't examples.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: document reassign-to-persist contract on AggregateFunction.update",
          "author_name": "Rusty Conover",
          "author_login": "rustyconover",
          "committed_at": "2026-06-22T17:55:04Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f6b65aa7c89f8a6f68da475e26f3b27a176aecb6",
          "body": "Bumps the python-minor-and-patch group with 5 updates:\n\n| Package | From | To |\n| --- | --- | --- |\n| [numpy](https://github.com/numpy/numpy) | `2.4.6` | `2.5.0` |\n| [pydoclint](https://github.com/jsh9/pydoclint) | `0.8.6` | `0.8.7` |\n| [pytest](https://github.com/pytest-dev/pytest) | `9.1.0` | `9.1\n[…]\nate:semver-patch\n  dependency-group: python-minor-and-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": "deps: Bump the python-minor-and-patch group with 5 updates (#39)",
          "author_name": "dependabot[bot]",
          "author_login": "dependabot[bot]",
          "committed_at": "2026-06-22T16:13:42Z",
          "body_truncated": true,
          "is_coding_agent": false
        }
      ],
      "releases_count": 25,
      "commits_last_year": 751,
      "latest_release_at": "2026-07-23T15:57:05Z",
      "latest_release_tag": "v0.19.0",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 26,
      "days_since_latest_release": 0,
      "mean_days_between_releases": 1.7
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 50,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "vgi-python",
          "exists": true,
          "license": null,
          "keywords": [
            "analytics",
            "apache-arrow",
            "arrow",
            "data-engineering",
            "database",
            "duckdb",
            "pyarrow",
            "rpc",
            "sql",
            "udf",
            "user-defined-functions",
            "vgi",
            "Development Status :: 4 - Beta",
            "Intended Audience :: Developers",
            "License :: Other/Proprietary License",
            "Operating System :: OS Independent",
            "Programming Language :: Python :: 3",
            "Programming Language :: Python :: 3 :: Only",
            "Programming Language :: Python :: 3.13",
            "Programming Language :: Python :: 3.14",
            "Topic :: Database",
            "Topic :: Database :: Database Engines/Servers",
            "Topic :: Software Development :: Libraries :: Python Modules",
            "Typing :: Typed"
          ],
          "ecosystem": "pypi",
          "matches_repo": true,
          "registry_url": "https://pypi.org/project/vgi-python/",
          "is_deprecated": false,
          "latest_version": "0.19.0",
          "repository_url": "https://github.com/Query-farm/vgi-python",
          "versions_count": 25,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2026-06-15T17:06:16.267432Z",
          "latest_published_at": "2026-07-23T15:57:48.728150Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 0
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 2,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": null,
      "open_issues_and_prs": 6
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": true,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "vgi/py.typed"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 212475,
      "source_files_sampled": 305,
      "oversized_source_files": 12,
      "agent_instruction_files": [
        "CLAUDE.md"
      ],
      "agent_instruction_max_bytes": 26757
    },
    "dependencies": {
      "manifests": [
        "pyproject.toml"
      ],
      "advisories": {
        "error": null,
        "scope": "repository_graph",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 113,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 2,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "pypi"
      ],
      "dependencies": [
        {
          "name": "click",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "pyarrow",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "typer",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.9"
        },
        {
          "name": "platformdirs",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": null
        },
        {
          "name": "vgi-rpc",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.26.0"
        },
        {
          "name": "httpx",
          "manifest": "pyproject.toml",
          "ecosystem": "pypi",
          "version_constraint": ">=0.24"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "click",
            "direct": true,
            "version": "8.4.2",
            "ecosystem": "pypi"
          },
          {
            "name": "httpx",
            "direct": true,
            "version": "0.28.1",
            "ecosystem": "pypi"
          },
          {
            "name": "platformdirs",
            "direct": true,
            "version": "4.10.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyarrow",
            "direct": true,
            "version": "24.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "typer",
            "direct": true,
            "version": "0.26.8",
            "ecosystem": "pypi"
          },
          {
            "name": "vgi-rpc",
            "direct": true,
            "version": "0.26.0",
            "ecosystem": "pypi"
          },
          {
            "name": "aiohappyeyeballs",
            "direct": false,
            "version": "2.6.2",
            "ecosystem": "pypi"
          },
          {
            "name": "aiohttp",
            "direct": false,
            "version": "3.14.1",
            "ecosystem": "pypi"
          },
          {
            "name": "aiosignal",
            "direct": false,
            "version": "1.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "annotated-doc",
            "direct": false,
            "version": "0.0.4",
            "ecosystem": "pypi"
          },
          {
            "name": "annotated-types",
            "direct": false,
            "version": "0.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "anyio",
            "direct": false,
            "version": "4.14.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ast-serialize",
            "direct": false,
            "version": "0.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "attrs",
            "direct": false,
            "version": "26.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "azure-core",
            "direct": false,
            "version": "1.41.0",
            "ecosystem": "pypi"
          },
          {
            "name": "azure-identity",
            "direct": false,
            "version": "1.25.3",
            "ecosystem": "pypi"
          },
          {
            "name": "babel",
            "direct": false,
            "version": "2.18.0",
            "ecosystem": "pypi"
          },
          {
            "name": "backrefs",
            "direct": false,
            "version": "7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "black",
            "direct": false,
            "version": "26.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "certifi",
            "direct": false,
            "version": "2026.6.17",
            "ecosystem": "pypi"
          },
          {
            "name": "cffi",
            "direct": false,
            "version": "2.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "charset-normalizer",
            "direct": false,
            "version": "3.4.7",
            "ecosystem": "pypi"
          },
          {
            "name": "colorama",
            "direct": false,
            "version": "0.4.6",
            "ecosystem": "pypi"
          },
          {
            "name": "coverage",
            "direct": false,
            "version": "7.14.2",
            "ecosystem": "pypi"
          },
          {
            "name": "cryptography",
            "direct": false,
            "version": "49.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "docstring-parser",
            "direct": false,
            "version": "0.18.0",
            "ecosystem": "pypi"
          },
          {
            "name": "duckdb",
            "direct": false,
            "version": "1.5.4",
            "ecosystem": "pypi"
          },
          {
            "name": "execnet",
            "direct": false,
            "version": "2.1.2",
            "ecosystem": "pypi"
          },
          {
            "name": "falcon",
            "direct": false,
            "version": "4.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "frozenlist",
            "direct": false,
            "version": "1.8.0",
            "ecosystem": "pypi"
          },
          {
            "name": "ghp-import",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "griffelib",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "h11",
            "direct": false,
            "version": "0.16.0",
            "ecosystem": "pypi"
          },
          {
            "name": "hatchling",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "haybarn",
            "direct": false,
            "version": "1.5.4rc1",
            "ecosystem": "pypi"
          },
          {
            "name": "httpcore",
            "direct": false,
            "version": "1.0.9",
            "ecosystem": "pypi"
          },
          {
            "name": "idna",
            "direct": false,
            "version": "3.18",
            "ecosystem": "pypi"
          },
          {
            "name": "iniconfig",
            "direct": false,
            "version": "2.3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jinja2",
            "direct": false,
            "version": "3.1.6",
            "ecosystem": "pypi"
          },
          {
            "name": "joserfc",
            "direct": false,
            "version": "1.7.1",
            "ecosystem": "pypi"
          },
          {
            "name": "jsonschema",
            "direct": false,
            "version": "4.26.0",
            "ecosystem": "pypi"
          },
          {
            "name": "jsonschema-specifications",
            "direct": false,
            "version": "2025.9.1",
            "ecosystem": "pypi"
          },
          {
            "name": "librt",
            "direct": false,
            "version": "0.11.0",
            "ecosystem": "pypi"
          },
          {
            "name": "lxml",
            "direct": false,
            "version": "6.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "markdown",
            "direct": false,
            "version": "3.10.2",
            "ecosystem": "pypi"
          },
          {
            "name": "markdown-it-py",
            "direct": false,
            "version": "4.2.0",
            "ecosystem": "pypi"
          },
          {
            "name": "markupsafe",
            "direct": false,
            "version": "3.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "mdurl",
            "direct": false,
            "version": "0.1.2",
            "ecosystem": "pypi"
          },
          {
            "name": "mergedeep",
            "direct": false,
            "version": "1.3.4",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs",
            "direct": false,
            "version": "1.6.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs-autorefs",
            "direct": false,
            "version": "1.4.4",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs-d2-plugin",
            "direct": false,
            "version": "1.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs-get-deps",
            "direct": false,
            "version": "0.2.2",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs-material",
            "direct": false,
            "version": "9.7.6",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs-material-extensions",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocs-section-index",
            "direct": false,
            "version": "0.3.12",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocstrings",
            "direct": false,
            "version": "1.0.4",
            "ecosystem": "pypi"
          },
          {
            "name": "mkdocstrings-python",
            "direct": false,
            "version": "2.0.5",
            "ecosystem": "pypi"
          },
          {
            "name": "msal",
            "direct": false,
            "version": "1.37.0",
            "ecosystem": "pypi"
          },
          {
            "name": "msal-extensions",
            "direct": false,
            "version": "1.3.1",
            "ecosystem": "pypi"
          },
          {
            "name": "multidict",
            "direct": false,
            "version": "6.7.1",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy",
            "direct": false,
            "version": "2.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "mypy-extensions",
            "direct": false,
            "version": "1.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "numpy",
            "direct": false,
            "version": "2.5.0",
            "ecosystem": "pypi"
          },
          {
            "name": "opentelemetry-api",
            "direct": false,
            "version": "1.42.1",
            "ecosystem": "pypi"
          },
          {
            "name": "opentelemetry-sdk",
            "direct": false,
            "version": "1.42.1",
            "ecosystem": "pypi"
          },
          {
            "name": "opentelemetry-semantic-conventions",
            "direct": false,
            "version": "0.63b1",
            "ecosystem": "pypi"
          },
          {
            "name": "packaging",
            "direct": false,
            "version": "26.2",
            "ecosystem": "pypi"
          },
          {
            "name": "paginate",
            "direct": false,
            "version": "0.5.7",
            "ecosystem": "pypi"
          },
          {
            "name": "pathspec",
            "direct": false,
            "version": "1.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pluggy",
            "direct": false,
            "version": "1.6.0",
            "ecosystem": "pypi"
          },
          {
            "name": "propcache",
            "direct": false,
            "version": "0.5.2",
            "ecosystem": "pypi"
          },
          {
            "name": "properdocs",
            "direct": false,
            "version": "1.6.7",
            "ecosystem": "pypi"
          },
          {
            "name": "pyarrow-stubs",
            "direct": false,
            "version": "20.0.0.20260625",
            "ecosystem": "pypi"
          },
          {
            "name": "pycparser",
            "direct": false,
            "version": "3.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pydantic",
            "direct": false,
            "version": "2.13.4",
            "ecosystem": "pypi"
          },
          {
            "name": "pydantic-core",
            "direct": false,
            "version": "2.46.4",
            "ecosystem": "pypi"
          },
          {
            "name": "pygments",
            "direct": false,
            "version": "2.20.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pyjwt",
            "direct": false,
            "version": "2.13.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pymdown-extensions",
            "direct": false,
            "version": "11.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pymssql",
            "direct": false,
            "version": "2.3.13",
            "ecosystem": "pypi"
          },
          {
            "name": "pynacl",
            "direct": false,
            "version": "1.6.2",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest",
            "direct": false,
            "version": "9.1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-cov",
            "direct": false,
            "version": "7.1.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-examples",
            "direct": false,
            "version": "0.0.18",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-ruff",
            "direct": false,
            "version": "0.5",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-timeout",
            "direct": false,
            "version": "2.4.0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytest-xdist",
            "direct": false,
            "version": "3.8.0",
            "ecosystem": "pypi"
          },
          {
            "name": "python-dateutil",
            "direct": false,
            "version": "2.9.0.post0",
            "ecosystem": "pypi"
          },
          {
            "name": "pytokens",
            "direct": false,
            "version": "0.4.1",
            "ecosystem": "pypi"
          },
          {
            "name": "pywin32",
            "direct": false,
            "version": "312",
            "ecosystem": "pypi"
          },
          {
            "name": "pyyaml",
            "direct": false,
            "version": "6.0.3",
            "ecosystem": "pypi"
          },
          {
            "name": "pyyaml-env-tag",
            "direct": false,
            "version": "1.1",
            "ecosystem": "pypi"
          },
          {
            "name": "referencing",
            "direct": false,
            "version": "0.37.0",
            "ecosystem": "pypi"
          },
          {
            "name": "requests",
            "direct": false,
            "version": "2.34.2",
            "ecosystem": "pypi"
          },
          {
            "name": "rich",
            "direct": false,
            "version": "15.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "rpds-py",
            "direct": false,
            "version": "2026.5.1",
            "ecosystem": "pypi"
          },
          {
            "name": "ruff",
            "direct": false,
            "version": "0.15.20",
            "ecosystem": "pypi"
          },
          {
            "name": "sentry-sdk",
            "direct": false,
            "version": "2.63.0",
            "ecosystem": "pypi"
          },
          {
            "name": "shellingham",
            "direct": false,
            "version": "1.5.4",
            "ecosystem": "pypi"
          },
          {
            "name": "six",
            "direct": false,
            "version": "1.17.0",
            "ecosystem": "pypi"
          },
          {
            "name": "sqlglot",
            "direct": false,
            "version": "30.12.0",
            "ecosystem": "pypi"
          },
          {
            "name": "tenacity",
            "direct": false,
            "version": "9.1.4",
            "ecosystem": "pypi"
          },
          {
            "name": "ty",
            "direct": false,
            "version": "0.0.55",
            "ecosystem": "pypi"
          },
          {
            "name": "typing-extensions",
            "direct": false,
            "version": "4.15.0",
            "ecosystem": "pypi"
          },
          {
            "name": "typing-inspection",
            "direct": false,
            "version": "0.4.2",
            "ecosystem": "pypi"
          },
          {
            "name": "tzdata",
            "direct": false,
            "version": "2026.2",
            "ecosystem": "pypi"
          },
          {
            "name": "urllib3",
            "direct": false,
            "version": "2.7.0",
            "ecosystem": "pypi"
          },
          {
            "name": "vgi-fixtures",
            "direct": false,
            "version": "0.8.2",
            "ecosystem": "pypi"
          },
          {
            "name": "vgi-python",
            "direct": false,
            "version": null,
            "ecosystem": "pypi"
          },
          {
            "name": "vgi-python",
            "direct": false,
            "version": "0.19.0",
            "ecosystem": "pypi"
          },
          {
            "name": "waitress",
            "direct": false,
            "version": "3.0.2",
            "ecosystem": "pypi"
          },
          {
            "name": "watchdog",
            "direct": false,
            "version": "6.0.0",
            "ecosystem": "pypi"
          },
          {
            "name": "yarl",
            "direct": false,
            "version": "1.24.2",
            "ecosystem": "pypi"
          },
          {
            "name": "zstandard",
            "direct": false,
            "version": "0.25.0",
            "ecosystem": "pypi"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 115,
        "direct_count": 6,
        "indirect_count": 109
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 2,
        "merged_prs": 39,
        "open_issues": 4,
        "closed_ratio": 0,
        "closed_issues": 0,
        "closed_unmerged_prs": 6
      },
      "bus_factor": 1,
      "bot_contributors": 1,
      "top_contributors": [
        {
          "type": "User",
          "login": "rustyconover",
          "commits": 750,
          "avatar_url": "https://avatars.githubusercontent.com/u/731941?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "docs.yml",
        "integration.yml",
        "release.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "uv.lock"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 3,
            "reason": "project has 1 contributing companies or organizations -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 9,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": 10,
            "reason": "packaging workflow detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 0,
            "reason": "dependency not pinned by hash detected -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "no SAST tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 9,
            "reason": "security policy file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 10,
            "reason": "GitHub workflow tokens follow principle of least privilege",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "e86b56bd656d67644acea4016c91d45f09a0f659",
        "ran_at": "2026-07-23T16:06:54Z",
        "aggregate_score": 6.3,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": true,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-23T16:02:18Z",
      "oldest_open_prs": [
        {
          "number": 45,
          "created_at": "2026-07-06T09:25:52Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 51,
          "created_at": "2026-07-21T18:32:03Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-06-29T22:41:26Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 32,
          "created_at": "2026-05-07T01:36:48Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 33,
          "created_at": "2026-05-07T01:37:15Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 34,
          "created_at": "2026-05-07T01:37:38Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 35,
          "created_at": "2026-05-07T01:37:59Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/Query-farm/vgi-python",
    "host": "github.com",
    "name": "vgi-python",
    "owner": "Query-farm"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 60,
      "inputs": {
        "security": 70,
        "vitality": 89,
        "community": 21,
        "governance": 47,
        "engineering": 72
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "excellent",
        "name": "Vitality",
        "value": 89,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "good",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 82,
            "inputs": {
              "commits_last_year": 751,
              "human_commit_share": 0.96,
              "days_since_last_push": 0,
              "active_weeks_last_year": 26
            },
            "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": "26/52 weeks with commits",
                "points": 18,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 26
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "751 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 751
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 25,
              "latest_release_tag": "v0.19.0",
              "releases_from_tags": false,
              "days_since_latest_release": 0,
              "mean_days_between_releases": 1.7
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "25 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 25
                    }
                  }
                ],
                "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 ~1.7 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 1.7
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 0,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 0 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "critical",
        "name": "Community & Adoption",
        "value": 21,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 2,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "2 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "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": "at_risk",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 44,
            "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": "license file present, not a recognized license",
                "points": 16.9,
                "status": "partial",
                "details": [
                  {
                    "code": "license_custom",
                    "params": {}
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "at_risk",
        "name": "Sustainability & Governance",
        "value": 47,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 13,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 3,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "at_risk",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 33,
            "inputs": {
              "merged_prs": 39,
              "open_issues": 4,
              "closed_issues": 0,
              "issue_closed_ratio": 0,
              "closed_unmerged_prs": 6
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "0% of issues closed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 0
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "39/45 decided PRs merged",
                "points": 33.1,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 39,
                      "decided": 45
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "moderate",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 61,
            "inputs": {
              "followers": 112,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "Query-farm",
              "public_repos": 205,
              "account_age_days": 660
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "112 followers of Query-farm",
                "points": 14.8,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 112,
                      "login": "Query-farm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "205 public repos, account ~1 yr old",
                "points": 16.6,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 205
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 1
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "vgi-python"
              ],
              "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": "25 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 25
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 72,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 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": "4 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "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": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "excellent",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 90,
            "inputs": {
              "topics": [
                "apache-arrow",
                "arrow",
                "data-engineering",
                "database",
                "duckdb",
                "pyarrow",
                "python",
                "udf",
                "user-defined-functions",
                "vgi",
                "aggregate-functions",
                "arrow-ipc",
                "query-engine",
                "scalar-functions",
                "sdk",
                "table-functions"
              ],
              "has_wiki": false,
              "homepage": "https://query.farm",
              "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": "https://query.farm",
                "points": 15,
                "status": "met",
                "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": "16 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 16
                    }
                  }
                ],
                "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": 70,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): CI-Tests, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "ci_tests",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 63,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 6.3
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "no pull request found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/30 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 1 contributing companies or organizations -- score normalized to 3",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow detected",
                "points": 5,
                "status": "met",
                "details": [],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "no SAST tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file detected",
                "points": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "GitHub workflow tokens follow principle of least privilege",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): Indirect dependencies free of known advisories, No advisories left outstanding. Remaining weights renormalized. Matched 113 resolved dependencies against OSV; 2 could not be assessed (no resolved version, an unsupported ecosystem, or beyond the reported package list). This repository publishes no package the index resolves, so the repository dependency graph was assessed instead. That graph mixes development and test pins with shipped dependencies, so only the declared runtime dependencies are scored; transitive findings are reported as context and excluded from the score. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "indirect_dependencies_free_of_known_advisories",
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_repository",
                "params": {
                  "assessed": 113
                }
              },
              {
                "code": "advisories_unassessed",
                "params": {
                  "count": 2
                }
              },
              {
                "code": "advisories_repo_graph_caveat",
                "params": {}
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 113,
              "unassessed_packages": 2,
              "affected_by_severity": "none",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "transitive set not separable from development and test dependencies in this scope",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_scope_not_separable",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 113,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 2
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 68,
        "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": 26757
            },
            "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": "96 of 96 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 96,
                      "sampled": 96
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 61,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "uv.lock"
              ],
              "has_dockerfile": true,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "vgi/py.typed"
              ],
              "agent_commit_share": 0.95,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0.04
            },
            "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": "vgi/py.typed",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "vgi/py.typed"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "Dockerfile, lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "Dockerfile, lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "95 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 95,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "4 of the last 100 commits are automated dependency updates",
                "points": 8,
                "status": "met",
                "details": [
                  {
                    "code": "dependency_bot_commits",
                    "params": {
                      "count": 4,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "good",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 80,
            "inputs": {
              "primary_language": "Python",
              "largest_source_bytes": 212475,
              "source_files_sampled": 305,
              "oversized_source_files": 12
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Python with type-check config (vgi/py.typed)",
                "points": 27,
                "status": "partial",
                "details": [
                  {
                    "code": "typecheck_config_language",
                    "params": {
                      "files": "vgi/py.typed",
                      "language": "Python"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "12/305 source files over 60KB",
                "points": 52.8,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 305,
                      "oversized": 12
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token",
    "deps.dev does not index pypi:vgi-python@0.19.0; advisories assessed against the repository dependency graph instead"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-23T16:07:01.382241Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/q/Query-farm/vgi-python.svg",
  "full_name": "Query-farm/vgi-python",
  "license_state": "custom",
  "license_spdx": null
}

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.