Skip to content

SONARJAVA-6205 Add an agentic focused quality profile for Java#5531

Open
dorian-burihabwa-sonarsource wants to merge 7 commits intomasterfrom
SONARJAVA-6205
Open

SONARJAVA-6205 Add an agentic focused quality profile for Java#5531
dorian-burihabwa-sonarsource wants to merge 7 commits intomasterfrom
SONARJAVA-6205

Conversation

@dorian-burihabwa-sonarsource
Copy link
Copy Markdown
Contributor

No description provided.

@hashicorp-vault-sonar-prod
Copy link
Copy Markdown
Contributor

hashicorp-vault-sonar-prod bot commented Mar 20, 2026

SONARJAVA-6205

@dorian-burihabwa-sonarsource dorian-burihabwa-sonarsource force-pushed the SONARJAVA-6205 branch 2 times, most recently from 37eb8d7 to 0dab089 Compare March 20, 2026 15:29
@dorian-burihabwa-sonarsource dorian-burihabwa-sonarsource marked this pull request as ready for review March 20, 2026 15:56
@sonar-review-alpha
Copy link
Copy Markdown

sonar-review-alpha bot commented Mar 20, 2026

Summary

This PR refactors quality profile handling and adds a new "Sonar agentic AI" profile focused on AI-assisted development.

Key Changes:

  1. New base class BuiltInJavaQualityProfile: Consolidates common profile logic (JSON loading, ProfileRegistrar integration, security rule reflection) that was previously duplicated in JavaSonarWayProfile
  2. Removed DBD reflection: The dataflow-bug-detection rules are now loaded automatically via ProfileRegistrar instead of reflection, simplifying the code
  3. Refactored JavaSonarWayProfile: Now extends the base class, reducing ~40 lines of duplicate code while maintaining identical behavior
  4. Added JavaAgenticWayProfile: A new quality profile with 467 rules curated for AI-assisted development, registered alongside the existing Sonar Way profile
  5. Updated tests: Changed method invocations from static to instance methods, removed DBD-specific test, added comprehensive test for the new agentic profile including a CSV utility method

What reviewers should know

Where to start:

  • Review BuiltInJavaQualityProfile.java first — this is the new abstraction layer
  • Check how JavaSonarWayProfile.java is simplified by extending it
  • Review JavaAgenticWayProfile.java to understand the new profile implementation
  • Check Sonar_agentic_ai_profile.json to see the 467 selected rules

Non-obvious decisions:

  • Security rules still use reflection (line 78-84) with a FIXME pointing to SONARJAVA-6207 for future removal — this is a known limitation
  • The disabled test utility (generate_ai_quality_profile) shows how the agentic rule set was generated from CSV; reviewers may want to understand the curation criteria
  • ProfileRegistrars now handle DBD rules automatically, so that reflection code was intentionally removed

Things to verify:

  • The 467 rules in the agentic profile are appropriate for AI/agent-assisted development (check if the selection aligns with coding quality vs. style)
  • Ensure backward compatibility: Sonar Way remains the default profile and hasn't changed functionally
  • Test counts in JavaPluginTest were updated from 36→37 and 37→38; verify this matches the added extensions
  • The commons-csv dependency is only in tests (appropriate for the CSV generation utility)

  • Generate Walkthrough
  • Generate Diagram

🗣️ Give feedback

sonar-review-alpha[bot]

This comment was marked as resolved.

@rombirli rombirli self-requested a review March 23, 2026 06:52
Copy link
Copy Markdown
Contributor

@rombirli rombirli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I just have two questions about external rules inclusion mechanism and the purpose of profileRegistrars

