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

sferik / multi_xml

A generic swappable back-end for XML parsing

RubyMIT★ 172 estrellas⑂ 38 forksdesde oct 2010Ver en GitHub ↗

sferik/multi_xml tiene un índice de salud de 65 sobre 100, lo que lo sitúa en la banda Moderado. Su puntuación más alta es Vitality (71/100) y la más baja, AI Readiness (32/100). Se actualizó por última vez hace 8 días. Una sola persona concentra la mayor parte del trabajo reciente.

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

65
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

Erik BerlinCuenta personal
2649 seguidores216 repositorios públicosdesde may 2008

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

Ecosistemas de paquetes

RegistroPaqueteVersiónDescargas / mesVersionesÚltima publicación
RubyGemsmulti_xml0.9.1-29hace 78 días

Métricas por categoría

Vitalidad

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

71Bueno · 22% del índice global
Cómo se puntúa
28.8/36Recencia de push — último push hace 8 días
6.2/36Cadencia de commits — 9/52 semanas con commits
17.1/18Volumen de commits — 80 commits en el último año
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 10
Datos de entrada utilizados
commits_last_year80
human_commit_share1
days_since_last_push8
active_weeks_last_year9
Cómo se puntúa
27/27Publica versiones — 1 versiones publicadas
36/36Recencia de las versiones — última versión hace 78 días
12.6/27Cadencia de publicación — cadencia desconocida (una sola versión)
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count1
latest_release_tagv0.9.1
releases_from_tagsno
days_since_latest_release78
mean_days_between_releases
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?

70Bueno · 18% del índice global
Cómo se puntúa
36.2/60Estrellas — 172 estrellas
13.1/25Forks — 38 forks
2.7/15Observadores — 4 observadores
Datos de entrada utilizados
forks38
stars172
watchers4
growth_stateorganic
growth_factor_pct100
Cómo se puntúa
22.5/22.5README
22.5/22.5Licencia — licencia reconocida (MIT)
18/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_contributing
has_issue_templateno
has_code_of_conductno
has_pull_request_templateno
Cómo se puntúa
80/80Descargas totales — 583.709.139 descargas históricas en rubygems
0/20Dependientes en el registro — no lo informa este ecosistema
Datos de entrada utilizados
packagesmulti_xml
dependents
ecosystemsrubygems
total_downloads583.709.139
monthly_downloads
Excluidos de la puntuación (sin datos o no aplicable): Dependientes en el registro. Los pesos restantes se han renormalizado.

Sostenibilidad y Gobernanza

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

68Moderado · 24% del índice global
Cómo se puntúa
9/54Factor bus — la mitad de los commits recae en 1 contribuyente(s)
2.7/22.5Distribución de commits — el principal contribuyente firma el 88% de los commits
13.5/13.5Amplitud de contribuyentes — 20 contribuyentes
10/10OpenSSF Scorecard: Contributors — project has 16 contributing companies or organizations
Datos de entrada utilizados
bus_factor1
contributors_sampled20
top_contributor_share0,879
Cómo se puntúa
46.8/46.8Resolución de issues — 100% de issues cerradas
30.8/38.3Aceptación de PR — 33/41 PR decididos fusionados
0/15OpenSSF Scorecard: Code-Review — Found 0/30 approved changesets -- score normalized to 0
Datos de entrada utilizados
merged_prs33
open_issues0
closed_issues34
issue_closed_ratio1
closed_unmerged_prs8
Cómo se puntúa
10/30Respaldo de la propiedad — cuenta personal (usuario)
0/20Dominio verificado — no aplicable a cuentas de usuario
24.6/25Alcance del propietario — 2649 seguidores de sferik
25/25Trayectoria — 216 repos públicos, cuenta de ~18 años
Datos de entrada utilizados
followers2649
owner_typeUser
is_verified
owner_loginsferik
public_repos216
account_age_days6642
Excluidos de la puntuación (sin datos o no aplicable): Dominio verificado. Los pesos restantes se han renormalizado.
Cómo se puntúa
25/25Publicado y resoluble — 1 paquete(s) en rubygems
35/35Recencia de publicación — última publicación hace 78 días
20/20Historial de versiones — 29 versiones en el registro
20/20No obsoleto — activo, ni obsoleto ni retirado
Datos de entrada utilizados
packagesmulti_xml
ecosystemsrubygems
any_deprecatedno
min_days_since_publish78

Calidad de Ingeniería

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

68Moderado · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 7 flujo(s) de trabajo
24/24Pruebas presentes
16/16Configuración de linter — .rubocop.yml
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_config
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

50Moderado
Cómo se puntúa
30/30README
0/25Directorio de documentación
0/15Sitio de documentación / página del proyecto
10/10Descripción del repositorio
0/10Topics
10/10Wiki
Datos de entrada utilizados
topics
has_wiki
homepage
has_readme
has_docs_dirno
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?

45En riesgo · 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
2.5/2.5Contributors — project has 16 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Licencia — license file detected
7.5/7.5Maintained — 30 commit(s) and 2 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
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — sin datos
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Datos de entrada utilizados
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate4,5
Excluidos de la puntuación (sin datos o no aplicable): ci_tests, signed_releases. Los pesos restantes se han renormalizado.

Preparación para IA

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

32En riesgo · 0% del índice global
Cómo se puntúa
0/45Instrucciones para agentes — sin CLAUDE.md / AGENTS.md / reglas de editor
0/15Documentación legible por máquinas (llms.txt)
18.1/40Historial de commits legible — 34 de 100 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,34
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
0/18Arranque con un solo comando
22/22Pruebas automatizadas
11/11Configuración de lint / formato — .rubocop.yml
0/11Verificación estática de tipos
0/10Entorno reproducible
0/10Práctica demostrada con agentes — ningún commit con autoría de agente entre los últimos 100
0/8Mantenimiento automatizado — no se observan 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
lockfiles
has_dockerfileno
typed_languageno
bootstrap_files
has_devcontainerno
has_linter_config
typecheck_configs
agent_commit_share0
toolchain_manifests
dependency_bot_commit_share0
Cómo se puntúa
0/45Código verificable por tipos — Ruby sin configuración de verificación de tipos
55/55Tamaños de archivo manejables — 0/80 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageRuby
largest_source_bytes30.160
source_files_sampled80
oversized_source_files0

Datos clave

172estrellas de GitHub
20contribuidores
80commits en los últimos 12 meses
8días desde el último push
1versiones publicadas
1factor bus
0issues abiertas
RubyGemsecosistemas de paquetes

Advertencias de recopilación de datos

  • No resolved dependencies carried a version and a supported ecosystem

Más detalle

Historial de estrellas y forks 172 ★ / 38 ⇿
172Estrellas
38Forks
1Versiones

Cuándo se añadió cada estrella y fork, recopilado de GitHub y agrupado por día. El crecimiento acumulado se sitúa justo encima de las adiciones diarias que lo componen, de modo que ambos se leen en conjunto: la acumulación orgánica sostenida no se parece en nada a un pico abrupto y efímero. Cuando esa diferencia es medible, se informa como autenticidad del crecimiento.

0408012016020017237542010-102018-072026-05
Mayor 0Menor 0Parche 1

Cada punto abarca 15 días.

OpenSSF Scorecard 4.5 / 10
4.5agregado

Evaluación de seguridad independiente y agnóstica en cuanto a herramientas, procedente del proyecto de código abierto OpenSSF Scorecard. Cada comprobación premia una práctica de seguridad, no la herramienta de un proveedor concreto. Las comprobaciones que Scorecard no pudo determinar se marcan como n/d y se excluyen de la puntuación de seguridad (nunca se cuentan como cero).Scorecard v5.5.0 · 2026-07-22 01:58 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
10Contributorsproject has 16 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
10Maintained30 commit(s) and 2 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
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
Dependencias directas 22
RegistroPaqueteRestricción de versiónManifiesto
RubyGemslibxml-rubyGemfile
RubyGemsnokogiriGemfile
RubyGemsoga>= 2.3Gemfile
RubyGemsoxGemfile
RubyGemsrexmlGemfile
RubyGemsminitest>= 6Gemfile
RubyGemsminitest-mock>= 5.27Gemfile
RubyGemsmutant-minitest>= 0.14.1Gemfile
RubyGemsrake>= 13.3.1Gemfile
RubyGemsrbs>= 4.0.0Gemfile
RubyGemsrdoc>= 7.0.2Gemfile
RubyGemsrdoc>= 7.0.2Gemfile
RubyGemsrubocop>= 1.81.7Gemfile
RubyGemsrubocop-minitest>= 0.36Gemfile
RubyGemsrubocop-performance>= 1.26.1Gemfile
RubyGemsrubocop-rake>= 0.7.1Gemfile
RubyGemssimplecov>= 1Gemfile
RubyGemsstandard>= 1.52Gemfile
RubyGemsstandard-performance>= 1.9Gemfile
RubyGemssteep>= 2Gemfile
RubyGemsyard>= 0.9.38Gemfile
RubyGemsyardstick>= 0.9.9Gemfile
Todas las dependencias 22

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

RegistroPaqueteVersiónRelación
RubyGemslibxml-rubydirecta
RubyGemsminitestdirecta
RubyGemsminitest-mockdirecta
RubyGemsmutant-minitestdirecta
RubyGemsnokogiridirecta
RubyGemsogadirecta
RubyGemsoxdirecta
RubyGemsrakedirecta
RubyGemsrbsdirecta
RubyGemsrdocdirecta
RubyGemsrexmldirecta
RubyGemsrubocopdirecta
RubyGemsrubocop-minitestdirecta
RubyGemsrubocop-performancedirecta
RubyGemsrubocop-rakedirecta
RubyGemssimplecovdirecta
RubyGemsstandarddirecta
RubyGemsstandard-performancedirecta
RubyGemssteepdirecta
RubyGemsyarddirecta
RubyGemsyardstickdirecta
RubyGemsbigdecimalindirecta
Avisos de dependencias sin evaluar

