Skip to content

Commit 22f8b09

Browse files
benzonicoclaude
andcommitted
Add Agent Quality Profile for security, reliability, and complexity rules
This profile activates 231 rules focused on: - Security vulnerabilities and security hotspots (81 rules) - Reliability issues/bugs (139 rules) - Code complexity metrics (28 rules) The Agent Quality Profile helps maintain code quality for AI agents by enforcing security, reliability, and manageable complexity standards. Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent bde7966 commit 22f8b09

4 files changed

Lines changed: 411 additions & 0 deletions

File tree

create_agent_profile.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to create Agent Quality Profile by filtering rules for security, reliability, and complexity.
4+
"""
5+
import json
6+
import os
7+
from pathlib import Path
8+
9+
def is_security_rule(rule_data):
10+
"""Check if rule is security-related"""
11+
if rule_data.get('type') in ['VULNERABILITY', 'SECURITY_HOTSPOT']:
12+
return True
13+
if 'code' in rule_data and 'impacts' in rule_data['code']:
14+
if 'SECURITY' in rule_data['code']['impacts']:
15+
return True
16+
if 'security' in rule_data.get('tags', []):
17+
return True
18+
return False
19+
20+
def is_reliability_rule(rule_data):
21+
"""Check if rule is reliability-related"""
22+
if rule_data.get('type') == 'BUG':
23+
return True
24+
if 'code' in rule_data and 'impacts' in rule_data['code']:
25+
if 'RELIABILITY' in rule_data['code']['impacts']:
26+
return True
27+
return False
28+
29+
def is_complexity_rule(rule_data):
30+
"""Check if rule is complexity-related"""
31+
tags = rule_data.get('tags', [])
32+
if 'brain-overload' in tags:
33+
return True
34+
if 'complexity' in tags or 'cognitive-complexity' in tags:
35+
return True
36+
37+
# Known complexity rule keys (Python specific)
38+
complexity_rules = ['S3776', 'S1067', 'S107', 'S134', 'S1142', 'S104']
39+
rule_key = rule_data.get('sqKey', '')
40+
if rule_key in complexity_rules:
41+
return True
42+
43+
# Check title for complexity keywords
44+
title = rule_data.get('title', '').lower()
45+
if any(keyword in title for keyword in ['complexity', 'nested', 'parameters', 'too many']):
46+
return True
47+
48+
return False
49+
50+
def main():
51+
rules_dir = Path('python-checks/src/main/resources/org/sonar/l10n/py/rules/python')
52+
53+
if not rules_dir.exists():
54+
print(f"Error: Rules directory not found: {rules_dir}")
55+
return
56+
57+
agent_rule_keys = []
58+
stats = {'security': 0, 'reliability': 0, 'complexity': 0, 'total_rules': 0}
59+
60+
# Process all JSON files
61+
for json_file in sorted(rules_dir.glob('S*.json')):
62+
stats['total_rules'] += 1
63+
try:
64+
with open(json_file, 'r', encoding='utf-8') as f:
65+
rule_data = json.load(f)
66+
67+
rule_key = json_file.stem # Filename without extension
68+
69+
# Check if rule matches any criteria
70+
is_sec = is_security_rule(rule_data)
71+
is_rel = is_reliability_rule(rule_data)
72+
is_comp = is_complexity_rule(rule_data)
73+
74+
if is_sec or is_rel or is_comp:
75+
agent_rule_keys.append(rule_key)
76+
if is_sec:
77+
stats['security'] += 1
78+
if is_rel:
79+
stats['reliability'] += 1
80+
if is_comp:
81+
stats['complexity'] += 1
82+
83+
# Print details for first few rules
84+
if len(agent_rule_keys) <= 10:
85+
print(f"{rule_key}: {rule_data.get('title', 'N/A')}")
86+
print(f" Type: {rule_data.get('type', 'N/A')}, Tags: {rule_data.get('tags', [])}")
87+
print(f" Matched: Security={is_sec}, Reliability={is_rel}, Complexity={is_comp}")
88+
89+
except Exception as e:
90+
print(f"Error processing {json_file}: {e}")
91+
92+
# Sort rule keys for consistency
93+
agent_rule_keys.sort()
94+
95+
# Create the profile JSON
96+
profile_data = {
97+
"name": "Agent Quality Profile",
98+
"ruleKeys": agent_rule_keys
99+
}
100+
101+
output_file = rules_dir / 'Agent_quality_profile.json'
102+
with open(output_file, 'w', encoding='utf-8') as f:
103+
json.dump(profile_data, f, indent=2)
104+
105+
print(f"\n=== Statistics ===")
106+
print(f"Total rules scanned: {stats['total_rules']}")
107+
print(f"Security rules: {stats['security']}")
108+
print(f"Reliability rules: {stats['reliability']}")
109+
print(f"Complexity rules: {stats['complexity']}")
110+
print(f"Total rules in Agent Quality Profile: {len(agent_rule_keys)}")
111+
print(f"\nProfile saved to: {output_file}")
112+
113+
if __name__ == '__main__':
114+
main()
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
{
2+
"name": "Agent Quality Profile",
3+
"ruleKeys": [
4+
"S104",
5+
"S1045",
6+
"S107",
7+
"S108",
8+
"S1142",
9+
"S1143",
10+
"S1172",
11+
"S1226",
12+
"S1244",
13+
"S1313",
14+
"S134",
15+
"S138",
16+
"S1523",
17+
"S1656",
18+
"S1700",
19+
"S1716",
20+
"S1717",
21+
"S1751",
22+
"S1763",
23+
"S1764",
24+
"S1862",
25+
"S2053",
26+
"S2068",
27+
"S2077",
28+
"S2092",
29+
"S2115",
30+
"S2159",
31+
"S2190",
32+
"S2201",
33+
"S2245",
34+
"S2257",
35+
"S2275",
36+
"S2612",
37+
"S2711",
38+
"S2712",
39+
"S2733",
40+
"S2734",
41+
"S2755",
42+
"S2757",
43+
"S2823",
44+
"S2876",
45+
"S3329",
46+
"S3330",
47+
"S3358",
48+
"S3403",
49+
"S3699",
50+
"S3752",
51+
"S3776",
52+
"S3827",
53+
"S3862",
54+
"S3923",
55+
"S3981",
56+
"S3984",
57+
"S3985",
58+
"S4143",
59+
"S4423",
60+
"S4426",
61+
"S4433",
62+
"S4502",
63+
"S4507",
64+
"S4721",
65+
"S4784",
66+
"S4787",
67+
"S4790",
68+
"S4792",
69+
"S4823",
70+
"S4828",
71+
"S4829",
72+
"S4830",
73+
"S5042",
74+
"S5122",
75+
"S5247",
76+
"S5300",
77+
"S5332",
78+
"S5344",
79+
"S5439",
80+
"S5443",
81+
"S5445",
82+
"S5527",
83+
"S5542",
84+
"S5547",
85+
"S5549",
86+
"S5607",
87+
"S5632",
88+
"S5642",
89+
"S5644",
90+
"S5659",
91+
"S5707",
92+
"S5708",
93+
"S5714",
94+
"S5717",
95+
"S5719",
96+
"S5722",
97+
"S5724",
98+
"S5756",
99+
"S5796",
100+
"S5807",
101+
"S5828",
102+
"S5842",
103+
"S5845",
104+
"S5850",
105+
"S5852",
106+
"S5855",
107+
"S5856",
108+
"S5868",
109+
"S5905",
110+
"S5915",
111+
"S5953",
112+
"S5994",
113+
"S5996",
114+
"S6001",
115+
"S6002",
116+
"S6245",
117+
"S6249",
118+
"S6252",
119+
"S6265",
120+
"S6270",
121+
"S6275",
122+
"S6281",
123+
"S6302",
124+
"S6303",
125+
"S6304",
126+
"S6308",
127+
"S6317",
128+
"S6319",
129+
"S6321",
130+
"S6323",
131+
"S6327",
132+
"S6328",
133+
"S6329",
134+
"S6330",
135+
"S6332",
136+
"S6333",
137+
"S6377",
138+
"S6418",
139+
"S6437",
140+
"S6463",
141+
"S6468",
142+
"S6540",
143+
"S6543",
144+
"S6552",
145+
"S6560",
146+
"S6662",
147+
"S6663",
148+
"S6709",
149+
"S6714",
150+
"S6725",
151+
"S6727",
152+
"S6729",
153+
"S6734",
154+
"S6735",
155+
"S6740",
156+
"S6741",
157+
"S6779",
158+
"S6781",
159+
"S6785",
160+
"S6786",
161+
"S6799",
162+
"S6863",
163+
"S6882",
164+
"S6883",
165+
"S6887",
166+
"S6890",
167+
"S6894",
168+
"S6900",
169+
"S6903",
170+
"S6908",
171+
"S6911",
172+
"S6918",
173+
"S6919",
174+
"S6925",
175+
"S6928",
176+
"S6929",
177+
"S6971",
178+
"S6972",
179+
"S6973",
180+
"S6974",
181+
"S6978",
182+
"S6982",
183+
"S6983",
184+
"S6984",
185+
"S6985",
186+
"S7483",
187+
"S7484",
188+
"S7487",
189+
"S7488",
190+
"S7489",
191+
"S7490",
192+
"S7493",
193+
"S7497",
194+
"S7499",
195+
"S7501",
196+
"S7502",
197+
"S7503",
198+
"S7506",
199+
"S7507",
200+
"S7514",
201+
"S7515",
202+
"S7516",
203+
"S7519",
204+
"S7608",
205+
"S7609",
206+
"S7613",
207+
"S7614",
208+
"S7617",
209+
"S7618",
210+
"S7619",
211+
"S7620",
212+
"S7621",
213+
"S7625",
214+
"S7931",
215+
"S7932",
216+
"S7942",
217+
"S7943",
218+
"S8370",
219+
"S8371",
220+
"S8374",
221+
"S8375",
222+
"S8385",
223+
"S8389",
224+
"S8392",
225+
"S8396",
226+
"S8400",
227+
"S8401",
228+
"S8405",
229+
"S8409",
230+
"S8411",
231+
"S8414",
232+
"S905",
233+
"S930",
234+
"S935"
235+
]
236+
}

0 commit comments

Comments
 (0)