Public record
Software health reportschema 0.27.0 · metrics 1.13.0 · 2026-07-25 17:14 UTC

openrewrite / rewrite-migrate-java

OpenRewrite recipes for migrating to newer versions of Java.

JavaCustom license★ 153 stars⑂ 123 forkssince Mar 2021View on GitHub ↗

openrewrite/rewrite-migrate-java holds a health index of 74 out of 100, placing it in the Good band. It scores highest on Vitality (100/100) and lowest on Security (53/100). It was last updated today. 4 contributors account for most of its recent work.

74
overall / 100
Good

Software health index

Metrics are grouped into weighted categories on one standardized 1–100 scale. Overall starts as their weighted mean; when public evidence triggers the High-Risk Jurisdiction Policy, the rating is adjusted and receives an At risk ceiling of 49. AI Readiness sits outside the overall score.

74
Excellent85-100Exemplary; meets essentially all checked criteria
Good70-84Healthy; minor gaps
Moderate50-69Acceptable with notable gaps; review recommended
At risk30-49Significant weaknesses; adoption warrants caution
Critical1-29Severe problems (abandoned, single-maintainer, no hygiene)
VitalityCommunity &AdoptionSustainability &GovernanceEngineeringQualitySecurityAI Readiness

Score profile

Each axis is a category. The shape matters more than the average — a healthy subject fills the whole shape, while a spike-and-crater profile means strength in one dimension is masking risk in another.

Ownership

OpenRewriteOrganization
984 followers75 public repossince Feb 2020

This repository is backed by an organization — shared, accountable stewardship that can outlive any single maintainer.

Metrics by category

Vitality

Is the project alive — is code being written and are releases shipping?

100Excellent · 22% of overall
How it's scored
36/36Push recency — last push 0 days ago
36/36Commit cadence — 52/52 weeks with commits
18/18Commit volume — 411 commits in the last year
10/10OpenSSF Scorecard: Maintained — 30 commit(s) and 19 issue activity found in the last 90 days -- score normalized to 10
Inputs used
commits_last_year411
human_commit_share0.91
days_since_last_push0
active_weeks_last_year52

Release discipline

100Excellent
How it's scored
27/27Ships releases — 100 releases published
36/36Release recency — latest release 11 days ago
27/27Release cadence — a release every ~9.3 days
0/10OpenSSF Scorecard: Signed-Releases — no data
Inputs used
releases_count100
latest_release_tagv3.40.0
releases_from_tagsno
days_since_latest_release11
mean_days_between_releases9.3
Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.

Community & Adoption

Does the project have users, downloads, attention, and a welcoming setup for contributors?

64Moderate · 18% of overall
How it's scored
35.4/60Stars — 153 stars
17.4/25Forks — 123 forks
5/15Watchers — 9 watchers
Inputs used
forks123
stars153
watchers9
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
How it's scored
22.5/22.5README
16.9/22.5License — license file present, not a recognized license
18/18CONTRIBUTING guide
0/13.5Code of conduct
0/7.2Issue template
6.3/6.3PR template
Inputs used
has_readmeyes
has_licenseyes
has_contributingyes
has_issue_templateno
has_code_of_conductno
has_pull_request_templateyes

Sustainability & Governance

Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?

80Good · 24% of overall
How it's scored
43.2/54Bus factor — 4 contributor(s) cover half of all commits
15.1/22.5Commit distribution — top contributor authored 33% of commits
13.5/13.5Contributor breadth — 98 contributors
10/10OpenSSF Scorecard: Contributors — project has 19 contributing companies or organizations
Inputs used
bus_factor4
contributors_sampled98
top_contributor_share0.327
How it's scored
42.1/46.8Issue resolution — 90% of issues closed
34.4/38.3PR acceptance — 690/767 decided PRs merged
4.5/15OpenSSF Scorecard: Code-Review — Found 10/30 approved changesets -- score normalized to 3
Inputs used
merged_prs690
open_issues36
closed_issues329
issue_closed_ratio0.901
closed_unmerged_prs77
How it's scored
30/30Ownership backing — organization-owned
0/20Verified domain
21.5/25Owner reach — 984 followers of openrewrite
25/25Track record — 75 public repos, account ~6 yr old
Inputs used
followers984
owner_typeOrganization
is_verified
owner_loginopenrewrite
public_repos75
account_age_days2,341

Engineering Quality

Are baseline engineering and documentation practices in place?

64Moderate · 20% of overall
How it's scored
24/24CI workflows — 5 workflow(s)
24/24Tests present
0/16Linter config
0/9.6Pre-commit hooks
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
Inputs used
has_ciyes
has_testsyes
has_editorconfigyes
has_linter_configno
has_precommit_configno

Documentation

50Moderate
How it's scored
30/30README
0/25Documentation directory
0/15Documentation / homepage site
10/10Repository description
10/10Topics — 2 topics
0/10Wiki
Inputs used
topicsopenrewrite, openrewrite-recipes
has_wikino
homepage
has_readmeyes
has_docs_dirno
has_descriptionyes

Security

Are visible security and supply-chain practices strong, without unresolved high-risk jurisdiction exposure?

53Moderate · 16% of overall
How it's scored
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.5License — 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 — no data
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 — no data
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
7.5/7.5Vulnerabilities — 0 existing vulnerabilities detected
Inputs used
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate5.3
Excluded from scoring (no data or not applicable): packaging, signed_releases. Remaining weights renormalized.

AI Readiness

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.

56Moderate · 0% of overall
How it's scored
0/45Agent instructions — no CLAUDE.md / AGENTS.md / editor rules
0/15Machine-readable docs (llms.txt)
40/40Legible commit history — 84 of 91 human commits state their intent (structured subject or explanatory body)
Inputs used
has_llms_txtno
legible_history_share0.923
agent_instruction_files
agent_instruction_max_bytes
How it's scored
12.6/18One-command bootstrap — build.gradle.kts (toolchain convention, no task runner)
22/22Automated tests
0/11Lint / format config
11/11Static type checking — Java (statically typed)
0/10Reproducible environment
0/10Demonstrated agent practice — no agent-authored commits among the last 100
5/8Automated maintenance — dependency automation configured, none observed in the sampled commits
0/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 0
Inputs used
has_nixno
has_testsyes
lockfiles
has_dockerfileno
typed_languageyes
bootstrap_files
has_devcontainerno
has_linter_configno
typecheck_configs
agent_commit_share0
toolchain_manifestsbuild.gradle.kts
dependency_bot_commit_share0
How it's scored
45/45Type-checkable code — Java (statically typed)
54.7/55Manageable file sizes — 3/488 source files over 60KB
Inputs used
primary_languageJava
largest_source_bytes142,015
source_files_sampled488
oversized_source_files3

Key facts

153GitHub stars
98contributors
411commits, last 12 months
0days since last push
100releases
4bus factor
36open issues
Mavenpackage ecosystems

Data collection warnings

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

More detail

Star and fork history 0 ★ / 123 ⇿
0Stars
123Forks
99Releases

When each star and fork was added, collected from GitHub and bucketed by day. Cumulative growth sits directly above the daily additions it is made of, so the two read against each other: steady organic accretion looks nothing like an abrupt, short-lived burst. Where that difference is measurable, it is reported as growth authenticity.

025507510012512232021-092024-022026-07
Major 1Minor 69Patch 29

Each point covers 5 days.

OpenSSF Scorecard 5.3 / 10
5.3aggregate

Independent, tool-agnostic security assessment from the open-source OpenSSF Scorecard. Each check rewards a security practice, not a specific vendor's tool. Checks Scorecard could not determine are marked n/a and excluded from the security score (never counted as zero).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/aPackagingpackaging 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/aSigned-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
10Vulnerabilities0 existing vulnerabilities detected
All dependencies 0

Full resolved dependency set from the GitHub dependency graph: 0 direct and 0 indirect (transitive) packages. The transitive closure is complete when the repository commits a lockfile.

RegistryPackageVersionRelation
Dependency advisories not assessed

Advisory matching could not run for this report: No resolved dependencies to assess

Raw JSON report machine-readable
{
  "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
}

Scores are signals, not warranties. They reflect publicly visible practices on GitHub — not a code audit, and not a security guarantee.

Missing data is excluded and weights renormalized, never scored as zero. Methodology is versioned and open: metrics v1.13.0, schema v0.27.0 — full methodology · metrics wiki.

How one result sits in the wider record: aggregate statistics.