El cotejo de avisos no pudo ejecutarse para este informe: No resolved dependencies carried a version and a supported ecosystem

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 575,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "Ruby": 258536,
        "Shell": 131
      },
      "pushed_at": "2026-07-13T21:04:12Z",
      "created_at": "2010-10-03T05:18:16Z",
      "owner_type": "User",
      "updated_at": "2026-07-13T21:04:49Z",
      "description": "A generic swappable back-end for XML parsing",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "main",
      "license_spdx_raw": "MIT",
      "primary_language": "Ruby",
      "significant_languages": [
        "Ruby"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Erik Berlin",
      "type": "User",
      "login": "sferik",
      "company": null,
      "location": "San Francisco",
      "followers": 2649,
      "avatar_url": "https://avatars.githubusercontent.com/u/10308?v=4",
      "created_at": "2008-05-14T20:36:12Z",
      "is_verified": null,
      "public_repos": 216,
      "account_age_days": 6642
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.9.1",
          "kind": "patch",
          "published_at": "2026-05-04T18:32:52Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "391efee2f509a7afde833eee8315f0ec7f59f16b",
          "body": "With the benchmark defaults of 0.03s warmup and 0.15s samples, the\nJIT engines are measured cold and close parser pairs flip: on\nTruffleRuby, nokogiri outranked oga by 21% in CI, while a warmed-up\nrun keeps the coded order (rexml, oga, nokogiri) within tolerance.\nGive the verify_preference job two seconds of warmup and one-second\nmeasurement windows so Graal and the JVM compile the hot paths\nbefore the ranking is asserted.",
          "is_bot": false,
          "headline": "Warm up the JIT before verifying parser preference order",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-07-13T20:48:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "54aacd371ddc7fe7bd5f6dec99724421a900b0b9",
          "body": "rdoc 8 depends on rbs 4, whose native extension cannot build on\nJRuby, and mutant pulls rdoc in via irb, so the existing platform\ngates on rbs and steep were bypassed; rdoc 7 has no rbs dependency.\nSkip the lowercase-require-path test on JRuby, where require-site\ncaching keeps warm call sites bound to the original Kernel#require\nso the stub never sees the call.",
          "is_bot": false,
          "headline": "Fix JRuby CI: cap rdoc below 8 and skip a require-stubbing test",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-07-13T11:46:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fd5955e32926847d96850b8d19525b01f7597047",
          "body": null,
          "is_bot": false,
          "headline": "Remove the redundant `keyword_init: true`",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-07-13T11:12:58Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4ed4e7f22ef05acfc49df2d5bb540df64aa5e18",
          "body": "Collapse the 11 reopenings of MultiXMLBenchmark in benchmark.rb into\na single class body and extract the deprecated MultiXml constant shim\nfrom lib/multi_xml.rb into lib/multi_xml/legacy_constant.rb, required\nafter multi_xml/deprecated so the forwarder snapshot still sees the\ncomplete public API.",
          "is_bot": false,
          "headline": "Fix Style/OneClassPerFile offenses",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-07-13T11:10:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "046d7687e90a81f42cb9dbd86740401d1fd28563",
          "body": null,
          "is_bot": false,
          "headline": "Use to_h { ... } instead of each_with_object",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-07-13T04:29:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9acf8036f1d82ec74169c596dd1da7499c901b0e",
          "body": null,
          "is_bot": false,
          "headline": "Update SimpleCov to version 1.0",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-07-13T04:24:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "52a03525397b1b0b1a3bd49ec7bee09fdd7154c9",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.9.1",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-05-04T17:36:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1c34a5c51c32ec3a41bc6c232f8ee7a5d96463c0",
          "body": "Mirror multi_json's push.yml: after the gem is published to RubyGems,\ncreate a GitHub release for the tag with auto-generated notes. The\n`gh release view` check makes the step idempotent in case the workflow\nre-runs against an existing tag.",
          "is_bot": false,
          "headline": "Create a GitHub release on tag push",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-05-04T17:36:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "533d505f49cdd09c831a7d81270127714bfa77c2",
          "body": "The legacy MultiXml constant forwarded calls to MultiXML via\nmethod_missing, but Module#method doesn't consult method_missing, so\nMultiXml.method(:load) resolved to the inherited Kernel#load and\ncrashed with LoadError when invoked. Any caller capturing the legacy\nconstant's load method as a Method o\n[…]\nevery public method\nMultiXML exposes, so Module#method finds the forwarder directly. Drop\nthe now-dead method_missing and respond_to_missing? hooks; the eager\nforwarders cover the full public surface.",
          "is_bot": false,
          "headline": "Fix MultiXml.method(:load) resolving to Kernel#load",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-05-04T17:23:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f785ca1898ac0e9cb293b433dbffdf990e2021d3",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.9.0",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-05-02T16:39:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9164cc4bc566214ff6a4f3c5bbe80948b9d1f550",
          "body": "Three OxNamespaceTest collision tests fail intermittently on TruffleRuby\nwhen run in the full suite. The handler hash ends up empty\n(`{\"root\" => {}}`) which post-typecast collapses to `{\"root\" => nil}`,\nbreaking the assertion.\n\nRoot cause is TruffleRuby's JIT, not Ox: when earlier tests in the\nproce\n[…]\n_handling_test.rb to match the existing\nskip in parser_integration_test.rb, and filter `lib/multi_xml/parsers/ox.rb`\nfrom coverage on TruffleRuby so the missing lines don't trip the\nSimpleCov minimum.",
          "is_bot": false,
          "headline": "Skip Ox tests on TruffleRuby",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-05-02T16:39:56Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d4887e322b9f7fadf26ad8fed0630180b8aa2d44",
          "body": "The previous table reported absolute throughput numbers from a\nsingle MRI run, which went stale on every benchmark refresh and\ntold readers nothing about JRuby or TruffleRuby. The new table\nshows the actual PARSER_PREFERENCE ordering on each supported\nruntime, surfacing the TruffleRuby flip (rexml ahead of oga,\nnokogiri last) that the engine-specific constant encodes. CI\nkeeps it honest by failing if the observed ranking diverges.",
          "is_bot": false,
          "headline": "Replace benchmark scores in README with per-engine preference table",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-30T17:58:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "af45aad809b6b088878de9ee88c8959a4672d7d3",
          "body": "Adjacent parsers in PARSER_PREFERENCE whose observed throughput is\nwithin 10% of each other are now treated as tied, so a noisy run\nthat flips a close pair (oga vs nokogiri on TruffleRuby is 4% apart)\nno longer fails the check. Real ordering bugs -- e.g. preferring\nrexml over oga on MRI, where the g\n[…]\n Pairwise tolerance check on adjacent\npositions catches transitive violations too: if A > B > C in\npreference but actual scores have C significantly above A, the\nadjacent A-B or B-C check picks it up.",
          "is_bot": false,
          "headline": "Tolerate noise in PARSER_PREFERENCE verifier",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-30T17:37:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d6f805eabb3ca0550642292aa6368502e8d0da15",
          "body": "TruffleRuby's JIT inverts the FFI-vs-pure-Ruby tradeoff: rexml jumps\nto the head of auto-detection (after ox, which is filtered out by\nskip_on_platform?) and nokogiri falls to last. Pin a TruffleRuby\nordering of rexml > libxml > oga > nokogiri behind a RUBY_ENGINE\ncheck so the verifier passes on all\n[…]\nocov:) wrap the conditional because the\nunreachable branch on a given engine would otherwise drop branch\ncoverage below the 100% MRI threshold.\n\nAlso adds truffleruby to the benchmark workflow matrix.",
          "is_bot": false,
          "headline": "Add TruffleRuby-specific PARSER_PREFERENCE",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-30T17:37:36Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "41430029f529cd8c0d50539614ce9ae2f466f57e",
          "body": "Adds jruby-10.0 to the benchmark workflow matrix. JRuby's available\nparser set (no ox/libxml; oga crashes on JRuby 10) shrinks the\nfiltered comparison to nokogiri vs rexml, which still matches\nPARSER_PREFERENCE -- so a single shared constant works for both\nruntimes.",
          "is_bot": false,
          "headline": "Verify PARSER_PREFERENCE on JRuby in addition to MRI",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-30T16:22:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d77088470f9822e503e7e2e7fa60740e95c9c89b",
          "body": "Adds a --verify-preference flag to benchmark.rb and a CI workflow\nthat runs the benchmark and asserts the throughput ranking, filtered\nto parsers in MultiXML::PARSER_PREFERENCE, matches the constant's\norder. Missing parsers (e.g. ox unavailable on JRuby) are tolerated.\nThe check pins to ubuntu-latest + Ruby 4.0 since benchmark numbers\naren't comparable across runtimes.",
          "is_bot": false,
          "headline": "Verify PARSER_PREFERENCE matches benchmark ranking in CI",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-30T16:20:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "182fa34e5b7635c5cfac07e45b1ee7e99da190b2",
          "body": "Swap oga ahead of rexml so the constant's \"fastest first\" promise is\nhonest: oga (0.168) outperforms rexml (0.117) on the bundled\nbenchmark suite. Affects auto-detection only when none of ox,\nlibxml-ruby, or nokogiri are installed; explicit parser selection\nis unchanged.",
          "is_bot": false,
          "headline": "Reorder PARSER_PREFERENCE to match benchmark throughput",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-30T16:20:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8b1c84bb317c26cf573f30ec1a597b5058dd878b",
          "body": "Re-ran the suite on Ruby 4.0 / Apple Silicon. libxml edges past\nnokogiri_sax for the #2 slot; other relative positions unchanged.\nAlso drops the \":parsers\" namespace from the rake invocation to\nmatch the renamed task.",
          "is_bot": false,
          "headline": "Refresh benchmark ranking table in README",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-30T16:20:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c0e7e1c294853120f6dd4c0551bd2daf609f7aa",
          "body": "Drops the namespace and the alias since there's only one benchmark\ntask. Invocation simplifies to \"rake benchmark\"; BENCHMARK_ARGS still\nforwards to benchmark.rb.",
          "is_bot": false,
          "headline": "Promote benchmark:parsers to a top-level rake benchmark task",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-30T16:06:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b4c127d42f7ccdb4ea747014f34dc5874134cb4f",
          "body": "Oga's Java backend crashes on JRuby 10 with java.lang.NoSuchMethodError,\nwhich extends java.lang.Error and bypasses StandardError rescues --\naborting the whole benchmark instead of letting the parser get excluded.\n\nCatch Java::JavaLang::Throwable alongside StandardError on JRuby so the\nexisting excluded-parsers path handles backend incompatibilities the\nsame way it handles output mismatches and Ruby exceptions.",
          "is_bot": false,
          "headline": "Skip JRuby-incompatible parsers in benchmark validation",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-30T16:01:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fe000beffa239b20e0e8ab982c706adca67ccc13",
          "body": null,
          "is_bot": false,
          "headline": "Add regression test for mixed-content inline text",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-29T01:18:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6e14d5bb7cd25f9d01915b498a58c2795308d4cf",
          "body": null,
          "is_bot": false,
          "headline": "Add parser benchmark and document benchmark ranking",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-29T01:18:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "15265c39ebc5d790ffbd36816f78fdb95fdb9057",
          "body": null,
          "is_bot": false,
          "headline": "Fix Ox mixed-content text aggregation in SAX parser",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-29T01:18:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9343839f5464ff5771cd760be02c7dc7e68f1dfb",
          "body": "Add a shared Parser mixin that reads the ParseError constant off the\nextending module via const_get with inherit: false (so stray top-level\n::ParseError doesn't leak through). Every built-in parser extends it\nand declares its backend exception class as ParseError, matching the\nMultiJSON::Adapter convention.\n\nCustom parsers can either extend Parser + define a ParseError constant\nor keep defining a .parse_error method directly; validate_parser!\naccepts both styles.",
          "is_bot": false,
          "headline": "Introduce MultiXML::Parser base module with ParseError constant",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-29T01:18:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "bc34f7e2ac5b0160b23f34d293489a415aafb1be",
          "body": "Raised when the parser spec is invalid, requiring the parser file\nraises LoadError, or the resolved parser doesn't satisfy the contract\n(must respond to .parse and define either a ParseError constant or a\n.parse_error method). Inherits from ArgumentError and carries the\noriginal exception's class name in its message, matching the role of\nMultiJSON::AdapterError.",
          "is_bot": false,
          "headline": "Add MultiXML::ParserLoadError for parser selection failures",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-29T01:18:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ba338d40718d79e06c2b28b817b82361eeec16a6",
          "body": "Introduce process-wide default options that merge between DEFAULT_OPTIONS\nand call-site overrides. Accepts a Hash or a callable (Proc/lambda); a\ncallable receives the call-site hash as its sole positional argument so\ndefaults can be computed per-call. Matches MultiJSON.parse_options.",
          "is_bot": false,
          "headline": "Add MultiXML.parse_options / .parse_options= for global defaults",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-29T01:18:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e76301065c24699a656e37d541f9008e64fea4c4",
          "body": "The override lives in Fiber[:multi_xml_parser] so concurrent fibers\nand threads each see their own parser without racing on a shared\nmodule variable; nested calls save and restore the previous\nfiber-local value. Matches MultiJSON.with_adapter.",
          "is_bot": false,
          "headline": "Add MultiXML.with_parser for fiber-local scoped overrides",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-29T01:18:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a5c53bbdb46eef4e37b48cd1156c3a413c62478f",
          "body": "Add JRuby 10.0 and TruffleRuby 33.0 (native and JVM) to the CI matrix,\nmatching the test coverage of MultiJSON. TruffleRuby is\nexcluded from Windows runners since the setup-ruby action doesn't\nsupport it there.",
          "is_bot": false,
          "headline": "Test against JRuby and TruffleRuby",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-29T01:18:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5aa5fcbe80290935d05921c2c34dff0bbf2e3fb5",
          "body": "Match Ruby stdlib's JSON.parse and MultiJSON. The\nlegacy :symbolize_keys option continues to work and emits a one-time\ndeprecation warning; it will be removed in 1.0. When both names appear\ntogether, :symbolize_names wins and :symbolize_keys is silently dropped.",
          "is_bot": false,
          "headline": "Rename :symbolize_keys option to :symbolize_names",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T20:06:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ce00fa7bb4581ef1b8048e605c32c9c2a822a2df",
          "body": "Adopt the MultiJSON README layout: CI badges, intro paragraph, minimal\nusage example, error-handling block, deprecation table for 0.9.0, and\ncustom-parser section. Drop the \"Drop-in replacement for stdlib\" and\n\"Gem Variants\" sections since neither applies to MultiXML.",
          "is_bot": false,
          "headline": "Restructure README to match MultiJSON",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T20:06:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "da358245bfbd3957a7e9466ecc648b0f6f5cf0cf",
          "body": "Match the MultiJSON.load → MultiJSON.parse convention. MultiXML.load\ncontinues to work and emits a one-time deprecation warning; it will\nbe removed in 1.0.",
          "is_bot": false,
          "headline": "Add a deprecated load alias for parse",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T20:06:59Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9099c3336a703ab942ee356a8f1a0456003fb50f",
          "body": "Use the all-caps acronym matching sister library MultiJSON. The legacy\nMultiXml constant continues to resolve via method_missing and\nconst_missing with a one-time deprecation warning, so every existing\ncall site keeps working through the 0.x line.",
          "is_bot": false,
          "headline": "Rename MultiXml to MultiXML and deprecate MultiXml",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T18:05:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2dee313b83db33b071cd4eb21585a7f5793a8bd7",
          "body": "When attributes with different namespace prefixes strip to the same\nlocal name (e.g. `foo:id` and `bar:id` both become `id`), collect their\nvalues in an array while preserving document order and keeping attribute\nvalues ahead of any colliding child elements. The libxml SAX parser\nfalls back to the DOM backend in this case since its callback drops\nprefixes from attribute qnames.",
          "is_bot": false,
          "headline": "Handle namespaced attribute name collisions consistently",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T18:04:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f0eab96d04f223bf17b21443ec033dcd760a8b1b",
          "body": null,
          "is_bot": false,
          "headline": "Fix parser detection",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T18:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ae0e9d109287cc7e62c140985305399fadcc9579",
          "body": null,
          "is_bot": false,
          "headline": "Harden namespace parsing and extract parse helpers",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T18:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c1313ea794518831253ec33e320c403f352715b",
          "body": "Add a :namespaces option to MultiXml.parse that makes every backend\nproduce byte-identical output:\n\n* :strip (default) — drop xmlns declarations and prefixes, matching\n  today's libxml/nokogiri behavior\n* :preserve — keep source prefixes (\"atom:rel\") and xmlns decls",
          "is_bot": false,
          "headline": "Fix inconsistent namespace handling across parsers",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T18:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d930a0fe3545b342e934764e168a19c3349118f",
          "body": null,
          "is_bot": false,
          "headline": "Ignore .mutant directory",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T18:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "27fd3bb59f79a0f746256afa041d03b890fa14a6",
          "body": "libxml-ruby 6.0.0 removed the deprecated `libxml.rb` shim, so\n`require \"libxml\"` now raises LoadError. Switch to the canonical\n`require \"libxml-ruby\"`, which is present in both 5.x and 6.x.\n\nAlso bump steep to >= 2 so CI resolves against rbs 4.x.",
          "is_bot": false,
          "headline": "Support libxml-ruby 6.0.0",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T18:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "11dba85e7d051623d770915a61f25927abd93a3f",
          "body": "```\nFinished in 0.050951s, 12600.3415 runs/s, 18586.4851 assertions/s.\n\n  1) Error:\nLoadParserCamelizeTest#test_load_parser_handles_underscore_names:\nLoadError: cannot load such file -- libxml\n    /Users/sue445/.rbenv/versions/4.0.2/lib/ruby/4.0.0/bundled_gems.rb:60:in 'Kernel.require'\n    /Users/su\n[…]\n_xml.rb:110:in 'MultiXml.load_parser'\n    test/load_parser_test.rb:56:in 'LoadParserCamelizeTest#test_load_parser_handles_underscore_names'\n\n642 runs, 947 assertions, 0 failures, 1 errors, 0 skips\n```",
          "is_bot": false,
          "headline": "Fix error with libxml-ruby 6.0.0",
          "author_name": "sue445",
          "author_login": "sue445",
          "committed_at": "2026-04-28T18:04:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "32d0dc255b22bbfb4318d02699950181490ca552",
          "body": "…ith rbs v4\n\n```\nlib/multi_xml/errors.rb:1:0: [error] Type checking failed due to error in library RBS file\n│ Different superclasses are specified for `::Psych::SyntaxError`\n│ (/Users/sue445/workspace/github.com/sferik/multi_xml/vendor/bundle/ruby/4.0.0/gems/rbs-4.0.2/stdlib/psych/0/psych.rbs:434:2)\n│\n│ Diagnostic ID: Ruby::LibraryRBSError\n│\n└ module MultiXml\n  ~~~~~~~~~~~~~~~\n```",
          "is_bot": false,
          "headline": "Fix Different superclasses are specified for `::Psych::SyntaxError` w…",
          "author_name": "sue445",
          "author_login": "sue445",
          "committed_at": "2026-04-28T18:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c4aee68fe0a7b55950033302fb7ca2a643dca99f",
          "body": null,
          "is_bot": false,
          "headline": "Test on Ruby 4.0",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-04-28T18:04:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c016f910f3fb35dcb050d7a5393b1773bae44bc0",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.8.1",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-01-08T14:39:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7c8977fb78590930359fae0e5082a821aa342d06",
          "body": "Closes https://github.com/sferik/multi_xml/issues/73.",
          "is_bot": false,
          "headline": "Fix array unwrapping when elements contain nil",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-01-08T06:38:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "75ea04280c5f4294a0e409fef5d3c3767148234e",
          "body": null,
          "is_bot": false,
          "headline": "Update to Minitest 6",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2026-01-06T04:26:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "df3bcded2db18c5d2eb961c393860f7ab02f07a6",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.8.0",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T14:09:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d87b8f0e2dfa4d08276b671ef68b13aa5c8f71d",
          "body": null,
          "is_bot": false,
          "headline": "Add push workflow and update release rake task",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T14:09:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cea6be3e3770dccab173d305bfacb97ed9050717",
          "body": null,
          "is_bot": false,
          "headline": "Document Ruby 4 support",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0a3bd225648181a32cdef85a75459de3ecbc761c",
          "body": null,
          "is_bot": false,
          "headline": "Refactor",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f5d3655f6d944968256ef4280f1b1a2d0286a2a6",
          "body": null,
          "is_bot": false,
          "headline": "Remove test skips",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e43f18848d90fe79fe4a33ad2eac94764ef0c2af",
          "body": null,
          "is_bot": false,
          "headline": "Increase branch coverage to 100%",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6811d856c0e30258b7290d8f0eb5c2fefeee34da",
          "body": null,
          "is_bot": false,
          "headline": "Fix tests on Windows",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eaa386cfef4ebb679e78118cb17f2ffb26a7d258",
          "body": null,
          "is_bot": false,
          "headline": "Drop support for JRuby",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eaaff8b9b5452598b6421f4d654e14d090b40c7f",
          "body": null,
          "is_bot": false,
          "headline": "Add type checking with RBS and Steep",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "49702d92a9ebc8e6584e5d24833c1d9ecd671268",
          "body": null,
          "is_bot": false,
          "headline": "More refactoring",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2a0ff51f426079b0a1baac363efa437baca1bf13",
          "body": null,
          "is_bot": false,
          "headline": "More test cleanup",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2cca440fc13daa0255af0f5743ed57973888e834",
          "body": null,
          "is_bot": false,
          "headline": "Kill remaining mutants",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61ef966dde3808ccbecbbca27e2d676f7a061e5d",
          "body": null,
          "is_bot": false,
          "headline": "Cleanup tests",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "be8df358efea132db3f1cc18518251e535c9c181",
          "body": null,
          "is_bot": false,
          "headline": "Kill mutants",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "18144f88b1bf1a2d639bdf2450d7397ce5ce45cb",
          "body": null,
          "is_bot": false,
          "headline": "Suppress oga warnings",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "661b419703cfe50b3d7f63431c91b6cacbab3a0d",
          "body": null,
          "is_bot": false,
          "headline": "Add mutant",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9fe7948112879b3d449be2bca2ef4194b73f09cd",
          "body": null,
          "is_bot": false,
          "headline": "100% c0 code coverage",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c58286849951cd2f6cac2d9b19d43104e165a520",
          "body": null,
          "is_bot": false,
          "headline": "Covert from RSpec to Minitest",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "885ff010de9a46218d93ce378e896268b208d0a9",
          "body": null,
          "is_bot": false,
          "headline": "100% documentation coverage",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "78a715f7232496ecbefde5ced529fadfc4a508e8",
          "body": null,
          "is_bot": false,
          "headline": "More refactoring",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5ac2c349a59651872bbcf4ae3a4d9b03fff5c06c",
          "body": null,
          "is_bot": false,
          "headline": "Extract modules and constants into separate files",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "156fc5c0b9be47285dca8084fc6bc3a7c2e5d75b",
          "body": null,
          "is_bot": false,
          "headline": "Update workflows",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2a78cb3f451851a9d78ddfa03ea2bf3834028ca8",
          "body": null,
          "is_bot": false,
          "headline": "Extract global variables into SpeedTest module",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "81c4fd8f3dbb1d2becdc328a3f862c64fde23b18",
          "body": null,
          "is_bot": false,
          "headline": "Replace @xml instance variables with let(:xml) declarations",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c3fadd0acaf28939e59b08285fbb7213564cd824",
          "body": null,
          "is_bot": false,
          "headline": "Refactor",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "6127e278a879391a247573cdd4abb4855421e26c",
          "body": null,
          "is_bot": false,
          "headline": "Refactor code into Helpers module",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e0530a935ad1677792ff1348c8faf6b3a73ca429",
          "body": null,
          "is_bot": false,
          "headline": "rake standard:fix",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "695729f7103305ed852da1efbb493504d5db773c",
          "body": "Resolves https://github.com/sferik/multi_xml/issues/32.",
          "is_bot": false,
          "headline": "Make parsing errors inspectable with cause and xml accessors",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ade3c5005ae76c4ca835186c25dac9c3a580e481",
          "body": "Previously, parsers handled whitespace-only content differently:\n  - nokogiri, libxml, oga: always stripped whitespace\n  - ox, rexml: always preserved whitespace\n\nNow all parsers have the same behavior:\n  - Empty elements return nil\n  - Whitespace-only content with no children/attributes is preserve\n[…]\n>\"        -> {\"tag\" => \" \"}\n    \"<tag> <child/></tag>\" -> {\"tag\" => {\"child\" => nil}}\n    \"<tag attr='x'> </tag>\" -> {\"tag\" => {\"attr\" => \"x\"}}\n\nResolves https://github.com/sferik/multi_xml/issues/46.",
          "is_bot": false,
          "headline": "Fix inconsistent whitespace handling across parsers",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "663ac9d3325146ca5306c5db1ff4d33ac55d65e8",
          "body": "Use top-level constant references (::Ox, ::LibXML, etc.) in the\n`defined?` checks to ensure we check for the actual gem constants rather\nthan the local parser module constants.\n\nPreviously, `defined?(Ox)` inside `MultiXml::Parsers::Ox` would find the\nparser module itself due to Ruby's constant looku\n[…]\nn't loaded. This\nresulted in \"undefined method `sax_parse' for Ox:Module\" errors in\nmultithreaded environments or when the gem wasn't preloaded.\n\nResolve https://github.com/sferik/multi_xml/issues/53.",
          "is_bot": false,
          "headline": "Fix constant lookup in parser require guards",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5dc70562a003eb7f621eeb46770090ec8255a3ed",
          "body": "Implement experimental event-driven SAX parsing alternatives to the\nexisting DOM-based parsers. SAX parsing can be more memory-efficient for\nlarge XML documents since it doesn't build the entire DOM tree in memory.\n\nUsage:\n    MultiXml.parser = :nokogiri_sax  # Uses Nokogiri::XML::SAX::Parser\n    Mu\n[…]\nracter references that\n    SAX parsers return differently than DOM parsers\n  - Both parsers properly raise MultiXml::ParseError for invalid XML\n\nResolves https://github.com/sferik/multi_xml/issues/10.",
          "is_bot": false,
          "headline": "Add SAX parsers for Nokogiri and LibXML",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c7f532af83963beb0204fcc5a4419cb1fdcbbe82",
          "body": null,
          "is_bot": false,
          "headline": "Change bigdecimal dependency to >= 3.1, < 5",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-24T13:10:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f5929bd870a94c7b9ee7cb99d4cfd33d87ca05a7",
          "body": "This reverts commit ecc425a26b5c2108732dfbf7d68e82cd7e16aec9.",
          "is_bot": false,
          "headline": "Revert \"Pass symbol as an argument to proc instead of a block\"",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-20T16:22:03Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c94bbfa4722f0356c111cc313baa8449817c31ae",
          "body": "Allow specifying a parser for individual parse operations via the\n:parser option, enabling use of different parsers in the same\napplication without changing the class-level setting.\n\nThe option accepts symbols, strings, or parser modules, consistent with\nthe existing MultiXml.parser= API.\n\nResolves https://github.com/sferik/multi_xml/issues/63.",
          "is_bot": false,
          "headline": "Add per-parse :parser option to MultiXml.parse",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-20T07:32:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ecc425a26b5c2108732dfbf7d68e82cd7e16aec9",
          "body": null,
          "is_bot": false,
          "headline": "Pass symbol as an argument to proc instead of a block",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-20T06:37:56Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8beccc67a578e2fc6ee269bbf464f425621ba9de",
          "body": "Resolves https://github.com/sferik/multi_xml/issues/72.",
          "is_bot": false,
          "headline": "Update bigdecimal depdnency to ~> 4.0",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-12-20T06:36:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "338107755fab44ef425225a03d5bc2b0640e436d",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.7.2",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-04-30T18:30:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "120fef648e702b903109eb001ef78c22585da616",
          "body": null,
          "is_bot": false,
          "headline": "Update CI workflow",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-04-29T20:57:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7946028f70d4b41bfc967e3fdf3ec0e8f882ba7e",
          "body": null,
          "is_bot": false,
          "headline": "Update LICENSE and README",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-04-29T20:03:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "00b3fca87f1eaa2cb3caefa1553684203278679d",
          "body": null,
          "is_bot": false,
          "headline": "Add metadata hash",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-04-29T20:03:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f7708e14c9e8fda165d5172d110d2c2e708520ea",
          "body": null,
          "is_bot": false,
          "headline": "Drop support for Ruby 3.1",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-04-29T19:40:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "70dab39a5597a2ff5bd535b0c30b0ce892cf9db3",
          "body": null,
          "is_bot": false,
          "headline": "Use add_dependency instead of add_runtime_dependency",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-04-29T19:37:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4951afefae166bfbff2a35fd276abbfc41eeb693",
          "body": null,
          "is_bot": false,
          "headline": "Specify plugins instead of require",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2025-04-29T19:32:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "854e26c603972ecf9898b99e7092a69fe619d6c9",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.7.1",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-05-01T18:50:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d81665f1ce7cd1cad07cfab3f19a679c4fdad002",
          "body": "…n stable\n\nSee discussion at https://github.com/sferik/multi_xml/commit/712cf97da3e6385179214644452cb7775d14e7d8#r141554010.",
          "is_bot": false,
          "headline": "Relax required Ruby version constraint to allow installation on Debia…",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-05-01T18:49:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1a2cde755452773aced4a870ff963a181a14381a",
          "body": null,
          "is_bot": false,
          "headline": "Bump version to 0.7.0",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-04-30T19:08:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "2b7e1637f800014bb7eaee6ed7dbffb5e08fa938",
          "body": null,
          "is_bot": false,
          "headline": "Add bin for development",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-04-30T19:00:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "712cf97da3e6385179214644452cb7775d14e7d8",
          "body": null,
          "is_bot": false,
          "headline": "Drop support for Ruby 3.0",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-04-30T18:59:32Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a2be7ce1ca13eb4b37d8ac88f6cbb893f18eccd2",
          "body": null,
          "is_bot": false,
          "headline": "Update runtime dependency in gemspec",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-04-30T18:59:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "86fdc12fa4a4e2a588abb768589703fe6e7e2f38",
          "body": null,
          "is_bot": false,
          "headline": "Update development dependencies in Gemfile",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-04-30T18:59:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1659443ea2659e7539e8bca2797dc3670e065985",
          "body": null,
          "is_bot": false,
          "headline": "Clean up code",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-04-30T18:59:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0b832249e270db9cd957d1a2e7c978400f4db960",
          "body": null,
          "is_bot": false,
          "headline": "Update copyright year",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-04-30T18:59:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b79adf03a93a4bb7cead2ab0752f54addad9c5df",
          "body": null,
          "is_bot": false,
          "headline": "Update name",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-04-30T18:59:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d7ea5225f3e10c2aeb95e6d24235c6de1487cff2",
          "body": null,
          "is_bot": false,
          "headline": "Clean up code",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-04-30T18:37:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f2ea10a7acedc044398d3ad11586b87dfb54d1ad",
          "body": null,
          "is_bot": false,
          "headline": "Use parentheses for super with arguments",
          "author_name": "Erik Berlin",
          "author_login": "sferik",
          "committed_at": "2024-04-30T18:33:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "54ff3221d241819d0183985494ef63126319f407",
          "body": null,
          "is_bot": false,
          "headline": "Add ruby 3.3 to CI",
          "author_name": "Earlopain",
          "author_login": "Earlopain",
          "committed_at": "2024-04-30T18:29:02Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 1,
      "commits_last_year": 80,
      "latest_release_at": "2026-05-04T18:32:52Z",
      "latest_release_tag": "v0.9.1",
      "releases_from_tags": false,
      "days_since_last_push": 8,
      "active_weeks_last_year": 9,
      "days_since_latest_release": 78,
      "mean_days_between_releases": null
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 57,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "multi_xml",
          "exists": true,
          "license": "MIT",
          "keywords": [],
          "ecosystem": "rubygems",
          "matches_repo": true,
          "registry_url": "https://rubygems.org/gems/multi_xml",
          "is_deprecated": false,
          "latest_version": "0.9.1",
          "repository_url": "https://github.com/sferik/multi_xml",
          "versions_count": 29,
          "total_downloads": 583709139,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": null,
          "monthly_downloads": null,
          "first_published_at": "2010-10-03T05:57:04.117000Z",
          "latest_published_at": "2026-05-04T18:32:12.994000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 78
        }
      ]
    },
    "popularity": {
      "forks": 38,
      "stars": 172,
      "watchers": 4,
      "fork_history": {
        "days": [
          {
            "date": "2010-10-04",
            "count": 1
          },
          {
            "date": "2011-06-05",
            "count": 1
          },
          {
            "date": "2011-08-24",
            "count": 1
          },
          {
            "date": "2011-12-30",
            "count": 1
          },
          {
            "date": "2012-04-16",
            "count": 1
          },
          {
            "date": "2012-05-08",
            "count": 1
          },
          {
            "date": "2013-01-11",
            "count": 1
          },
          {
            "date": "2013-05-31",
            "count": 1
          },
          {
            "date": "2013-07-02",
            "count": 1
          },
          {
            "date": "2013-07-08",
            "count": 1
          },
          {
            "date": "2013-07-12",
            "count": 1
          },
          {
            "date": "2013-08-14",
            "count": 1
          },
          {
            "date": "2013-09-02",
            "count": 1
          },
          {
            "date": "2013-12-27",
            "count": 1
          },
          {
            "date": "2014-02-10",
            "count": 1
          },
          {
            "date": "2015-02-10",
            "count": 1
          },
          {
            "date": "2015-02-14",
            "count": 1
          },
          {
            "date": "2015-06-18",
            "count": 1
          },
          {
            "date": "2015-10-16",
            "count": 1
          },
          {
            "date": "2015-11-02",
            "count": 1
          },
          {
            "date": "2016-03-24",
            "count": 1
          },
          {
            "date": "2016-07-24",
            "count": 1
          },
          {
            "date": "2016-12-05",
            "count": 1
          },
          {
            "date": "2017-04-06",
            "count": 1
          },
          {
            "date": "2017-05-18",
            "count": 1
          },
          {
            "date": "2017-06-22",
            "count": 1
          },
          {
            "date": "2019-02-01",
            "count": 1
          },
          {
            "date": "2019-03-04",
            "count": 1
          },
          {
            "date": "2020-07-28",
            "count": 1
          },
          {
            "date": "2021-01-12",
            "count": 1
          },
          {
            "date": "2022-02-12",
            "count": 1
          },
          {
            "date": "2023-06-02",
            "count": 1
          },
          {
            "date": "2024-01-02",
            "count": 1
          },
          {
            "date": "2024-02-13",
            "count": 1
          },
          {
            "date": "2024-05-11",
            "count": 1
          },
          {
            "date": "2024-06-09",
            "count": 1
          },
          {
            "date": "2026-04-17",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 37,
        "total_forks": 38
      },
      "star_history": {
        "days": [
          {
            "date": "2010-10-03",
            "count": 52
          },
          {
            "date": "2010-10-05",
            "count": 2
          },
          {
            "date": "2011-03-10",
            "count": 1
          },
          {
            "date": "2011-06-13",
            "count": 1
          },
          {
            "date": "2011-06-20",
            "count": 1
          },
          {
            "date": "2011-06-29",
            "count": 1
          },
          {
            "date": "2013-02-20",
            "count": 1
          },
          {
            "date": "2013-03-07",
            "count": 1
          },
          {
            "date": "2013-03-09",
            "count": 1
          },
          {
            "date": "2013-04-18",
            "count": 1
          },
          {
            "date": "2013-04-20",
            "count": 1
          },
          {
            "date": "2013-04-22",
            "count": 1
          },
          {
            "date": "2013-06-10",
            "count": 1
          },
          {
            "date": "2013-06-17",
            "count": 1
          },
          {
            "date": "2013-06-27",
            "count": 1
          },
          {
            "date": "2013-07-04",
            "count": 1
          },
          {
            "date": "2013-07-08",
            "count": 1
          },
          {
            "date": "2013-10-01",
            "count": 1
          },
          {
            "date": "2013-10-12",
            "count": 1
          },
          {
            "date": "2013-10-30",
            "count": 1
          },
          {
            "date": "2013-11-14",
            "count": 1
          },
          {
            "date": "2014-01-01",
            "count": 1
          },
          {
            "date": "2014-01-03",
            "count": 1
          },
          {
            "date": "2014-01-08",
            "count": 1
          },
          {
            "date": "2014-04-03",
            "count": 1
          },
          {
            "date": "2014-04-17",
            "count": 1
          },
          {
            "date": "2014-04-20",
            "count": 1
          },
          {
            "date": "2014-04-23",
            "count": 1
          },
          {
            "date": "2014-06-07",
            "count": 1
          },
          {
            "date": "2014-07-21",
            "count": 1
          },
          {
            "date": "2014-07-31",
            "count": 1
          },
          {
            "date": "2014-08-01",
            "count": 1
          },
          {
            "date": "2014-08-31",
            "count": 1
          },
          {
            "date": "2014-09-01",
            "count": 1
          },
          {
            "date": "2014-09-24",
            "count": 1
          },
          {
            "date": "2014-11-21",
            "count": 1
          },
          {
            "date": "2014-12-19",
            "count": 1
          },
          {
            "date": "2015-02-07",
            "count": 1
          },
          {
            "date": "2015-03-04",
            "count": 1
          },
          {
            "date": "2015-05-19",
            "count": 1
          },
          {
            "date": "2015-07-23",
            "count": 1
          },
          {
            "date": "2015-08-08",
            "count": 1
          },
          {
            "date": "2015-08-11",
            "count": 1
          },
          {
            "date": "2015-09-21",
            "count": 1
          },
          {
            "date": "2015-10-15",
            "count": 1
          },
          {
            "date": "2015-11-05",
            "count": 1
          },
          {
            "date": "2015-11-09",
            "count": 2
          },
          {
            "date": "2015-11-24",
            "count": 1
          },
          {
            "date": "2015-12-21",
            "count": 1
          },
          {
            "date": "2016-02-18",
            "count": 1
          },
          {
            "date": "2016-02-26",
            "count": 2
          },
          {
            "date": "2016-03-11",
            "count": 1
          },
          {
            "date": "2016-04-06",
            "count": 1
          },
          {
            "date": "2016-04-15",
            "count": 1
          },
          {
            "date": "2016-06-26",
            "count": 1
          },
          {
            "date": "2016-07-20",
            "count": 2
          },
          {
            "date": "2016-08-10",
            "count": 1
          },
          {
            "date": "2016-08-16",
            "count": 1
          },
          {
            "date": "2016-09-28",
            "count": 1
          },
          {
            "date": "2016-11-04",
            "count": 1
          },
          {
            "date": "2016-12-11",
            "count": 1
          },
          {
            "date": "2016-12-19",
            "count": 1
          },
          {
            "date": "2017-02-27",
            "count": 1
          },
          {
            "date": "2017-03-09",
            "count": 1
          },
          {
            "date": "2017-04-03",
            "count": 1
          },
          {
            "date": "2017-04-08",
            "count": 1
          },
          {
            "date": "2017-04-10",
            "count": 1
          },
          {
            "date": "2017-05-17",
            "count": 1
          },
          {
            "date": "2017-06-16",
            "count": 1
          },
          {
            "date": "2017-06-27",
            "count": 1
          },
          {
            "date": "2017-07-27",
            "count": 1
          },
          {
            "date": "2017-10-04",
            "count": 1
          },
          {
            "date": "2017-12-23",
            "count": 1
          },
          {
            "date": "2018-02-12",
            "count": 1
          },
          {
            "date": "2018-02-16",
            "count": 1
          },
          {
            "date": "2018-02-26",
            "count": 1
          },
          {
            "date": "2018-04-28",
            "count": 1
          },
          {
            "date": "2018-06-20",
            "count": 1
          },
          {
            "date": "2018-08-03",
            "count": 1
          },
          {
            "date": "2018-10-03",
            "count": 1
          },
          {
            "date": "2018-11-06",
            "count": 1
          },
          {
            "date": "2019-01-09",
            "count": 1
          },
          {
            "date": "2019-02-01",
            "count": 1
          },
          {
            "date": "2019-03-07",
            "count": 1
          },
          {
            "date": "2019-03-31",
            "count": 1
          },
          {
            "date": "2019-05-17",
            "count": 1
          },
          {
            "date": "2019-07-10",
            "count": 1
          },
          {
            "date": "2019-08-11",
            "count": 1
          },
          {
            "date": "2020-02-19",
            "count": 1
          },
          {
            "date": "2020-06-16",
            "count": 1
          },
          {
            "date": "2020-07-22",
            "count": 1
          },
          {
            "date": "2020-08-29",
            "count": 1
          },
          {
            "date": "2022-01-31",
            "count": 1
          },
          {
            "date": "2023-06-02",
            "count": 1
          },
          {
            "date": "2023-06-24",
            "count": 1
          },
          {
            "date": "2024-05-02",
            "count": 1
          },
          {
            "date": "2024-05-12",
            "count": 1
          },
          {
            "date": "2024-05-13",
            "count": 1
          },
          {
            "date": "2024-05-14",
            "count": 1
          },
          {
            "date": "2024-12-18",
            "count": 1
          },
          {
            "date": "2025-06-15",
            "count": 1
          },
          {
            "date": "2025-10-03",
            "count": 1
          },
          {
            "date": "2025-12-25",
            "count": 1
          },
          {
            "date": "2026-01-15",
            "count": 1
          },
          {
            "date": "2026-02-10",
            "count": 1
          },
          {
            "date": "2026-04-21",
            "count": 1
          },
          {
            "date": "2026-05-23",
            "count": 2
          },
          {
            "date": "2026-05-24",
            "count": 1
          },
          {
            "date": "2026-05-25",
            "count": 7
          },
          {
            "date": "2026-05-30",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 172,
        "total_stars": 172
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [],
      "toolchain_manifests": [],
      "largest_source_bytes": 30160,
      "source_files_sampled": 80,
      "oversized_source_files": 0,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "Gemfile"
      ],
      "advisories": {
        "error": "No resolved dependencies carried a version and a supported ecosystem",
        "scope": "repository_graph",
        "source": null,
        "findings": [],
        "collected": false,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 0,
        "malicious_count": 0,
        "assessed_package": null,
        "unassessed_count": 22,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "rubygems"
      ],
      "dependencies": [
        {
          "name": "libxml-ruby",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": null
        },
        {
          "name": "nokogiri",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": null
        },
        {
          "name": "oga",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 2.3"
        },
        {
          "name": "ox",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": null
        },
        {
          "name": "rexml",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": null
        },
        {
          "name": "minitest",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 6"
        },
        {
          "name": "minitest-mock",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 5.27"
        },
        {
          "name": "mutant-minitest",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 0.14.1"
        },
        {
          "name": "rake",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 13.3.1"
        },
        {
          "name": "rbs",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 4.0.0"
        },
        {
          "name": "rdoc",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 7.0.2"
        },
        {
          "name": "rdoc",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 7.0.2"
        },
        {
          "name": "rubocop",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 1.81.7"
        },
        {
          "name": "rubocop-minitest",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 0.36"
        },
        {
          "name": "rubocop-performance",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 1.26.1"
        },
        {
          "name": "rubocop-rake",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 0.7.1"
        },
        {
          "name": "simplecov",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 1"
        },
        {
          "name": "standard",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 1.52"
        },
        {
          "name": "standard-performance",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 1.9"
        },
        {
          "name": "steep",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 2"
        },
        {
          "name": "yard",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 0.9.38"
        },
        {
          "name": "yardstick",
          "manifest": "Gemfile",
          "ecosystem": "rubygems",
          "version_constraint": ">= 0.9.9"
        }
      ],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [
          {
            "name": "libxml-ruby",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "minitest",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "minitest-mock",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "mutant-minitest",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "nokogiri",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "oga",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "ox",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "rake",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "rbs",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "rdoc",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "rexml",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "rubocop",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "rubocop-minitest",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "rubocop-performance",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "rubocop-rake",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "simplecov",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "standard",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "standard-performance",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "steep",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "yard",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "yardstick",
            "direct": true,
            "version": null,
            "ecosystem": "rubygems"
          },
          {
            "name": "bigdecimal",
            "direct": false,
            "version": null,
            "ecosystem": "rubygems"
          }
        ],
        "collected": true,
        "truncated": false,
        "total_count": 22,
        "direct_count": 21,
        "indirect_count": 1
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 33,
        "open_issues": 0,
        "closed_ratio": 1,
        "closed_issues": 34,
        "closed_unmerged_prs": 8
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "sferik",
          "commits": 401,
          "avatar_url": "https://avatars.githubusercontent.com/u/10308?v=4"
        },
        {
          "type": "User",
          "login": "ohler55",
          "commits": 16,
          "avatar_url": "https://avatars.githubusercontent.com/u/118856?v=4"
        },
        {
          "type": "User",
          "login": "phiggins",
          "commits": 6,
          "avatar_url": "https://avatars.githubusercontent.com/u/22962?v=4"
        },
        {
          "type": "User",
          "login": "joshk",
          "commits": 4,
          "avatar_url": "https://avatars.githubusercontent.com/u/8701?v=4"
        },
        {
          "type": "User",
          "login": "Earlopain",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/14981592?v=4"
        },
        {
          "type": "User",
          "login": "hakanensari",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/31693?v=4"
        },
        {
          "type": "User",
          "login": "koic",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/13203?v=4"
        },
        {
          "type": "User",
          "login": "koraktor",
          "commits": 3,
          "avatar_url": "https://avatars.githubusercontent.com/u/66112?v=4"
        },
        {
          "type": "User",
          "login": "ka8725",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/243846?v=4"
        },
        {
          "type": "User",
          "login": "fisherwebdev",
          "commits": 2,
          "avatar_url": "https://avatars.githubusercontent.com/u/169760?v=4"
        }
      ],
      "contributors_sampled": 20,
      "top_contributor_share": 0.879
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "benchmark.yml",
        "docs.yml",
        "linter.yml",
        "mutant.yml",
        "push.yml",
        "tests.yml",
        "typecheck.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [
        ".rubocop.yml"
      ],
      "has_editorconfig": false,
      "has_linter_config": true,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": null,
            "reason": "no pull request found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/30 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 16 contributing companies or organizations",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 2 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": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 10,
            "reason": "0 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "391efee2f509a7afde833eee8315f0ec7f59f16b",
        "ran_at": "2026-07-22T01:58:58Z",
        "aggregate_score": 4.5,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-13T21:09:52Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-04-22T22:23:11Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/sferik/multi_xml",
    "host": "github.com",
    "name": "multi_xml",
    "owner": "sferik"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 65,
      "inputs": {
        "security": 45,
        "vitality": 71,
        "community": 70,
        "governance": 68,
        "engineering": 68
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 71,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 62,
            "inputs": {
              "commits_last_year": 80,
              "human_commit_share": 1,
              "days_since_last_push": 8,
              "active_weeks_last_year": 9
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 8 days ago",
                "points": 28.8,
                "status": "partial",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "9/52 weeks with commits",
                "points": 6.2,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 9
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "80 commits in the last year",
                "points": 17.1,
                "status": "partial",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 80
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "good",
            "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": 84,
            "inputs": {
              "releases_count": 1,
              "latest_release_tag": "v0.9.1",
              "releases_from_tags": false,
              "days_since_latest_release": 78,
              "mean_days_between_releases": null
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "1 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 78 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 78
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "cadence unknown (single release)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "release_cadence_unknown",
                    "params": {}
                  }
                ],
                "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": 8,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 8 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 8
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "good",
        "name": "Community & Adoption",
        "value": 70,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "moderate",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 52,
            "inputs": {
              "forks": 38,
              "stars": 172,
              "watchers": 4,
              "growth_state": "organic",
              "growth_factor_pct": 100
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "172 stars",
                "points": 36.2,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 172
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "38 forks",
                "points": 13.1,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 38
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "4 watchers",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 70,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "excellent",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "packages": [
                "multi_xml"
              ],
              "dependents": null,
              "ecosystems": "rubygems",
              "total_downloads": 583709139,
              "monthly_downloads": null
            },
            "components": [
              {
                "key": "total_downloads",
                "name": "Total downloads",
                "detail": "583,709,139 downloads all-time across rubygems",
                "points": 80,
                "status": "met",
                "details": [
                  {
                    "code": "downloads_total",
                    "params": {
                      "count": 583709139,
                      "ecosystems": "rubygems"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 68,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "at_risk",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 35,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 20,
              "top_contributor_share": 0.879
            },
            "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 88% of commits",
                "points": 2.7,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 88
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "20 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 20
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 16 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 78,
            "inputs": {
              "merged_prs": 33,
              "open_issues": 0,
              "closed_issues": 34,
              "issue_closed_ratio": 1,
              "closed_unmerged_prs": 8
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "100% of issues closed",
                "points": 46.8,
                "status": "met",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "33/41 decided PRs merged",
                "points": 30.8,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 33,
                      "decided": 41
                    }
                  }
                ],
                "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": "good",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 74,
            "inputs": {
              "followers": 2649,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "sferik",
              "public_repos": 216,
              "account_age_days": 6642
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "2,649 followers of sferik",
                "points": 24.6,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 2649,
                      "login": "sferik"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "216 public repos, account ~18 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 216
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 18
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "multi_xml"
              ],
              "ecosystems": "rubygems",
              "any_deprecated": false,
              "min_days_since_publish": 78
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on rubygems",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "rubygems"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 78 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 78
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "29 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 29
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 68,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_ci_tests"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 80,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": true,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "7 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 7
                    }
                  }
                ],
                "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": ".rubocop.yml",
                "points": 16,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".rubocop.yml"
                    }
                  }
                ],
                "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": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": false,
              "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": 0,
                "status": "missed",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 45,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "at_risk",
            "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": 45,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 4.5
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection 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 16 contributing companies or organizations",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 2 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 not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "0 existing vulnerabilities detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "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": 20
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "at_risk",
        "name": "AI Readiness",
        "value": 32,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "critical",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 18,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.34,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "34 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 18.1,
                "status": "partial",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 34,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "at_risk",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 33,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": false,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": true,
              "typecheck_configs": [],
              "agent_commit_share": 0,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": ".rubocop.yml",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": ".rubocop.yml"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "no agent-authored commits among the last 100",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_authored_commits",
                    "params": {
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "moderate",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "primary_language": "Ruby",
              "largest_source_bytes": 30160,
              "source_files_sampled": 80,
              "oversized_source_files": 0
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Ruby without a type-check config",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_typecheck_config_language",
                    "params": {
                      "language": "Ruby"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "0/80 source files over 60KB",
                "points": 55,
                "status": "met",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 80,
                      "oversized": 0
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "No resolved dependencies carried a version and a supported ecosystem"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-22T01:59:09.869304Z",
  "schema_version": "0.26.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/s/sferik/multi_xml.svg",
  "full_name": "sferik/multi_xml",
  "license_state": "standard",
  "license_spdx": "MIT"
}

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

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

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