Comment on lines +39 to +41
for (ProfileRegistrar profileRegistrar : profileRegistrars) {
profileRegistrar.register(ruleKeys::addAll);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In test JavaAgenticWayProfileTest, profileRegistrars is always null and this part is never covered, is there a reason ?

public void define(Context context) {
NewBuiltInQualityProfile agenticWay = context.createBuiltInQualityProfile("AI Quality Profile", Java.KEY);
Set<RuleKey> ruleKeys = QualityProfileUtils.registerRulesFromJson(
"/org/sonar/l10n/java/rules/java/Agentic_way_profile.json",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This string constant could be extracted in a constant SONAR_AGENTIC_WAY_PATH like SONAR_WAY_PATH in JavaSonarWayProfile

Comment on lines +49 to +51
ruleKeys.forEach(ruleKey -> agenticWay.activateRule(ruleKey.repository(), ruleKey.rule()));
agenticWay.done();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines and the creation of agenticWay (or sonarWay) are repeated in JavaSonarWayProfile, maybe it could be refactored in QualityProfileUtils

static void createQualityProfile(String title, Set<RuleKey> ruleKeys) {
  NewBuiltInQualityProfile way = context.createBuiltInQualityProfile(title, Java.KEY);
  ruleKeys.forEach(ruleKey -> way.activateRule(ruleKey.repository(), ruleKey.rule()));
    way.done();
  }
}

Comment on lines 76 to 78
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this mechanism to include external rules is not present in JavaAgenticWayProfile? (Why the implementations diverge? Is there a justification?)

Copy link
Copy Markdown
Contributor

@rombirli rombirli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agentic_way_profile.json seems to be wrong

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this file auto-generated from the CSV with a script? Could we add the script to the repo? It seems to be wrong!
S100 shouldn't be included according to the spreadsheet.

Image

Copy link
Copy Markdown
Contributor

@rombirli rombirli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM i get the exact same json quality profile file, I still have 2 refactoring proposals :

  • use tsv format instead of csv to get rid of csv library (so we can simply split with '\t' instead of ';')
  • use a single class that take qp name and json path instead of duplicated logic (we could also get rid of qualityprofileutils.java and put everything in this class)

Copy link
Copy Markdown

@sonar-review-alpha sonar-review-alpha bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conclusion: Clean refactoring overall — the base class extraction is well-done and the agentic profile is properly wired up. Two issues in the generator utility method worth fixing before someone uses it to regenerate the profile.

🗣️ Give feedback

return fileName.substring(0, fileName.lastIndexOf('.'));
})
.collect(Collectors.toSet());
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path.endsWith(String) does not work like String.endsWith(String). On a Path, it checks whether the path ends with a complete path segment named exactly "_profile.json", not whether the filename string ends with that suffix. This predicate is always false, so profile JSON files (Sonar_way_profile.json, Agentic_way_profile.json, etc.) are never excluded from keysOfImplementedRules.

The bug is harmless today because profile filenames won't appear as rule IDs in the CSV, but the filter silently does nothing. Fix:

.filter(path -> !path.getFileName().toString().endsWith("_profile.json"))
  • Mark as noise

Path.of("Path", "to", "your", "input.csv"),
RULE_DESCRIPTION_DIRECTORY.resolve("Agentic_way_profile.json"),
"AI Quality Profile"
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate_ai_quality_profile() is missing @Test. In JUnit 5, @Disabled without @Test is a no-op — the framework never discovers the method, so the annotation provides no documentation value and could mislead a future developer into thinking this was intentionally skipped rather than just a utility method. Either add @Test so @Disabled works as intended, or remove @Disabled and leave it as a plain utility method with a descriptive Javadoc comment.

  • Mark as noise

sonar-review-alpha[bot]

This comment was marked as resolved.

sonar-review-alpha[bot]

This comment was marked as outdated.

sonar-review-alpha[bot]

This comment was marked as outdated.

sonar-review-alpha[bot]

This comment was marked as outdated.

DBD registers rules using ProfileRegistrar defined in the sonar-java API
and is therefore automatically loaded into all built-in quality
profiles.
@sonarqube-next
Copy link
Copy Markdown

Copy link
Copy Markdown

@sonar-review-alpha sonar-review-alpha bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! ✅

Solid refactoring with no new bugs. The two previously flagged issues (the Path.endsWith no-op filter and @Disabled without @Test) are the only items to address before merge.

🗣️ Give feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants