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

openrewrite / rewrite-migrate-java

OpenRewrite recipes for migrating to newer versions of Java.

JavaLicencia propia★ 153 estrellas⑂ 123 forksdesde mar 2021Ver en GitHub ↗

openrewrite/rewrite-migrate-java tiene un índice de salud de 74 sobre 100, lo que lo sitúa en la banda Bueno. Su puntuación más alta es Vitality (100/100) y la más baja, Security (53/100). Se actualizó por última vez hoy. 4 personas concentran la mayor parte del trabajo reciente.

74
global / 100
Bueno

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

74
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

OpenRewriteOrganización
984 seguidores75 repositorios públicosdesde feb 2020

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

Métricas por categoría

Vitalidad

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

100Excelente · 22% del índice global
Cómo se puntúa
36/36Recencia de push — último push hace 0 días
36/36Cadencia de commits — 52/52 semanas con commits
18/18Volumen de commits — 411 commits en el último año
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 19 issue activity found in the last 90 days -- score normalized to 10
Datos de entrada utilizados
commits_last_year411
human_commit_share0,91
days_since_last_push0
active_weeks_last_year52
Cómo se puntúa
27/27Publica versiones — 100 versiones publicadas
36/36Recencia de las versiones — última versión hace 11 días
27/27Cadencia de publicación — una versión cada ~9,3 días
0/10OpenSSF Scorecard: Signed-Releases — sin datos
Datos de entrada utilizados
releases_count100
latest_release_tagv3.40.0
releases_from_tagsno
days_since_latest_release11
mean_days_between_releases9,3
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?

64Moderado · 18% del índice global
Cómo se puntúa
35.4/60Estrellas — 153 estrellas
17.4/25Forks — 123 forks
5/15Observadores — 9 observadores
Datos de entrada utilizados
forks123
stars153
watchers9
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Cómo se puntúa
22.5/22.5README
16.9/22.5Licencia — archivo de licencia presente, no es una licencia reconocida
18/18Guía CONTRIBUTING
0/13.5Código de conducta
0/7.2Plantilla de issues
6.3/6.3Plantilla de PR
Datos de entrada utilizados
has_readme
has_license
has_contributing
has_issue_templateno
has_code_of_conductno
has_pull_request_template

Sostenibilidad y Gobernanza

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

80Bueno · 24% del índice global
Cómo se puntúa
43.2/54Factor bus — la mitad de los commits recae en 4 contribuyente(s)
15.1/22.5Distribución de commits — el principal contribuyente firma el 33% de los commits
13.5/13.5Amplitud de contribuyentes — 98 contribuyentes
10/10OpenSSF Scorecard: Contributors — project has 19 contributing companies or organizations
Datos de entrada utilizados
bus_factor4
contributors_sampled98
top_contributor_share0,327
Cómo se puntúa
42.1/46.8Resolución de issues — 90% de issues cerradas
34.4/38.3Aceptación de PR — 690/767 PR decididos fusionados
4.5/15OpenSSF Scorecard: Code-Review — Found 10/30 approved changesets -- score normalized to 3
Datos de entrada utilizados
merged_prs690
open_issues36
closed_issues329
issue_closed_ratio0,901
closed_unmerged_prs77
Cómo se puntúa
30/30Respaldo de la propiedad — propiedad de una organización
0/20Dominio verificado
21.5/25Alcance del propietario — 984 seguidores de openrewrite
25/25Trayectoria — 75 repos públicos, cuenta de ~6 años
Datos de entrada utilizados
followers984
owner_typeOrganization
is_verified
owner_loginopenrewrite
public_repos75
account_age_days2341

Calidad de Ingeniería

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

64Moderado · 20% del índice global
Cómo se puntúa
24/24Flujos de trabajo de CI — 5 flujo(s) de trabajo
24/24Pruebas presentes
0/16Configuración de linter
0/9.6Hooks de pre-commit
6.4/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 24 out of 24 merged PRs checked by a CI test -- score normalized to 10
Datos de entrada utilizados
has_ci
has_tests
has_editorconfig
has_linter_configno
has_precommit_configno

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
10/10Topics — 2 topics
0/10Wiki
Datos de entrada utilizados
topicsopenrewrite, openrewrite-recipes
has_wikino
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?

53Moderado · 16% del índice global
Cómo se puntúa
6.8/7.5Binary-Artifacts — binaries present in source code
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.5/2.5CI-Tests — 24 out of 24 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
2.2/7.5Code-Review — Found 10/30 approved changesets -- score normalized to 3
2.5/2.5Contributors — project has 19 contributing companies or organizations
10/10Dangerous-Workflow — no dangerous workflow patterns detected
7.5/7.5Dependency-Update-Tool — update tool detected
0/5Fuzzing — project is not fuzzed
2.2/2.5Licencia — license file detected
7.5/7.5Maintained — 30 commit(s) and 19 issue activity found in the last 90 days -- score normalized to 10
0/5Packaging — sin datos
0/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — 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_aggregate5,3
Excluidos de la puntuación (sin datos o no aplicable): packaging, 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.

56Moderado · 0% del índice global
Cómo se puntúa
0/45Instrucciones para agentes — sin CLAUDE.md / AGENTS.md / reglas de editor
0/15Documentación legible por máquinas (llms.txt)
40/40Historial de commits legible — 84 de 91 commits humanos declaran su intención (asunto estructurado o cuerpo explicativo)
Datos de entrada utilizados
has_llms_txtno
legible_history_share0,923
agent_instruction_files
agent_instruction_max_bytes
Cómo se puntúa
12.6/18Arranque con un solo comando — build.gradle.kts (convención del toolchain, sin ejecutor de tareas)
22/22Pruebas automatizadas
0/11Configuración de lint / formato
11/11Verificación estática de tipos — Java (tipado estático)
0/10Entorno reproducible
0/10Práctica demostrada con agentes — ningún commit con autoría de agente entre los últimos 100
5/8Mantenimiento automatizado — automatización de dependencias configurada, no observada en los commits muestreados
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_language
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0
toolchain_manifestsbuild.gradle.kts
dependency_bot_commit_share0
Cómo se puntúa
45/45Código verificable por tipos — Java (tipado estático)
54.7/55Tamaños de archivo manejables — 3/488 archivos fuente de más de 60 KB
Datos de entrada utilizados
primary_languageJava
largest_source_bytes142.015
source_files_sampled488
oversized_source_files3

Datos clave

153estrellas de GitHub
98contribuidores
411commits en los últimos 12 meses
0días desde el último push
100versiones publicadas
4factor bus
36issues abiertas
Mavenecosistemas de paquetes

Advertencias de recopilación de datos

  • Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token

Más detalle

Historial de estrellas y forks 0 ★ / 123 ⇿
0Estrellas
123Forks
99Versiones

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.

025507510012512232021-092024-022026-07
Mayor 1Menor 69Parche 29

Cada punto abarca 5 días.

OpenSSF Scorecard 5.3 / 10
5.3agregado

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

9Binary-Artifactsbinaries present in source code
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests24 out of 24 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
3Code-ReviewFound 10/30 approved changesets -- score normalized to 3
10Contributorsproject has 19 contributing companies or organizations
10Dangerous-Workflowno dangerous workflow patterns detected
10Dependency-Update-Toolupdate tool detected
0Fuzzingproject is not fuzzed
9Licenselicense file detected
10Maintained30 commit(s) and 19 issue activity found in the last 90 days -- score normalized to 10
n/dPackagingpackaging workflow not detected
0Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 0
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
n/dSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
Todas las dependencias 0

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

RegistroPaqueteVersiónRelación
Avisos de dependencias sin evaluar

El cotejo de avisos no pudo ejecutarse para este informe: No resolved dependencies to assess

Informe JSON sin procesar legible por máquina
{
  "data": {
    "repo": {
      "topics": [
        "openrewrite",
        "openrewrite-recipes"
      ],
      "is_fork": false,
      "size_kb": 20823,
      "has_wiki": false,
      "homepage": null,
      "languages": {
        "Java": 3261655
      },
      "pushed_at": "2026-07-24T21:36:46Z",
      "created_at": "2021-03-21T20:14:16Z",
      "owner_type": "Organization",
      "updated_at": "2026-07-24T21:36:48Z",
      "description": "OpenRewrite recipes for migrating to newer versions of Java.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": null,
      "default_branch": "main",
      "license_spdx_raw": "NOASSERTION",
      "primary_language": "Java",
      "significant_languages": [
        "Java"
      ]
    },
    "owner": {
      "blog": "https://docs.openrewrite.org",
      "name": "OpenRewrite",
      "type": "Organization",
      "login": "openrewrite",
      "company": null,
      "location": "San Francisco, CA",
      "followers": 984,
      "avatar_url": "https://avatars.githubusercontent.com/u/61478321?v=4",
      "created_at": "2020-02-25T21:27:36Z",
      "is_verified": null,
      "public_repos": 75,
      "account_age_days": 2341
    },
    "license": {
      "state": "custom",
      "spdx_id": null,
      "raw_spdx": "NOASSERTION",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v3.40.0",
          "kind": "minor",
          "published_at": "2026-07-14T05:53:34Z"
        },
        {
          "tag": "v3.39.0",
          "kind": "minor",
          "published_at": "2026-07-01T06:28:45Z"
        },
        {
          "tag": "v3.38.0",
          "kind": "minor",
          "published_at": "2026-06-22T12:43:43Z"
        },
        {
          "tag": "v3.37.0",
          "kind": "minor",
          "published_at": "2026-06-17T11:00:27Z"
        },
        {
          "tag": "v3.36.0",
          "kind": "minor",
          "published_at": "2026-06-03T14:24:32Z"
        },
        {
          "tag": "v3.35.0",
          "kind": "minor",
          "published_at": "2026-05-21T10:54:17Z"
        },
        {
          "tag": "v3.34.1",
          "kind": "patch",
          "published_at": "2026-05-07T07:26:45Z"
        },
        {
          "tag": "v3.34.0",
          "kind": "minor",
          "published_at": "2026-04-27T10:19:59Z"
        },
        {
          "tag": "v3.33.1",
          "kind": "patch",
          "published_at": "2026-04-23T10:06:36Z"
        },
        {
          "tag": "v3.33.0",
          "kind": "minor",
          "published_at": "2026-04-21T09:23:21Z"
        },
        {
          "tag": "v3.32.1",
          "kind": "patch",
          "published_at": "2026-04-10T13:17:25Z"
        },
        {
          "tag": "v3.32.0",
          "kind": "minor",
          "published_at": "2026-04-08T13:23:17Z"
        },
        {
          "tag": "v3.31.3",
          "kind": "patch",
          "published_at": "2026-03-30T19:31:11Z"
        },
        {
          "tag": "v3.31.2",
          "kind": "patch",
          "published_at": "2026-03-30T17:49:36Z"
        },
        {
          "tag": "v3.31.1",
          "kind": "patch",
          "published_at": "2026-03-27T14:16:46Z"
        },
        {
          "tag": "v3.31.0",
          "kind": "minor",
          "published_at": "2026-03-25T10:34:55Z"
        },
        {
          "tag": "v3.30.1",
          "kind": "patch",
          "published_at": "2026-03-18T18:56:02Z"
        },
        {
          "tag": "v3.30.0",
          "kind": "minor",
          "published_at": "2026-03-12T14:44:00Z"
        },
        {
          "tag": "v3.29.0",
          "kind": "minor",
          "published_at": "2026-03-04T17:41:44Z"
        },
        {
          "tag": "v3.28.0",
          "kind": "minor",
          "published_at": "2026-02-25T13:13:03Z"
        },
        {
          "tag": "v3.27.1",
          "kind": "patch",
          "published_at": "2026-02-17T16:38:49Z"
        },
        {
          "tag": "v3.27.0",
          "kind": "minor",
          "published_at": "2026-02-11T09:32:31Z"
        },
        {
          "tag": "v3.26.0",
          "kind": "minor",
          "published_at": "2026-01-20T19:51:08Z"
        },
        {
          "tag": "v3.25.0",
          "kind": "minor",
          "published_at": "2026-01-07T16:38:00Z"
        },
        {
          "tag": "v3.24.0",
          "kind": "minor",
          "published_at": "2025-12-16T16:59:38Z"
        },
        {
          "tag": "v3.23.0",
          "kind": "minor",
          "published_at": "2025-12-05T11:20:09Z"
        },
        {
          "tag": "v3.22.0",
          "kind": "minor",
          "published_at": "2025-11-20T12:20:13Z"
        },
        {
          "tag": "v3.21.2",
          "kind": "patch",
          "published_at": "2025-11-12T18:49:08Z"
        },
        {
          "tag": "v3.21.1",
          "kind": "patch",
          "published_at": "2025-11-04T20:00:48Z"
        },
        {
          "tag": "v3.21.0",
          "kind": "minor",
          "published_at": "2025-11-04T15:32:26Z"
        },
        {
          "tag": "v3.20.0",
          "kind": "minor",
          "published_at": "2025-10-22T12:37:37Z"
        },
        {
          "tag": "v3.19.0",
          "kind": "minor",
          "published_at": "2025-10-10T17:54:06Z"
        },
        {
          "tag": "v3.18.0",
          "kind": "minor",
          "published_at": "2025-09-24T14:48:11Z"
        },
        {
          "tag": "v3.17.1",
          "kind": "patch",
          "published_at": "2025-09-16T17:44:00Z"
        },
        {
          "tag": "v3.17.0",
          "kind": "minor",
          "published_at": "2025-09-10T11:24:07Z"
        },
        {
          "tag": "v3.16.0",
          "kind": "minor",
          "published_at": "2025-08-27T16:57:50Z"
        },
        {
          "tag": "v3.15.1",
          "kind": "patch",
          "published_at": "2025-08-21T20:02:34Z"
        },
        {
          "tag": "v3.15.0",
          "kind": "minor",
          "published_at": "2025-08-12T21:32:44Z"
        },
        {
          "tag": "v3.14.1",
          "kind": "patch",
          "published_at": "2025-07-23T21:58:49Z"
        },
        {
          "tag": "v3.14.0",
          "kind": "minor",
          "published_at": "2025-07-23T11:03:21Z"
        },
        {
          "tag": "v3.13.0",
          "kind": "minor",
          "published_at": "2025-07-09T15:52:54Z"
        },
        {
          "tag": "v3.12.0",
          "kind": "minor",
          "published_at": "2025-06-25T11:46:02Z"
        },
        {
          "tag": "v3.11.0",
          "kind": "minor",
          "published_at": "2025-05-28T16:04:19Z"
        },
        {
          "tag": "v3.10.1",
          "kind": "patch",
          "published_at": "2025-05-23T21:31:18Z"
        },
        {
          "tag": "v3.10.0",
          "kind": "minor",
          "published_at": "2025-05-22T16:06:13Z"
        },
        {
          "tag": "v3.9.0",
          "kind": "minor",
          "published_at": "2025-05-07T17:52:58Z"
        },
        {
          "tag": "v3.8.0",
          "kind": "minor",
          "published_at": "2025-04-24T18:35:47Z"
        },
        {
          "tag": "v3.7.0",
          "kind": "minor",
          "published_at": "2025-04-10T15:49:36Z"
        },
        {
          "tag": "v3.6.0",
          "kind": "minor",
          "published_at": "2025-04-09T19:26:41Z"
        },
        {
          "tag": "v3.5.0",
          "kind": "minor",
          "published_at": "2025-03-27T19:38:33Z"
        },
        {
          "tag": "v3.4.0",
          "kind": "minor",
          "published_at": "2025-03-11T20:36:22Z"
        },
        {
          "tag": "v3.3.0",
          "kind": "minor",
          "published_at": "2025-02-20T22:57:14Z"
        },
        {
          "tag": "v3.2.0",
          "kind": "minor",
          "published_at": "2025-02-07T17:35:36Z"
        },
        {
          "tag": "v3.1.0",
          "kind": "minor",
          "published_at": "2025-01-24T17:00:21Z"
        },
        {
          "tag": "v3.0.1",
          "kind": "patch",
          "published_at": "2025-01-17T17:05:24Z"
        },
        {
          "tag": "v3.0.0",
          "kind": "major",
          "published_at": "2025-01-10T17:38:00Z"
        },
        {
          "tag": "v2.31.0",
          "kind": "minor",
          "published_at": "2024-12-18T17:38:52Z"
        },
        {
          "tag": "v2.30.1",
          "kind": "patch",
          "published_at": "2024-11-28T19:12:51Z"
        },
        {
          "tag": "v2.30.0",
          "kind": "minor",
          "published_at": "2024-11-27T17:00:26Z"
        },
        {
          "tag": "v2.29.1",
          "kind": "patch",
          "published_at": "2024-11-19T23:06:35Z"
        },
        {
          "tag": "v2.29.0",
          "kind": "minor",
          "published_at": "2024-11-13T16:42:43Z"
        },
        {
          "tag": "v2.28.0",
          "kind": "minor",
          "published_at": "2024-10-23T15:39:12Z"
        },
        {
          "tag": "v2.27.1",
          "kind": "patch",
          "published_at": "2024-10-17T22:51:28Z"
        },
        {
          "tag": "v2.27.0",
          "kind": "minor",
          "published_at": "2024-10-10T15:57:14Z"
        },
        {
          "tag": "v2.26.1",
          "kind": "patch",
          "published_at": "2024-09-25T17:41:45Z"
        },
        {
          "tag": "v2.26.0",
          "kind": "minor",
          "published_at": "2024-09-24T19:52:38Z"
        },
        {
          "tag": "v2.25.1",
          "kind": "patch",
          "published_at": "2024-09-20T21:46:31Z"
        },
        {
          "tag": "v2.25.0",
          "kind": "minor",
          "published_at": "2024-09-12T17:59:24Z"
        },
        {
          "tag": "v2.24.0",
          "kind": "minor",
          "published_at": "2024-09-11T17:34:39Z"
        },
        {
          "tag": "v2.23.0",
          "kind": "minor",
          "published_at": "2024-08-28T14:17:39Z"
        },
        {
          "tag": "v2.22.1",
          "kind": "patch",
          "published_at": "2024-08-15T10:21:13Z"
        },
        {
          "tag": "v2.22.0",
          "kind": "minor",
          "published_at": "2024-08-12T19:41:10Z"
        },
        {
          "tag": "v2.21.0",
          "kind": "minor",
          "published_at": "2024-07-31T11:55:13Z"
        },
        {
          "tag": "v2.20.0",
          "kind": "minor",
          "published_at": "2024-07-15T09:14:35Z"
        },
        {
          "tag": "v2.19.0",
          "kind": "minor",
          "published_at": "2024-07-03T16:52:07Z"
        },
        {
          "tag": "v2.18.1",
          "kind": "patch",
          "published_at": "2024-06-19T17:37:38Z"
        },
        {
          "tag": "v2.18.0",
          "kind": "minor",
          "published_at": "2024-06-19T09:04:43Z"
        },
        {
          "tag": "v2.17.0",
          "kind": "minor",
          "published_at": "2024-06-07T22:36:12Z"
        },
        {
          "tag": "v2.16.0",
          "kind": "minor",
          "published_at": "2024-05-22T21:47:53Z"
        },
        {
          "tag": "v2.15.0",
          "kind": "minor",
          "published_at": "2024-05-22T16:03:50Z"
        },
        {
          "tag": "v2.14.1",
          "kind": "patch",
          "published_at": "2024-05-21T14:58:51Z"
        },
        {
          "tag": "v2.14.0",
          "kind": "minor",
          "published_at": "2024-05-18T06:16:45Z"
        },
        {
          "tag": "v2.13.0",
          "kind": "minor",
          "published_at": "2024-05-08T13:50:43Z"
        },
        {
          "tag": "v2.12.0",
          "kind": "minor",
          "published_at": "2024-04-24T15:00:51Z"
        },
        {
          "tag": "v2.11.0",
          "kind": "minor",
          "published_at": "2024-03-19T20:28:57Z"
        },
        {
          "tag": "v2.10.0",
          "kind": "minor",
          "published_at": "2024-03-12T22:04:41Z"
        },
        {
          "tag": "v2.9.1",
          "kind": "patch",
          "published_at": "2024-02-25T13:29:18Z"
        },
        {
          "tag": "v2.9.0",
          "kind": "minor",
          "published_at": "2024-02-20T20:20:18Z"
        },
        {
          "tag": "v2.8.0",
          "kind": "minor",
          "published_at": "2024-02-06T14:18:53Z"
        },
        {
          "tag": "v2.7.1",
          "kind": "patch",
          "published_at": "2024-01-23T17:12:16Z"
        },
        {
          "tag": "v2.7.0",
          "kind": "minor",
          "published_at": "2024-01-16T16:02:04Z"
        },
        {
          "tag": "v2.6.0",
          "kind": "minor",
          "published_at": "2024-01-09T14:37:47Z"
        },
        {
          "tag": "v2.5.0",
          "kind": "minor",
          "published_at": "2023-12-21T13:53:42Z"
        },
        {
          "tag": "v2.4.2",
          "kind": "patch",
          "published_at": "2023-12-08T10:26:57Z"
        },
        {
          "tag": "v2.4.1",
          "kind": "patch",
          "published_at": "2023-12-04T19:27:31Z"
        },
        {
          "tag": "v2.4.0",
          "kind": "minor",
          "published_at": "2023-11-25T10:27:32Z"
        },
        {
          "tag": "v2.3.0",
          "kind": "minor",
          "published_at": "2023-11-11T02:22:19Z"
        },
        {
          "tag": "v2.2.1",
          "kind": "patch",
          "published_at": "2023-11-07T10:25:54Z"
        },
        {
          "tag": "v2.2.0",
          "kind": "minor",
          "published_at": "2023-10-28T14:50:52Z"
        },
        {
          "tag": "v2.1.1",
          "kind": "patch",
          "published_at": "2023-10-03T16:13:32Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "7c45df7add66d4df1f3253c0846e740832d4caca",
          "body": "…nd MapStruct are used (#1175)\n\n* Add mapstruct-processor to annotation processor paths for Lombok + MapStruct (#1174)\n\n* Use final fields for displayName and description\n\n* Use fluent .actual() in test assertion\n\n* Drop UpgradeToJava17Test full-chain test; covered by AddLombokMapstructBindingTest",
          "is_bot": false,
          "headline": "Add `mapstruct-processor` to annotation processor paths when Lombok a…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-07-24T21:36:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ab370a9db1a8b641a5d62a1187c980612d971364",
          "body": null,
          "is_bot": false,
          "headline": "Set Develocity `projectId` to \"openrewrite\" (#1172)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-07-22T15:03:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cddded884eb9f0e1d7833589809eb76c726a4b16",
          "body": "Co-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "Move Develocity to community.develocity.cloud",
          "author_name": "tim@moderne.io",
          "author_login": "timtebeek",
          "committed_at": "2026-07-22T12:12:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "577446f9e3c51b1c6a089f34e02d71b3a9ede7fe",
          "body": "…nge (#1171)\n\nThe 2026-07-20 openrewrite/rewrite snapshot changed NoGuavaRefaster so that\nPreconditions.checkNotNull(obj, description) now migrates to\nrequireNonNull(obj, valueOf(description)) with a static import of\njava.lang.String.valueOf, rather than String.valueOf(description).\n\nAligns the expected output in\npreconditionsCheckNotNullToObjectsRequireNonNullTwoArgumentsSecondObject\nwith current behavior.\n\nCI: https://github.com/openrewrite/rewrite-migrate-java/actions/runs/29769956822",
          "is_bot": false,
          "headline": "Update NoGuavaRefaster expected output for upstream static-import cha…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-07-21T10:42:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9b7a874bfe860b22c9a103dadb1c55719fdfd39c",
          "body": null,
          "is_bot": true,
          "headline": "[Auto] SDKMAN! Java candidates as of 2026-07-20T1212",
          "author_name": "team-moderne[bot]",
          "author_login": "TeamModerne",
          "committed_at": "2026-07-20T12:12:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a5b7ddcf37df2aaa9c71799cabe387eb7fb9dd20",
          "body": "* Move Java EE 8 servlet update into separate recipe\n\n* update csv",
          "is_bot": false,
          "headline": "Move Java EE 8 servlet update into separate recipe (#1170)",
          "author_name": "Ralph Sanders",
          "author_login": "rlsanders4",
          "committed_at": "2026-07-17T08:19:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e5e1d5fddd605326ab120c2b2af8be1f88ed77f3",
          "body": "…tor modules (#1169)\n\nWhen a module's parent pom is part of the same reactor and manages the\nsurefire and dependency plugins in pluginManagement (without declaring\nthem in build/plugins), the recipe added an empty argLine property and\nthe maven-dependency-plugin, but skipped adding the surefire plug\n[…]\ndded, leaving a pointless partial change.\n\nPass the same **/pom.xml filePattern for the surefire AddPlugin so the\nconfiguration is added consistently, producing a complete, working setup.\n\nFixes #1168",
          "is_bot": false,
          "headline": "AddMockitoJavaAgentToMavenSurefirePlugin: add surefire config in reac…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-07-15T12:22:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "658481254a6ee678f5f162e51d8d49ee01c75877",
          "body": null,
          "is_bot": false,
          "headline": "Fix Jakarta EE 10 web.xml migration (#1159)",
          "author_name": "sakshichitnis27",
          "author_login": "sakshichitnis27",
          "committed_at": "2026-07-08T11:49:34Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "3d0ad8f745ca7c8c091cc95f9f8c826daf10d63f",
          "body": "Co-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices",
          "author_name": "timtebeek@gmail.com",
          "author_login": "timtebeek",
          "committed_at": "2026-07-08T09:17:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "76925b9fbf3f5a4d89437801ff6f47e345970e95",
          "body": "…lls (#1167)\n\n* Add RedundantUtf8Charset recipe to remove UTF-8 from java.nio.file.Files calls\n\nThe character-based java.nio.file.Files methods always default to UTF-8,\nso passing StandardCharsets.UTF_8 explicitly is redundant. Wire the recipe\ninto java-version-11.yml, the lowest version where every\n[…]\n redundant guard\n\n- Bump copyright headers to 2026\n- End the display name with 'method calls' and regenerate recipes.csv\n- Remove the parameterNames size guard; it always matches parameterTypes length",
          "is_bot": false,
          "headline": "Add RedundantUtf8Charset recipe to drop redundant UTF-8 from Files ca…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-07-07T20:35:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c0d0f673d62c3d7319843db190aea2c94f4c0cc6",
          "body": "…igured in build/plugins (#1166)\n\n* Skip AddMockitoJavaAgentToMavenSurefirePlugin when agent already configured in build/plugins (#1164)\n\n* Minimize comments\n\n* Simplify plugin matching; tolerate implied plugin groupId",
          "is_bot": false,
          "headline": "Skip AddMockitoJavaAgentToMavenSurefirePlugin when agent already conf…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-07-06T13:56:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "12386c8d722bf3912b81749572d06988fb005692",
          "body": "…#1163) (#1165)",
          "is_bot": false,
          "headline": "Skip UseMapOf for LinkedHashMap/TreeMap in prose put-statement form (…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-07-06T12:59:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ee2f4c4dda491b20de45ceac2165e100ea56910c",
          "body": "Co-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices",
          "author_name": "tim@moderne.io",
          "author_login": "timtebeek",
          "committed_at": "2026-07-03T08:56:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5f18964968e9b49bb904f34706753e381a24bd2a",
          "body": "…r class-init (#1157) (#1161)\n\n* Skip UseEnumSetOf empty conversion for static fields to avoid circular class-init (#1157)\n\n* Prevent conversion of empty Set.of() in static fields\n\nSkip conversion for empty Set.of() in static field initializers to avoid ClassCastException.",
          "is_bot": false,
          "headline": "Skip UseEnumSetOf empty conversion for static fields to avoid circula…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-07-01T13:04:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4cd2123a38f17e50d29b580f9425f5c40336ec03",
          "body": "…e stripping (#1160)\n\nFixes #1158",
          "is_bot": false,
          "headline": "Keep \\t and \\f escapes in UseTextBlocks to avoid incidental whitespac…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-07-01T12:56:43Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "16e662d63d12e8e456b2f3a7631df156be9d3fc6",
          "body": null,
          "is_bot": false,
          "headline": "Upgrade maven-ear-plugin for ee9 and ee11 (#1156)",
          "author_name": "Evie Lau",
          "author_login": "evie-lau",
          "committed_at": "2026-06-30T16:12:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b9f0360158bfac7a85a6788b13899e736a64912d",
          "body": "* Upgrade maven-ejb-plugin alongside jakarta.ejb-api\n\n* Change XPath to be less rigid\n\nCo-authored-by: Tim te Beek <tim@moderne.io>\n\n* Handle case where ejb.api is coupled with maven-ejb-plugin's ejbVersion\n\n* More specific version assertions in ejb-api test\n\n* regenerate recipes.csv\n\n* Return assertThat(pom)...actual() in ejb-api test assertions\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>",
          "is_bot": false,
          "headline": "Upgrade maven-ejb-plugin alongside jakarta.ejb-api (#1155)",
          "author_name": "Evie Lau",
          "author_login": "evie-lau",
          "committed_at": "2026-06-29T09:07:50Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83f0e689327acb3b7fc995c1a904da258d8eff7a",
          "body": "* Add recipe to replace jakarta jws-api with ws-api in EE10\n\n* Add test for removing jws-api for EE10 recipe\n\n* Update recipes.csv\n\n* Use ChangeDependency for in-place jws-api replacement; assert exact replacement in test\n\n* Keep AddDependency fallback for transitive jakarta.jws-api\n\n* Use AssertJ assertion verifying 4.x version instead of pinning exact patch\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>",
          "is_bot": false,
          "headline": "Add recipe to replace jakarta jws-api with ws-api in EE10 (#1151)",
          "author_name": "Evie Lau",
          "author_login": "evie-lau",
          "committed_at": "2026-06-26T09:18:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "48213f642b923cee574baa007ddc4238ea879460",
          "body": "* Fix jakarta.enterprise.concurrent-api version for EE9 and EE10\n\n* add newVersion in ChangeDependency for javax.enterprise.concurrent-api",
          "is_bot": false,
          "headline": "Fix jakarta.enterprise.concurrent-api version for EE9 and EE10 (#1152)",
          "author_name": "Evie Lau",
          "author_login": "evie-lau",
          "committed_at": "2026-06-26T04:49:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b6c9ae68c9b95360652c85433d9e8f0880609263",
          "body": "…p (#1148) (#1149)",
          "is_bot": false,
          "headline": "Skip UseMapOf rewrite when the assignment target is a concrete HashMa…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-25T12:37:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ceb4af5157531f2251a6d7bbf984fcef64c51c5e",
          "body": "* Extend Use{List,Set,Map}Of to recognise prose-statement chains\n\nUseListOf, UseSetOf, and UseMapOf previously matched only the\nanonymous-class idiom:\n\n    List<String> l = new ArrayList<>() {{ add(\"a\"); add(\"b\"); }};\n\nExtends each recipe to also recognise the more common prose-statement\nshape, wher\n[…]\nserve comments and one-per-line formatting in UseMapOf prose chains\n\n* Extend prose comment + one-per-line formatting to UseListOf and UseSetOf\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>",
          "is_bot": false,
          "headline": "Extend Use{List,Set,Map}Of to recognise prose-statement chains (#1145)",
          "author_name": "Steve Elliott",
          "author_login": "steve-aom-elliott",
          "committed_at": "2026-06-25T10:57:23Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "8ec6841bbd9ce334267b92f94ff46725b9db3824",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/builder/YzLYjtH9I?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZQ%3D%3D\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-24T11:33:21Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fc4e5d655551c4d1816bd8f413d491dce480f4b1",
          "body": "* Move ReplaceUnusedVariablesWithUnderscore to Java best practices\n\nDevelopers pushed back on the Java 25 upgrade automatically replacing\nunused for-each/catch/lambda variable names with `_`, since automation\ncannot tell an intentionally-named variable from a genuinely unused one\nand stripping the n\n[…]\n` version migration and into the opt-in `JavaBestPractices`\nrecipe, so it is applied deliberately rather than across every upgrade.\n\n* Regenerate recipes.csv after moving recipe to Java best practices",
          "is_bot": false,
          "headline": "Move ReplaceUnusedVariablesWithUnderscore to Java best practices (#1144)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-24T10:50:21Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cfdda28787ce83078a1eab219aaf6b1f07977dfe",
          "body": "…ytecode source/target compatibility (#1143)\n\n* Fix JavadocToMarkdown's handling of <br>, varargs, type parameters, jdks newer than the bytecode source/target compatibility\n\n* Remove duplicate tests that overlap with #1141 and #1142 after merge\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>",
          "is_bot": false,
          "headline": "Fix JavadocToMarkdown's handling of varargs and JDKs newer than the b…",
          "author_name": "Sam Snyder",
          "author_login": "sambsnyd",
          "committed_at": "2026-06-24T09:10:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ad1045d5811bfe22d7bbb3183a37e8b1430a726e",
          "body": null,
          "is_bot": false,
          "headline": "Preserve angle brackets when converting @param <T> to Markdown (#1141)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-24T08:25:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "79e522245e6876be97263759a35a427d0d8d3008",
          "body": null,
          "is_bot": false,
          "headline": "Convert Javadoc <br> tags to Markdown line breaks (#1142)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-24T08:25:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9105dbd71a1acf3e6618d3e12bb7a5a4cb81c4bc",
          "body": "…free (#1140)\n\n* Make ExtractExplicitConstructorInvocationArguments templates context-free\n\nThe two JavaTemplate uses were context-sensitive, which reconstructs and\nreparses the enclosing class and method on every application. Neither needs\nit: contextSensitive() only reconstructs surrounding local \n[…]\nk: collapse complex-arg guard and template call\n\n- Replace the `anyComplex` flag + loop + `if` with a single `noneMatch` guard.\n- Use the static `JavaTemplate.apply(..)` for the argument-list rewrite.",
          "is_bot": false,
          "headline": "Make ExtractExplicitConstructorInvocationArguments templates context-…",
          "author_name": "Knut Wannheden",
          "author_login": "knutwannheden",
          "committed_at": "2026-06-23T09:43:02Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "19703614fed7ee71feb24bf4e764f6bb960783d5",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/builder/yESIGzVB0?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZQ%3D%3D\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "Recipe best practices",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-23T07:37:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f3227f70a3929cc7f5fa9dca34f058586a01a857",
          "body": "* Bump Kotlin 2.0-2.2 to 2.3 so Kotlin modules reach Java 25\n\n* Floor Kotlin 2.0-2.2 modules at Java 24 as a bump safety net\n\n* Explain the Java 24 safety-net floor in UpgradeKotlinForJava25\n\n* Rename UpgradeBuildToJava24 to UpgradeBuildToJava24ForKotlin1x\n\n* Comment both Kotlin 1.x caps and 2.x bum\n[…]\nKotlinModulesCappedAtJava24 wrapper scoped to Kotlin modules, so the\nexplanation lands on every Kotlin module that truly stays at Java 24 without\nleaving a stale comment on modules that reach Java 25.",
          "is_bot": false,
          "headline": "Bump Kotlin 2.0-2.2 to 2.3 so Kotlin modules can reach Java 25 (#1139)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-22T12:37:59Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a602847d7648412acd2a5aadbe677e50f9c7cd79",
          "body": "…ts (JEP 513) (#1135)\n\n* Add `ExtractSuperConstructorArgument` recipe for JEP 513\n\nExtracts complex `super(..)` arguments (method invocations and object\ncreations) into local variables declared right before the `super(..)`\ncall, now that JEP 513 permits statements before the explicit\nconstructor inv\n[…]\nices, since it restyles\nalready-valid code rather than migrating it.\n\nAdd tests for the nested-class case, varargs bail, statements before super,\nstatic-field extraction, and name-collision avoidance.",
          "is_bot": false,
          "headline": "Add recipe to extract complex explicit constructor invocation argumen…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-22T11:54:08Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c0be3e515414588a7a24365cb2cfa23df9986ada",
          "body": "`matchOverrides=true` only changes how a `MethodMatcher` treats overrides of a\nmethod on subtypes. Static methods cannot be overridden, so the flag is a no-op\non matchers that target them — it is misleading, and it can defeat precondition\noptimizations that key on the declaring type.\n\nDrop it from t\n[…]\nateTimeFormats (`DateFormat`/`DateTimeFormatter` factory methods)\n\nAdd a static-import regression test confirming the singleton recipe still fires\nwhen the declaring type is never referenced directly.",
          "is_bot": false,
          "headline": "Remove meaningless `matchOverrides` on static-method MethodMatchers",
          "author_name": "Knut Wannheden",
          "author_login": "knutwannheden",
          "committed_at": "2026-06-22T11:53:52Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a8974233fbcf996efc03ca42075befcb5ed5df8b",
          "body": "…ge (#1138)\n\n* Preserve `@{argLine}` in AddSurefireFailsafeArgLine for JaCoCo coverage\n\nWhen writing or merging a surefire/failsafe `argLine`, prepend Surefire's\n`@{argLine}` late property reference so an agent injected into the `argLine`\nproperty by an earlier plugin (e.g. JaCoCo `prepare-agent`) i\n[…]\ne reference is not added when the existing\n`argLine` already references the `argLine` property (`@{argLine}`/`${argLine}`).\n\n* Regenerate recipes.csv for updated AddSurefireFailsafeArgLine description",
          "is_bot": false,
          "headline": "Preserve `@{argLine}` in AddSurefireFailsafeArgLine for JaCoCo covera…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-22T11:34:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5cb24acc8b4702c3e070fb30f19537a3d70efaa6",
          "body": "…tion (#1137)\n\n* Explain why Kotlin modules are capped at Java 24 during Java 25 migration\n\nWhen migrating to Java 25, modules that compile Kotlin and depend on\nkotlin-stdlib older than 2.3 are capped at Java 24, since Kotlin <2.3\ncannot target Java 25 bytecode. Previously this happened silently,\nle\n[…]\notlin-stdlib version found and the next\nstep to reach Java 25. Wired into UpgradeBuildToJava24 so it runs scoped\nbehind the same Kotlin preconditions.\n\n* Register CommentJava24KotlinCap in recipes.csv",
          "is_bot": false,
          "headline": "Explain why Kotlin modules are capped at Java 24 during Java 25 migra…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-22T11:31:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e2614a37b0764c53d7f803ae10bce82e17e15ba3",
          "body": "PMD 7.0 does not support parsing Java 25; maven-pmd-plugin 3.28.0\nships PMD 7.17.0, which does. Upgrade it as part of\nUpgradePluginsForJava25.",
          "is_bot": false,
          "headline": "Bump maven-pmd-plugin to 3.28.x for Java 25 support (#1136)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-22T11:12:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1d25dc2dbdb32eb365cc7b4cc70c02820750b98b",
          "body": "The transform visitor ran its ChangeMethodName and ChangeType sub-recipes\ninside preVisit, which fires on every node. Each call re-traversed the whole\nsubtree and rebuilt the sub-recipes (re-parsing their matchers), making the\nrecipe quadratic in tree size. This was especially costly within the\nJavaBestPractices composite.\n\nAdd stopAfterPreVisit() so preVisit runs once on the root, applying both\nsub-recipes over the tree in a single linear pass.",
          "is_bot": false,
          "headline": "Fix quadratic traversal in NoGuavaPredicate",
          "author_name": "Knut Wannheden",
          "author_login": "knutwannheden",
          "committed_at": "2026-06-22T08:41:54Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a58ef3a411c27159acb4b174a720b915f91ddc48",
          "body": null,
          "is_bot": false,
          "headline": "use . instead # for FQN link in Markdown javadoc (#1134)",
          "author_name": "Marius Barbulescu",
          "author_login": "barbulescu",
          "committed_at": "2026-06-20T11:28:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "306ab43ad1f6c08e451238a6c5a53bbcfdf068dd",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.github.ChangeActionVersion?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZQ%3D%3D#defaults=W3sidmFsdWUiOiJhY3Rpb25zL2NoZWNrb3V0IiwibmFtZSI6ImFjdGlvbiJ9LHsidmFsdWUiOiJ2NyIsIm5hbWUiOiJ2ZXJzaW9uIn1d\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "Use GitHub actions/checkout@v7",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-19T09:43:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ef808101d92b5ea11a03f5621c7626dc3506389d",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.xml.security.RemoveOwaspSuppressions?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZQ%3D%3D#defaults=W3sidmFsdWUiOiIyMDI2LTA2LTE3IiwibmFtZSI6ImN1dE9mZkRhdGUifV0=\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "Remove out-of-date OWASP suppressions",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-17T17:36:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5832fe8d01a63d664984cdea9e6a89df30ca9aea",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/builder/abtSSjvHK?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZQ%3D%3D\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-16T10:56:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "909588861cd01314fa8ce9484b25c07f2dc2560b",
          "body": null,
          "is_bot": true,
          "headline": "[Auto] SDKMAN! Java candidates as of 2026-06-15T1541",
          "author_name": "team-moderne[bot]",
          "author_login": "TeamModerne",
          "committed_at": "2026-06-15T15:41:29Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "741bc5019c4f523269f781558059d3f87aca6558",
          "body": null,
          "is_bot": false,
          "headline": "Preserve significant trailing space in UseTextBlocks (#1132) (#1133)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-15T08:29:31Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5526dd187c32286f221e00224ecc8afa7c52ed63",
          "body": "* Contributing AddMockitoJavaAgentToMavenSurefirePlugin recipe for better recipe alignment to Mockito recommendations.\n\n* Contributing AddMockitoJavaAgentToMavenSurefirePlugin recipe for better recipe alignment to Mockito recommendations.\n\n* Remove stale AddSurefireFailsafeArgLineForMockito entry fr\n[…]\ned with multiple argLine tags\n\n* Remove test for invalid multiple-argLine configuration\n\n---------\n\nCo-authored-by: Hudson, Ryan <ryan.hudson@jpmchase.com>\nCo-authored-by: Tim te Beek <tim@moderne.io>",
          "is_bot": false,
          "headline": "Contribute AddMockitoJavaAgentToMavenSurefirePlugin Recipe (#1128)",
          "author_name": "Ryan Hudson",
          "author_login": "ryan-hudson",
          "committed_at": "2026-06-10T10:07:55Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e3a46d52b8741179a43c2acdad92dd5315306d30",
          "body": "* javadoc code tag language is not converted to markdown\n\n* Place code fence on its own line so the first code line is not consumed as the info string\n\nCo-authored-by: Tim te Beek <tim@moderne.io>\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>",
          "is_bot": false,
          "headline": "javadoc code tag language is not converted to markdown (#1129)",
          "author_name": "Marius Barbulescu",
          "author_login": "barbulescu",
          "committed_at": "2026-06-09T19:13:44Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "68767e1f515eb9e181bc1cb6baf5f2a46ef0e8aa",
          "body": "* Move instance main methods recipe to JavaBestPractices\n\nMove MigrateMainMethodToInstanceMain out of UpgradeToJava25 and into\nJavaBestPractices, since instance main methods do not yet work for\nSpring Boot (spring-projects/spring-boot#35785).\n\n* Regenerate recipes.csv",
          "is_bot": false,
          "headline": "Move instance main methods recipe to JavaBestPractices (#1130)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-09T14:32:36Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "34025ad106d82b680dba143c8dec1d1c3c32cdd8",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.AddToGitignore?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZQ%3D%3D#defaults=W3sidmFsdWUiOiIuY29udGV4dC8iLCJuYW1lIjoiZW50cmllcyJ9XQ==\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "git-ignore .context/",
          "author_name": "Greg Oledzki",
          "author_login": "greg-at-moderne",
          "committed_at": "2026-06-09T11:30:55Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "68f982cf3b59bf1472265b634594177258a54235",
          "body": null,
          "is_bot": true,
          "headline": "[Auto] SDKMAN! Java candidates as of 2026-06-08T1401",
          "author_name": "team-moderne[bot]",
          "author_login": "TeamModerne",
          "committed_at": "2026-06-08T14:01:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4d98294f382ab67a286799ce4f8a1628c353bc68",
          "body": "…n (#1120)",
          "is_bot": false,
          "headline": "Align Kotlin jvmTarget with the Java version during UpgradeJavaVersio…",
          "author_name": "Merlin Bögershausen",
          "author_login": "MBoegers",
          "committed_at": "2026-06-03T19:25:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d4df17857ef81e000da0bd2440a08bca9efbdbbb",
          "body": "…g -1 (#1125)\n\n* Skip unparseable Java versions in FindJavaVersion instead of reporting -1\n\nA JavaVersion marker whose source/target compatibility cannot be parsed\nreports a major version of -1. FindJavaVersion stringified that straight\ninto the data table, so repositories surfaced a bogus -1 row. W\n[…]\n\nWhen the recipe emits no rows the JavaVersionTable is absent rather than\npresent-but-empty, so the dataTable assertion throws. The skip behavior is\nalready covered by unknownVersionMarkersAreSkipped.",
          "is_bot": false,
          "headline": "Skip unparseable Java versions in FindJavaVersion instead of reportin…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-03T08:12:11Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b8a298efbf34a018c85dfd601e484efbc502ec2a",
          "body": "…els (#1124)\n\n`when` guards are only valid on pattern case labels, but the recipe\nalso matched constant labels (e.g. enum constants) when the `if`\ncondition referenced no label-bound variables, producing uncompilable\ncode with a duplicate case. Require the case label to bind pattern\nvariables before refining.\n\nFixes #1123",
          "is_bot": false,
          "headline": "Fix `RefineSwitchCases` generating invalid guard on enum constant lab…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-06-01T15:54:37Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c7f400b59e125a859c1cf63622bedab860b79653",
          "body": null,
          "is_bot": true,
          "headline": "[Auto] SDKMAN! Java candidates as of 2026-06-01T1550",
          "author_name": "team-moderne[bot]",
          "author_login": "TeamModerne",
          "committed_at": "2026-06-01T15:50:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "fca7c7c2c9687c08e017dfb36c93136536f72899",
          "body": "…lassfish.jaxb.runtime.marshaller.NamespacePrefixMapper` (#1121)\n\nThe JAXB RI relocated `NamespacePrefixMapper` as part of the 2.x→3.x\nrepackaging that accompanies the `javax.xml.bind` → `jakarta.xml.bind`\nmove. Wire a declarative `ChangeType` into\n`JavaxXmlBindMigrationToJakartaXmlBind` so subclasses migrate alongside\nthe rest of the Jakarta XML Binding 3.0 wave.\n\nRefs: https://github.com/moderneinc/customer-requests/issues/2462 (item 8)",
          "is_bot": false,
          "headline": "Migrate `com.sun.xml.bind.marshaller.NamespacePrefixMapper` to `org.g…",
          "author_name": "Jente Sondervorst",
          "author_login": "Jenson3210",
          "committed_at": "2026-06-01T11:25:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "74017b27eab927dc885e4ec65265fac0c7d335b8",
          "body": "* Route WSS4J `message.token` classes to their real 2.x packages\n\nThe recursive `ChangePackage` in `UpdateApacheWSSecurityPackages` over-renames\n`org.apache.ws.security.message.token.*` to `org.apache.wss4j.common.ext.message.token.*`,\na namespace that does not exist in any WSS4J release. Append `Ch\n[…]\nough the non-existent `org.apache.wss4j.common.ext.message.token.*`\nnamespace and keeps the recipe to one routing per class.\n\nAddresses review comment on PR #1122.\n\n* Apply suggestion from @Jenson3210",
          "is_bot": false,
          "headline": "Route WSS4J message.token classes to their real 2.x packages (#1122)",
          "author_name": "Jente Sondervorst",
          "author_login": "Jenson3210",
          "committed_at": "2026-06-01T09:41:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "52b0808bbb6c9e04be50a513706006fe79502d92",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZQ%3D%3D\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-29T08:57:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "23e5804fe017ddb6604a8f984943db9220afe91d",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.gradle.UpdateGradleWrapper?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZS9PcGVuUmV3cml0ZQ%3D%3D#defaults=W3sidmFsdWUiOiI5LjUuMSIsIm5hbWUiOiJ2ZXJzaW9uIn0seyJ2YWx1ZSI6ImJpbiIsIm5hbWUiOiJkaXN0cmlidXRpb24ifSx7InZhbHVlIjoiYmFmYzE0MWI2MTlhZDYzNTBmZDk3NWZjOTAzMTU2ZGQ1YzE1MTk5OGNjOGIwNThlOGMxMDQ0YWI1ZjdiMDMxZiIsIm5hbWUiOiJkaXN0cmlidXRpb25DaGVja3N1bSJ9XQ==\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "Update Gradle wrapper 9.5.1",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-28T19:52:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "21548bd4f043d0202fb5ab1eff7e16a651c29853",
          "body": "…ment target (#1117)",
          "is_bot": false,
          "headline": "fix: do not replace lambda params with underscore when used as assign…",
          "author_name": "darrencilia",
          "author_login": "darrencilia",
          "committed_at": "2026-05-28T18:50:10Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61e7d90e7a8f5e4b369c42e2b6ed7b4432563532",
          "body": "Fixes #1115. JEP 512 moved the new `IO` class to `java.lang.IO` for the\nfinal Java 25 release, so it is implicitly imported by every source file;\nthe `java.io.IO` location only existed in the preview JEPs 477 and 495.\nReverts the import added in #1093, which produced an import of the\nnon-existent `java.io.IO`.",
          "is_bot": false,
          "headline": "Do not add `java.io.IO` import in `ReplaceSystemOutWithIOPrint` (#1118)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-28T18:42:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dec86d0f6c2d2194a1d551a5f9b5834e8177834b",
          "body": "Mirror the precondition gate already used by the sibling\n`ReplaceUnusedVariablesWithUnderscore` so the recipe no longer rewrites\nlegal `_` placeholders in Kotlin lambdas to `__`, which is reserved in\nKotlin 2.0+.",
          "is_bot": false,
          "headline": "Skip `RenameUnderscoreIdentifier` on Kotlin and Groovy sources (#1114)",
          "author_name": "Merlin Bögershausen",
          "author_login": "MBoegers",
          "committed_at": "2026-05-28T16:36:45Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "baceee19e666606d011c1ff4fbb9eb2b11a81ca4",
          "body": "…eeMap` (#1113)\n\n`Map.of(..)` does not preserve iteration order, so converting order-sensitive\nmaps silently drops their ordering contract.",
          "is_bot": false,
          "headline": "Skip `UseMapOf` for `HashMap` subclasses like `LinkedHashMap` and `Tr…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-28T10:23:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9cacf885293e46847a197a1ab33fa8717428b01e",
          "body": "Defend against `J.Literal` values that come back identical to their\n`valueSource` (observed for string literals containing supplementary\ncharacters encoded as surrogate pairs). Skipping the conversion avoids\nemitting a broken text block that drops or re-escapes content.\n\nFixes #1110",
          "is_bot": false,
          "headline": "Skip `UseTextBlocks` when literal value matches its source (#1111)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-28T08:38:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "584dfd72a7992a7a2eb8c1257e86ecb5eab489bb",
          "body": "… check is present (#1109)\n\nPreviously the trailing branch's body was silently dropped because `validatePotentialCandidate()` overwrote the disqualifying flag set by `handleNullCheck` when it could not recognise the condition.\n\nFixes #1108",
          "is_bot": false,
          "headline": "Skip `IfElseIfConstructToSwitch` when a trailing non-`== null` binary…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-27T11:13:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a333baaa9cd0a64e36b65de248dae16e7c42e9ce",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUgKyBPcGVuUmV3cml0ZS9PcGVuUmV3cml0ZQ%3D%3D\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-26T09:29:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9630229a5d8af5ba53482e792a9865d7591aa725",
          "body": null,
          "is_bot": true,
          "headline": "[Auto] SDKMAN! Java candidates as of 2026-05-25T1257",
          "author_name": "team-moderne[bot]",
          "author_login": "TeamModerne",
          "committed_at": "2026-05-25T12:57:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ab9515db6e0c5af711d9c30a6d0436a757bed3a",
          "body": "Now handled by https://github.com/openrewrite/rewrite-build-gradle-plugin/pull/175\n\nUse this link to re-run the recipe: https://app.moderne.io/builder/Qzl8kgixb?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "Remove explicit test dependencies",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-22T10:30:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c417b7ac98078726510a4af8d3610f4932ba4e26",
          "body": "…es (#1106)\n\n* Move StringFormatted recipe from Java 17 upgrade to Java best practices\n\n* Set addParentheses: true for StringFormatted in best practices\n\n* Drop StringFormatted expectations from Java 17 upgrade tests",
          "is_bot": false,
          "headline": "Move StringFormatted recipe from Java 17 upgrade to Java best practic…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-21T22:56:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8247c73a2186e0208a275a22d4ec1cca255e3da2",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-21T08:00:51Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a08ce01f917e1b3db4056cf1d78882851396da43",
          "body": "* Record one row per project in FindJavaVersion\n\nThe recipe used a `transient Set<JavaVersion> seen` HashSet on the recipe\ninstance to deduplicate rows. Because `JavaVersion` excludes its UUID from\n`equals`, two compilation units from different projects built with the same\nJDK compare equal, and rec\n[…]\nUUID, JavaVersion UUID) now get\n  explicit `origin:` / `project:` / `version:` prefixes so they can never\n  collide with each other.\n- Collapse the if/else key-derivation into a single Optional chain.",
          "is_bot": false,
          "headline": "Aggregate FindJavaVersion to one row per repository (#1105)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-20T21:27:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "25a2805b08c6a11d644371c4e05076d5ee2831dd",
          "body": "* Revert inline mirror — central config lives in gh-automation now\n\nThe Maven Artifactory mirror configuration that this repo carried\ninline (s4u/maven-settings-action + REWRITE_GRADLE_MIRROR_* env\nvars) has been moved to the shared reusable workflows in\nopenrewrite/gh-automation (#95). Restoring th\n[…]\n on the repo (or org), this is a no-op — the\nmirror is consulted anonymously, which is sufficient for any artifact\npresent in the anonymous-readable backing repos.\n\n* Apply suggestion from @Jenson3210",
          "is_bot": false,
          "headline": "Revert inline Maven mirror (now in gh-automation#95) (#1104)",
          "author_name": "Jente Sondervorst",
          "author_login": "Jenson3210",
          "committed_at": "2026-05-18T15:25:39Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "17c73bda8957f7eb5960e5fd830776e9225a02ae",
          "body": null,
          "is_bot": true,
          "headline": "[Auto] SDKMAN! Java candidates as of 2026-05-18T1340",
          "author_name": "team-moderne[bot]",
          "author_login": "TeamModerne",
          "committed_at": "2026-05-18T13:40:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d6ec0b8b89fa79ae2e89748237d94baecd67e394",
          "body": "…(#1095)\n\n* Use `contextSensitive()` template in `IfElseIfConstructToSwitch`\n\nThe template references symbols visible from its insertion scope\n(variables, types, methods), so parsing outside that context can fail\non Java 21 pattern-switch syntax and leak `__P__` parameter stubs into\nthe result.\n\n* R\n[…]\ns up to the\nenclosing `JavaSourceFile`, but the visitor was invoked without a\nparent cursor, causing `IllegalStateException: Expected to find\nenclosing JavaSourceFile` after a recent framework change.",
          "is_bot": false,
          "headline": "Skip `IfElseIfConstructToSwitch` when `instanceof` types are missing …",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-18T09:20:29Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "568b7a9204a46b2cbe6450327cac20d72057d6cf",
          "body": "`List<I> x = singletonList(c)` where `c` is a `C extends I` keeps the\nLST type as `List<I>` via target type inference. Converting to\n`var x = List.of(c)` drops the target context, so javac re-infers\n`List<C>` and downstream usages expecting `List<I>` fail to compile.\n\nDetect the widening by comparin\n[…]\nter type: when the parameter is a bare class (not parameterized)\nthat is a strict supertype of the argument, target inference widened\na `<T>` substitution, and switching to `var` would narrow it back.",
          "is_bot": false,
          "headline": "Skip `var` when target type inference widens a generic argument (#1103)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-16T11:34:41Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f7a32879ebb3b075b844002a1c1190f381aeee3a",
          "body": "…cMethodInvocations` (#1102)\n\nWildcards (`?`) are not valid as explicit type arguments on a method\ninvocation, so e.g. `Class<?> x = cl.loadClass(...)` was being rewritten\nto invalid `var x = cl.<?>loadClass(...)`.",
          "is_bot": false,
          "headline": "Skip explicit type arguments containing wildcards in `UseVarForGeneri…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-16T10:57:49Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9ca7bbb469d8ac3c3a5f8ad1e3377370a5e21f51",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-16T10:29:14Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dd5e0dcc5e0cc43d080af1754f9c88c20a22e0d7",
          "body": "…#1101)\n\n`classpathFromResources(\"sun.internal.new\")` uses\n`Pattern.compile(artifactName + \".*\")` to match against artifact-version\nstrings in both `META-INF/rewrite/classpath.tsv.gz` type tables and\nJAR files under `META-INF/rewrite/classpath/`. Since `.` is a regex\nwildcard, the prefix `sun.intern\n[…]\nvia\n`classpath(Collection<Path>)` and a `getResource` lookup bypasses\nboth the regex matching and the shared static cache, so the IBM\nJSSE stub classes are always available to the parser.\n\nFixes #1100",
          "is_bot": false,
          "headline": "Load `sun.internal.new[Class].jar` directly to fix CI test failures (…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-15T21:58:45Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f56a1ead780a40b5b8ce02cdc8f16e3206186c71",
          "body": "* Route Maven through Moderne Artifactory cache to avoid HTTP 429\n\nMaven Central has started rate-limiting parallel test resolution\n(HTTP 429), failing CI across recipe repos. Inline the same mirror\nconfiguration used by moderneinc/rewrite-java-security: route\n`mirrorOf: \"*\"` through artifactory.mod\n[…]\n `latest.release`, which now resolves to `1.0.0.redhat-00001`\nthrough the Moderne Artifactory cache mirror, breaking\nJSpecifyBestPracticesTest.\n\n---------\n\nCo-authored-by: Tim te Beek <tim@moderne.io>",
          "is_bot": false,
          "headline": "Route Maven through Moderne Artifactory cache to avoid HTTP 429 (#1096)",
          "author_name": "Jente Sondervorst",
          "author_login": "Jenson3210",
          "committed_at": "2026-05-13T23:39:25Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d5db0d75d9cbc3fa00a91d0f9615e64d23479554",
          "body": "…099)\n\nWithout this, `Collections.<K, V>emptyMap()` was rewritten to `Map.of()`,\nlosing the type witness needed in contexts like ternaries where the\ncompiler cannot otherwise infer the type parameters.",
          "is_bot": false,
          "headline": "Preserve explicit type arguments in `MigrateCollections*` recipes (#1…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-13T14:38:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8ba21db85723fd3429ff3b9381c0ccd2e752b420",
          "body": "* Add reproducer: JAXB XJC binding migration ignores version 2.0/2.1/2.2\n\nThe JavaxXmlToJakartaXmlXJCBinding recipe only matches version=\"1.0\" on\nthe <jxb:bindings> root, leaving 2.x bindings with a now-mismatched\nnamespace and a stale version attribute.\n\nSee moderneinc/customer-requests#2359.\n\n* Mi\n[…]\nXB 3 then\nrejects them at build time.\n\nBroaden the version rule to a regex that matches exactly the\nspec-defined pre-3.0 binding versions (1.0, 2.0, 2.1, 2.2).\n\nFixes moderneinc/customer-requests#2359",
          "is_bot": false,
          "headline": "Migrate JAXB XJC binding files declaring version 2.0/2.1/2.2 (#1098)",
          "author_name": "Merlin Bögershausen",
          "author_login": "MBoegers",
          "committed_at": "2026-05-13T12:19:27Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "d845f4db07f3250708b99968212ad4bf130bcf06",
          "body": null,
          "is_bot": true,
          "headline": "[Auto] SDKMAN! Java candidates as of 2026-05-11T1235",
          "author_name": "team-moderne[bot]",
          "author_login": "TeamModerne",
          "committed_at": "2026-05-11T12:35:42Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "972a5192fc716da19e00b0ea10e2022dab1d3d8c",
          "body": "`Map.of(..)` throws `NullPointerException` on null keys or values, so\nconverting a `HashMap` containing null arguments is not behavior-preserving.\n\nFixes #1092",
          "is_bot": false,
          "headline": "Skip `UseMapOf` when `put()` argument is a null literal (#1094)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-11T11:41:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9b419e99373a21ac3c6bce35064cc51945aeb188",
          "body": "Fixes #1091: in regular classes with a package declaration, `IO` is not\nimplicitly available, so the rewritten `IO.println(...)` call failed to\ncompile. Force-add the import so the output compiles in both regular\nclasses and JEP 512 compact source files.",
          "is_bot": false,
          "headline": "Add `java.io.IO` import in `ReplaceSystemOutWithIOPrint` (#1093)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-11T11:26:53Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "cb4f1bcfc96721fd0ce555cf28131972d5d4bb0f",
          "body": "* Use `Map.ofEntries` when more than 10 entries\n\n`Map.of` overloads only support up to 10 entries, so emit\n`Map.ofEntries(Map.entry(k, v), ...)` once the anonymous `HashMap`\ninitializer has more than 10 `put(..)` calls.\n\n* Preserve `put` statement prefixes on generated `Map.entry` calls\n\nTransfer th\n[…]\nrefix transfer for single-entry initializers\n\nA lone entry doesn't benefit from being put on its own line, so leave\nthe inline `Map.of(k, v)` formatting untouched when there's only one\n`put(..)` call.",
          "is_bot": false,
          "headline": "Use `Map.ofEntries` when migrating more than 10 entries (#1090)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-06T16:46:38Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e26618cf19cd40e8cfaf8085385a8dc30f1b2026",
          "body": null,
          "is_bot": false,
          "headline": "Keep block when refined switch arm contains an if statement (#1088)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-06T15:57:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7424e22c12805c18770035a92d02aaf444b48aad",
          "body": "…(#1089)\n\n`List.copyOf` and `Set.copyOf` only accept `Collection`, and `Map.copyOf`\nonly accepts `Map`, while their Guava counterparts also accept `Iterable`\nand `Iterator`. Skip the rewrite when the argument type would not satisfy\nthe JDK signature, to avoid producing code that fails to compile.",
          "is_bot": false,
          "headline": "Skip `Immutable*.copyOf` rewrite when argument is not a `Collection` …",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-06T15:55:22Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "dcaa8cabffbae755339504cee49441f54e6b7d72",
          "body": "Convert `MigrateMainMethodToInstanceMain` to a `ScanningRecipe` so it\ndetects `Main.main(...)` invocations and `Main::main` references across\nall compilation units, not just the same file. Migrating the declaring\nclass to `void main()` would otherwise leave call sites broken.\n\nFixes #1083",
          "is_bot": false,
          "headline": "Skip main method migration when referenced as static API (#1084)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-05T09:42:00Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "b6c609d208f3f10a730f49e3858dc3ce24512d13",
          "body": "…1081)\n\n`List.of(..)`, `Set.of(..)`, and `Map.of(..)` throw `NullPointerException`\nwhen probed with `contains(null)` and friends, whereas the\n`Collections.singleton*` factories return `false`/`-1`/`null`. Call this\nout in each recipe description so users can decide whether the migration\nis safe for their code. Also fixes a `Set.Of` typo.",
          "is_bot": false,
          "headline": "Document null-probing semantic differences in singleton migrations (#…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-04T18:55:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "915f92e7c5af2bbdc324ed2e661f4c416406015f",
          "body": "…#1082)\n\nA single explicitly typed lambda parameter like `(RequestContext rc) -> ...`\nmust remain parenthesized after renaming to `_`, otherwise the resulting\n`RequestContext _ -> ...` is invalid Java.\n\nFixes #1080",
          "is_bot": false,
          "headline": "Keep parentheses when renaming typed lambda parameter to underscore (…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-04T18:50:28Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "88ef91c3f557b2d0b29d28c0b254234ecdad7048",
          "body": null,
          "is_bot": true,
          "headline": "[Auto] SDKMAN! Java candidates as of 2026-05-04T1143",
          "author_name": "team-moderne[bot]",
          "author_login": "TeamModerne",
          "committed_at": "2026-05-04T11:43:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "4ea11911eb19e8afdfe5bb3be661ac505f081cb7",
          "body": "* Skip `var` when reassignment relies on declared supertype\n\nWhen a generic variable is declared as a supertype but initialized with a\nconcrete subtype constructor or method, switching to `var` narrows the\ninferred type and breaks later reassignments. Detect reassignment within\nthe enclosing method \n[…]\nal diverged. Anchor the regex to\nthe jakarta.json-api artifact.\n\nAlso consolidate the `isReassigned` visitor to use `.reduce(...)` directly,\nmatching the existing idiom in NullCheck and other recipes.",
          "is_bot": false,
          "headline": "Skip `var` when reassignment relies on declared supertype (#1078)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-04T09:43:37Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "1ead1d82f0b5961c0d10f137d0eef08a93b7e947",
          "body": null,
          "is_bot": false,
          "headline": "Add jspecify hyperlink (#1076)",
          "author_name": "sullis",
          "author_login": "sullis",
          "committed_at": "2026-05-03T16:54:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "c69eb618ae132097e84661b45ebd0840c15c187f",
          "body": "* OpenRewrite recipe best practices\n\nUse this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>\n\n* Use Java 25 toolchain\n\nAllo\n[…]\nlchain rejects unnamed variables (a Java 22 feature) without --enable-preview. Restore the named parameter so compileTestJava succeeds on Java 21.\n\n---------\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices (#1074)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-01T13:12:16Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a1f85d22bb256fb0168d9db432572a96a0cd71ed",
          "body": "Includes EqualsAvoidsNull, MissingOverrideAnnotation, LambdaBlockToExpression, and RemoveRedundantNullCheckBeforeInstanceof.",
          "is_bot": false,
          "headline": "Add more static analysis recipes to java-best-practices (#1075)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-05-01T12:39:09Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0313c29cb0b9a540bdad98b071633b099108705f",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-04-29T09:59:12Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e911312449b57e460e761d952c7efb189ce2db95",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.recipes.rewrite.OpenRewriteRecipeBestPractices?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "OpenRewrite recipe best practices",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-04-28T10:19:38Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "83f0156729430eabc7412e8a6e4d8bf5df3488e1",
          "body": "The 2026-04-27 auto-update of sdkman-java.csv removed several\npatch versions that the test fixtures hard-coded:\n\n- 17.0.18-tem → only 17.0.19-tem now ships\n- 11.0.30-amzn → only 11.0.31-amzn now ships\n- 23.0.1-open and 23.0.2-amzn → no Java 23 entries remain\n\nUpdate the three failing tests to use versions present in the\ncurrent CSV, choosing pairs that still demonstrate the same\nrecipe behavior.",
          "is_bot": false,
          "headline": "Refresh UpdateSdkManTest fixtures after SDKMAN CSV update (#1073)",
          "author_name": "Steve Elliott",
          "author_login": "steve-aom-elliott",
          "committed_at": "2026-04-27T19:22:11Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9664adb3b9d097d4bbf9db4d48f31f1512121588",
          "body": null,
          "is_bot": true,
          "headline": "[Auto] SDKMAN! Java candidates as of 2026-04-27T1141",
          "author_name": "team-moderne[bot]",
          "author_login": "TeamModerne",
          "committed_at": "2026-04-27T11:41:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "61c17778f9e8df95d3ba7a93f6a47415799a8fd6",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.java.recipes.ExamplesExtractor?organizationId=N2EwZmI3MzMtZTg2My00Njk5LTkwZDUtMmZiYzJhMDRkZTlk\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "Extract documentation examples from tests",
          "author_name": "Jente Sondervorst",
          "author_login": "Jenson3210",
          "committed_at": "2026-04-27T08:30:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "95028a50df2c3ab08e8e69c4d8137f16cefb9b4f",
          "body": "…..)` (#1072)\n\n* Add `UsePredicateNot` to replace cast-and-negate with `Predicate.not(..)`\n\nTargets Java 11+ code like `((Predicate<T>) lambdaOrMethodRef).negate()` and\nrewrites to `Predicate.not(lambdaOrMethodRef)`.\n\n* Regenerate `recipes.csv`\n\n* Use `Expression.unwrap()` in `UsePredicateNot`",
          "is_bot": false,
          "headline": "Add `UsePredicateNot` to replace cast-and-negate with `Predicate.not(…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-04-24T07:10:06Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a58b8b2a8545391ecb83323645ee9f400a67d0a6",
          "body": "…ctToSwitch` (#1071)\n\nGuarantee a single space between `case` and the pattern label when the\nlabel prefix is empty and the type expression has no leading whitespace,\nso the printed switch is always well-formed (e.g. `case Type name` rather\nthan `caseType name`).\n\nSee https://github.com/openrewrite/rewrite/issues/7458",
          "is_bot": false,
          "headline": "Ensure `case` always has a space before the label in `IfElseIfConstru…",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-04-23T13:45:48Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "eac4344ef723d96e282bb2f891f80da7bd0cbc70",
          "body": "…xts (#1067)\n\nThe `MigrateCollections{Empty,Singleton,Unmodifiable}*` family applied\n`JavaTemplate` in `.contextSensitive()` mode. When the\n`Collections.emptyList()` (etc.) call sat inside a switch expression\n(`case 0 -> Collections.emptyList()`), a ternary branch, a method\nargument, or similar non-\n[…]\nscore` and `IfElseIfConstructToSwitch` —\nsince `JavaTemplate` cannot reliably target non-Java trees, and the\nidiomatic replacement in Kotlin (`emptyList()`) and Groovy (`[]`) isn't\n`List.of()` anyway.",
          "is_bot": false,
          "headline": "Fix `MigrateCollections*` template errors on complex expression conte…",
          "author_name": "Knut Wannheden",
          "author_login": "knutwannheden",
          "committed_at": "2026-04-21T08:56:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0ca5cc837f6228869e1e03c886293351c5387cae",
          "body": "Use this link to re-run the recipe: https://app.moderne.io/recipes/org.openrewrite.java.recipes.ExamplesExtractor?organizationId=QUxML09wZW4gU291cmNlL09wZW5SZXdyaXRl\n\nCo-authored-by: Moderne <team@moderne.io>",
          "is_bot": false,
          "headline": "Extract documentation examples from tests",
          "author_name": "Greg Oledzki",
          "author_login": "greg-at-moderne",
          "committed_at": "2026-04-21T07:05:04Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "968a22fcf44767f0e731a5f4987a8efc4fa8ee78",
          "body": null,
          "is_bot": false,
          "headline": "Gate Kotlin-based Java version cap on actual Kotlin sources (#1066)",
          "author_name": "Tim te Beek",
          "author_login": "timtebeek",
          "committed_at": "2026-04-20T16:50:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        }
      ],
      "releases_count": 100,
      "commits_last_year": 411,
      "latest_release_at": "2026-07-14T05:53:34Z",
      "latest_release_tag": "v3.40.0",
      "releases_from_tags": false,
      "days_since_last_push": 0,
      "active_weeks_last_year": 52,
      "days_since_latest_release": 11,
      "mean_days_between_releases": 9.3
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": true,
      "health_percentage": 62,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": true
    },
    "ecosystem": {
      "packages": []
    },
    "popularity": {
      "forks": 123,
      "stars": 153,
      "watchers": 9,
      "fork_history": {
        "days": [
          {
            "date": "2021-09-27",
            "count": 1
          },
          {
            "date": "2022-02-03",
            "count": 1
          },
          {
            "date": "2022-04-07",
            "count": 1
          },
          {
            "date": "2022-06-30",
            "count": 1
          },
          {
            "date": "2022-11-04",
            "count": 1
          },
          {
            "date": "2022-12-01",
            "count": 1
          },
          {
            "date": "2022-12-22",
            "count": 1
          },
          {
            "date": "2023-01-05",
            "count": 1
          },
          {
            "date": "2023-01-08",
            "count": 1
          },
          {
            "date": "2023-01-18",
            "count": 1
          },
          {
            "date": "2023-01-31",
            "count": 1
          },
          {
            "date": "2023-02-05",
            "count": 1
          },
          {
            "date": "2023-03-25",
            "count": 1
          },
          {
            "date": "2023-03-30",
            "count": 1
          },
          {
            "date": "2023-04-18",
            "count": 1
          },
          {
            "date": "2023-04-26",
            "count": 1
          },
          {
            "date": "2023-05-01",
            "count": 1
          },
          {
            "date": "2023-05-09",
            "count": 1
          },
          {
            "date": "2023-05-12",
            "count": 1
          },
          {
            "date": "2023-05-16",
            "count": 1
          },
          {
            "date": "2023-05-18",
            "count": 1
          },
          {
            "date": "2023-06-13",
            "count": 1
          },
          {
            "date": "2023-06-14",
            "count": 1
          },
          {
            "date": "2023-07-22",
            "count": 1
          },
          {
            "date": "2023-08-02",
            "count": 1
          },
          {
            "date": "2023-08-24",
            "count": 1
          },
          {
            "date": "2023-08-30",
            "count": 1
          },
          {
            "date": "2023-08-31",
            "count": 1
          },
          {
            "date": "2023-09-21",
            "count": 1
          },
          {
            "date": "2023-10-06",
            "count": 1
          },
          {
            "date": "2023-10-14",
            "count": 1
          },
          {
            "date": "2023-10-20",
            "count": 1
          },
          {
            "date": "2023-11-09",
            "count": 1
          },
          {
            "date": "2023-11-18",
            "count": 1
          },
          {
            "date": "2023-11-22",
            "count": 1
          },
          {
            "date": "2023-11-28",
            "count": 1
          },
          {
            "date": "2023-12-08",
            "count": 1
          },
          {
            "date": "2023-12-09",
            "count": 1
          },
          {
            "date": "2024-01-08",
            "count": 1
          },
          {
            "date": "2024-01-10",
            "count": 1
          },
          {
            "date": "2024-01-12",
            "count": 1
          },
          {
            "date": "2024-01-22",
            "count": 1
          },
          {
            "date": "2024-02-01",
            "count": 1
          },
          {
            "date": "2024-02-14",
            "count": 1
          },
          {
            "date": "2024-02-18",
            "count": 1
          },
          {
            "date": "2024-03-16",
            "count": 1
          },
          {
            "date": "2024-03-23",
            "count": 1
          },
          {
            "date": "2024-03-29",
            "count": 1
          },
          {
            "date": "2024-04-02",
            "count": 1
          },
          {
            "date": "2024-04-03",
            "count": 1
          },
          {
            "date": "2024-04-14",
            "count": 1
          },
          {
            "date": "2024-04-16",
            "count": 1
          },
          {
            "date": "2024-04-19",
            "count": 1
          },
          {
            "date": "2024-04-22",
            "count": 1
          },
          {
            "date": "2024-05-22",
            "count": 1
          },
          {
            "date": "2024-06-03",
            "count": 1
          },
          {
            "date": "2024-06-24",
            "count": 2
          },
          {
            "date": "2024-07-02",
            "count": 1
          },
          {
            "date": "2024-07-26",
            "count": 2
          },
          {
            "date": "2024-09-10",
            "count": 1
          },
          {
            "date": "2024-09-11",
            "count": 1
          },
          {
            "date": "2024-09-15",
            "count": 1
          },
          {
            "date": "2024-09-18",
            "count": 1
          },
          {
            "date": "2024-09-30",
            "count": 1
          },
          {
            "date": "2024-10-11",
            "count": 1
          },
          {
            "date": "2024-11-04",
            "count": 1
          },
          {
            "date": "2024-11-21",
            "count": 1
          },
          {
            "date": "2024-12-07",
            "count": 1
          },
          {
            "date": "2024-12-08",
            "count": 1
          },
          {
            "date": "2024-12-23",
            "count": 1
          },
          {
            "date": "2025-01-05",
            "count": 1
          },
          {
            "date": "2025-02-17",
            "count": 1
          },
          {
            "date": "2025-02-18",
            "count": 1
          },
          {
            "date": "2025-03-24",
            "count": 1
          },
          {
            "date": "2025-04-02",
            "count": 1
          },
          {
            "date": "2025-04-11",
            "count": 1
          },
          {
            "date": "2025-04-16",
            "count": 1
          },
          {
            "date": "2025-05-09",
            "count": 1
          },
          {
            "date": "2025-05-10",
            "count": 1
          },
          {
            "date": "2025-05-12",
            "count": 1
          },
          {
            "date": "2025-05-19",
            "count": 1
          },
          {
            "date": "2025-05-25",
            "count": 1
          },
          {
            "date": "2025-06-02",
            "count": 1
          },
          {
            "date": "2025-06-06",
            "count": 1
          },
          {
            "date": "2025-06-10",
            "count": 1
          },
          {
            "date": "2025-06-20",
            "count": 1
          },
          {
            "date": "2025-06-26",
            "count": 1
          },
          {
            "date": "2025-07-23",
            "count": 1
          },
          {
            "date": "2025-07-26",
            "count": 1
          },
          {
            "date": "2025-08-07",
            "count": 1
          },
          {
            "date": "2025-08-13",
            "count": 1
          },
          {
            "date": "2025-08-22",
            "count": 1
          },
          {
            "date": "2025-09-17",
            "count": 1
          },
          {
            "date": "2025-10-08",
            "count": 1
          },
          {
            "date": "2025-10-24",
            "count": 1
          },
          {
            "date": "2025-10-26",
            "count": 1
          },
          {
            "date": "2025-11-06",
            "count": 1
          },
          {
            "date": "2025-11-12",
            "count": 1
          },
          {
            "date": "2025-11-14",
            "count": 2
          },
          {
            "date": "2025-11-21",
            "count": 1
          },
          {
            "date": "2025-12-10",
            "count": 1
          },
          {
            "date": "2025-12-12",
            "count": 1
          },
          {
            "date": "2025-12-19",
            "count": 1
          },
          {
            "date": "2026-01-20",
            "count": 1
          },
          {
            "date": "2026-02-07",
            "count": 1
          },
          {
            "date": "2026-02-17",
            "count": 1
          },
          {
            "date": "2026-03-05",
            "count": 1
          },
          {
            "date": "2026-03-26",
            "count": 1
          },
          {
            "date": "2026-03-28",
            "count": 1
          },
          {
            "date": "2026-03-30",
            "count": 1
          },
          {
            "date": "2026-04-03",
            "count": 1
          },
          {
            "date": "2026-04-15",
            "count": 1
          },
          {
            "date": "2026-04-20",
            "count": 1
          },
          {
            "date": "2026-05-28",
            "count": 1
          },
          {
            "date": "2026-06-05",
            "count": 1
          },
          {
            "date": "2026-06-14",
            "count": 1
          },
          {
            "date": "2026-06-29",
            "count": 1
          },
          {
            "date": "2026-07-03",
            "count": 1
          },
          {
            "date": "2026-07-11",
            "count": 1
          }
        ],
        "complete": true,
        "collected": 122,
        "total_forks": 123
      },
      "star_history": null,
      "open_issues_and_prs": 37
    },
    "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": [
        "build.gradle.kts"
      ],
      "largest_source_bytes": 142015,
      "source_files_sampled": 488,
      "oversized_source_files": 3,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "build.gradle.kts"
      ],
      "advisories": {
        "error": "No resolved dependencies to assess",
        "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": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "maven"
      ],
      "dependencies": [],
      "all_dependencies": {
        "error": null,
        "source": "github-sbom",
        "packages": [],
        "collected": true,
        "truncated": false,
        "total_count": 0,
        "direct_count": 0,
        "indirect_count": 0
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 1,
        "merged_prs": 690,
        "open_issues": 36,
        "closed_ratio": 0.901,
        "closed_issues": 329,
        "closed_unmerged_prs": 77
      },
      "bus_factor": 4,
      "bot_contributors": 2,
      "top_contributors": [
        {
          "type": "User",
          "login": "timtebeek",
          "commits": 498,
          "avatar_url": "https://avatars.githubusercontent.com/u/1027334?v=4"
        },
        {
          "type": "User",
          "login": "jkschneider",
          "commits": 134,
          "avatar_url": "https://avatars.githubusercontent.com/u/1697736?v=4"
        },
        {
          "type": "User",
          "login": "aegershman",
          "commits": 101,
          "avatar_url": "https://avatars.githubusercontent.com/u/5619476?v=4"
        },
        {
          "type": "User",
          "login": "TeamModerne",
          "commits": 72,
          "avatar_url": "https://avatars.githubusercontent.com/u/85364911?v=4"
        },
        {
          "type": "User",
          "login": "knutwannheden",
          "commits": 66,
          "avatar_url": "https://avatars.githubusercontent.com/u/408765?v=4"
        },
        {
          "type": "User",
          "login": "traceyyoshima",
          "commits": 63,
          "avatar_url": "https://avatars.githubusercontent.com/u/16889475?v=4"
        },
        {
          "type": "User",
          "login": "tkvangorder",
          "commits": 57,
          "avatar_url": "https://avatars.githubusercontent.com/u/1878529?v=4"
        },
        {
          "type": "User",
          "login": "sambsnyd",
          "commits": 52,
          "avatar_url": "https://avatars.githubusercontent.com/u/8549033?v=4"
        },
        {
          "type": "User",
          "login": "pway99",
          "commits": 36,
          "avatar_url": "https://avatars.githubusercontent.com/u/22326988?v=4"
        },
        {
          "type": "User",
          "login": "evie-lau",
          "commits": 27,
          "avatar_url": "https://avatars.githubusercontent.com/u/689163?v=4"
        }
      ],
      "contributors_sampled": 98,
      "top_contributor_share": 0.327
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "publish.yml",
        "repository-backup.yml",
        "sdkman-candidates.yml",
        "stale.yml"
      ],
      "has_docs_dir": false,
      "linter_configs": [],
      "has_editorconfig": true,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 9,
            "reason": "binaries present in source code",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "24 out of 24 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 3,
            "reason": "Found 10/30 approved changesets -- score normalized to 3",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 10,
            "reason": "project has 19 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": 10,
            "reason": "update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 9,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 10,
            "reason": "30 commit(s) and 19 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": null,
            "reason": "packaging workflow not 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": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": 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": "7c45df7add66d4df1f3253c0846e740832d4caca",
        "ran_at": "2026-07-25T17:13:53Z",
        "aggregate_score": 5.3,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": true
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-24T21:39:59Z",
      "oldest_open_prs": [
        {
          "number": 1162,
          "created_at": "2026-07-03T18:01:28Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ],
      "last_merged_pr_at": "2026-07-24T21:36:44Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": [
        {
          "number": 28,
          "created_at": "2021-06-14T17:28:00Z",
          "last_comment_at": "2021-08-23T18:05:39Z",
          "last_comment_author": "pway99"
        },
        {
          "number": 71,
          "created_at": "2022-03-31T23:26:48Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 86,
          "created_at": "2022-04-06T18:29:55Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 91,
          "created_at": "2022-04-15T04:53:10Z",
          "last_comment_at": "2026-06-17T10:48:52Z",
          "last_comment_author": "Ouokki"
        },
        {
          "number": 108,
          "created_at": "2022-05-16T22:06:46Z",
          "last_comment_at": "2022-05-18T20:05:13Z",
          "last_comment_author": "tkvangorder"
        },
        {
          "number": 110,
          "created_at": "2022-06-14T15:36:53Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 113,
          "created_at": "2022-06-21T13:46:23Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 116,
          "created_at": "2022-08-04T17:46:19Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 147,
          "created_at": "2022-11-14T20:28:03Z",
          "last_comment_at": "2022-12-29T20:57:41Z",
          "last_comment_author": "jkschneider"
        },
        {
          "number": 148,
          "created_at": "2022-12-03T20:00:23Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 155,
          "created_at": "2022-12-16T18:30:35Z",
          "last_comment_at": "2022-12-22T19:36:51Z",
          "last_comment_author": "tkvangorder"
        },
        {
          "number": 261,
          "created_at": "2023-04-02T07:30:10Z",
          "last_comment_at": "2023-08-29T12:54:10Z",
          "last_comment_author": "jbessels"
        },
        {
          "number": 208,
          "created_at": "2023-04-14T19:29:45Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 1048,
          "created_at": "2023-04-17T14:26:32Z",
          "last_comment_at": "2023-04-17T14:33:36Z",
          "last_comment_author": "timtebeek"
        },
        {
          "number": 512,
          "created_at": "2023-04-24T17:28:10Z",
          "last_comment_at": "2024-07-14T18:39:02Z",
          "last_comment_author": "timtebeek"
        },
        {
          "number": 1047,
          "created_at": "2023-04-24T17:39:02Z",
          "last_comment_at": "2024-10-20T16:09:33Z",
          "last_comment_author": "timo-a"
        },
        {
          "number": 1046,
          "created_at": "2023-04-24T17:44:06Z",
          "last_comment_at": null,
          "last_comment_author": null
        },
        {
          "number": 780,
          "created_at": "2023-05-07T15:43:44Z",
          "last_comment_at": "2023-12-13T10:24:34Z",
          "last_comment_author": "nitschSB"
        },
        {
          "number": 236,
          "created_at": "2023-06-12T06:41:56Z",
          "last_comment_at": "2023-07-07T08:40:05Z",
          "last_comment_author": "MBoegers"
        },
        {
          "number": 237,
          "created_at": "2023-06-13T07:08:36Z",
          "last_comment_at": null,
          "last_comment_author": null
        }
      ]
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/openrewrite/rewrite-migrate-java",
    "host": "github.com",
    "name": "rewrite-migrate-java",
    "owner": "openrewrite"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "good",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 74,
      "inputs": {
        "security": 53,
        "vitality": 100,
        "community": 64,
        "governance": 80,
        "engineering": 64
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "excellent",
        "name": "Vitality",
        "value": 100,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "excellent",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "commits_last_year": 411,
              "human_commit_share": 0.91,
              "days_since_last_push": 0,
              "active_weeks_last_year": 52
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 0 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "52/52 weeks with commits",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 52
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "411 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 411
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "30 commit(s) and 19 issue activity found in the last 90 days -- score normalized to 10",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 100,
              "latest_release_tag": "v3.40.0",
              "releases_from_tags": false,
              "days_since_latest_release": 11,
              "mean_days_between_releases": 9.3
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "100 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 100
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 11 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 11
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~9.3 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 9.3
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "maintained",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": null,
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": 0,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "last human commit 0 days ago",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_maintained",
                    "params": {
                      "days": 0
                    }
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "moderate",
        "name": "Community & Adoption",
        "value": 64,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "moderate",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 58,
            "inputs": {
              "forks": 123,
              "stars": 153,
              "watchers": 9,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "153 stars",
                "points": 35.4,
                "status": "partial",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 153
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "123 forks",
                "points": 17.4,
                "status": "partial",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 123
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "9 watchers",
                "points": 5,
                "status": "partial",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 9
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "good",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 71,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": true,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file present, not a recognized license",
                "points": 16.9,
                "status": "partial",
                "details": [
                  {
                    "code": "license_custom",
                    "params": {}
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 18,
                "status": "met",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 6.3,
                "status": "met",
                "details": [],
                "max_points": 6.3
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "good",
        "name": "Sustainability & Governance",
        "value": 80,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "good",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 82,
            "inputs": {
              "bus_factor": 4,
              "contributors_sampled": 98,
              "top_contributor_share": 0.327
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "4 contributor(s) cover half of all commits",
                "points": 43.2,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 4
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 33% of commits",
                "points": 15.1,
                "status": "partial",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 33
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "98 contributors",
                "points": 13.5,
                "status": "met",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 98
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 19 contributing companies or organizations",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": null,
            "notes": [],
            "value": 81,
            "inputs": {
              "merged_prs": 690,
              "open_issues": 36,
              "closed_issues": 329,
              "issue_closed_ratio": 0.901,
              "closed_unmerged_prs": 77
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "90% of issues closed",
                "points": 42.1,
                "status": "partial",
                "details": [
                  {
                    "code": "issues_closed_share",
                    "params": {
                      "share": 90
                    }
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "690/767 decided PRs merged",
                "points": 34.4,
                "status": "partial",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 690,
                      "decided": 767
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 10/30 approved changesets -- score normalized to 3",
                "points": 4.5,
                "status": "partial",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "good",
            "name": "Ownership & stewardship",
            "note": null,
            "notes": [],
            "value": 76,
            "inputs": {
              "followers": 984,
              "owner_type": "Organization",
              "is_verified": null,
              "owner_login": "openrewrite",
              "public_repos": 75,
              "account_age_days": 2341
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "organization-owned",
                "points": 30,
                "status": "met",
                "details": [
                  {
                    "code": "owner_organization",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "984 followers of openrewrite",
                "points": 21.5,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 984,
                      "login": "openrewrite"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "75 public repos, account ~6 yr old",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 75
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 6
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "moderate",
        "name": "Engineering Quality",
        "value": 64,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "good",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 74,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": true,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "5 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 5
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 6.4,
                "status": "met",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "24 out of 24 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "moderate",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "topics": [
                "openrewrite",
                "openrewrite-recipes"
              ],
              "has_wiki": false,
              "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": "2 topics",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "topics_count",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "moderate",
        "name": "Security",
        "value": 53,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "moderate",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 53,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 5.3
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "binaries present in source code",
                "points": 6.8,
                "status": "partial",
                "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": "24 out of 24 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 10/30 approved changesets -- score normalized to 3",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 19 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": "update tool detected",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.2,
                "status": "partial",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "30 commit(s) and 19 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 not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "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": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "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": 16
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 56,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 0.923,
              "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": "84 of 91 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 84,
                      "sampled": 91
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 51,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [],
              "agent_commit_share": 0,
              "toolchain_manifests": [
                "build.gradle.kts"
              ],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": "build.gradle.kts (toolchain convention, no task runner)",
                "points": 12.6,
                "status": "partial",
                "details": [
                  {
                    "code": "toolchain_convention",
                    "params": {
                      "files": "build.gradle.kts"
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "Java (statically typed)",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Java"
                    }
                  }
                ],
                "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": "dependency automation configured, none observed in the sampled commits",
                "points": 5,
                "status": "partial",
                "details": [
                  {
                    "code": "dependency_bot_config_only",
                    "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": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "primary_language": "Java",
              "largest_source_bytes": 142015,
              "source_files_sampled": 488,
              "oversized_source_files": 3
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "Java (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "Java"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "3/488 source files over 60KB",
                "points": 54.7,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 488,
                      "oversized": 3
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "Star history unavailable: GitHub GraphQL error: Resource not accessible by personal access token"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-25T17:14:17.842608Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/o/openrewrite/rewrite-migrate-java.svg",
  "full_name": "openrewrite/rewrite-migrate-java",
  "license_state": "custom",
  "license_spdx": null
}

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

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

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