1use crate::analysis::findings::LlmSeverity;
28use crate::analysis::response_contract::{
29 CATEGORY, CODE_SNIPPET, COMPILE_FAILURE, ISSUES, LINE, MESSAGE, SEVERITY, SUGGESTION, SUMMARY,
30};
31use crate::languages::spec::LanguageSupport;
32
33pub fn build_analysis_prompt(language: &LanguageSupport) -> String {
43 let conventions = conventions_block(language);
44 let display_name = language.display_name;
45 let severities = LlmSeverity::review_alternation();
49 let issues = ISSUES;
50 let summary = SUMMARY;
51 let line = LINE;
52 let severity = SEVERITY;
53 let category = CATEGORY;
54 let message = MESSAGE;
55 let suggestion = SUGGESTION;
56 let code_snippet = CODE_SNIPPET;
57 let compile_failure = COMPILE_FAILURE;
58 format!(
64 "You are an expert {display_name} code reviewer.\n\
65 Review the following code as a merge gate. Report only concrete issues\n\
66 that are worth fixing before merge:\n\
67 \n\
68 1. **Bugs & Logic Errors**: Incorrect logic, reachable crashes, data\n\
69 loss, broken contracts, type errors\n\
70 2. **Security Issues**: Injection, path traversal, unsafe deserialization,\n\
71 hardcoded secrets, weak cryptography\n\
72 3. **Reliability & Maintainability Defects**: Resource leaks, races,\n\
73 inconsistent state, or a design defect with a concrete failure mode\n\
74 4. **Performance Defects**: Material algorithmic or resource problems on\n\
75 a plausible execution path\n\
76 \n\
77 {conventions}\
78 For each issue found, provide:\n\
79 - The exact gutter line number of the affected code\n\
80 - Severity: critical (security vulnerabilities, data loss), high (bugs,\n\
81 crashes, serious issues), medium (material but non-critical defects).\n\
82 Low and info suggestions are outside this review and must not be emitted\n\
83 - Category: bug, security, performance, maintainability\n\
84 - Clear message explaining the issue\n\
85 - Specific, actionable suggestion for fixing it\n\
86 - The problematic code snippet\n\
87 - Whether the finding explicitly claims the code cannot compile\n\
88 \n\
89 **Important instructions:**\n\
90 - Only report a finding when it is concrete and reachable from the code\n\
91 shown, with a plausible execution path and a material consequence\n\
92 - This is not an exhaustive hardening exercise. Do not report optional hardening,\n\
93 extreme edge cases without a plausible execution path, nits, subjective\n\
94 preferences, cleanup, or refactoring opportunities\n\
95 - Do not report missing tests or documentation unless their absence creates\n\
96 a concrete product or API defect in the shown change\n\
97 - Prefer no finding over a speculative or marginal finding\n\
98 - Provide actionable suggestions, not vague advice\n\
99 - Focus on correctness, security, reliability, and material performance\n\
100 - The input is a line-numbered excerpt. Report the finding's `line`\n\
101 as the number shown in the gutter, never an offset into the\n\
102 excerpt. The excerpt itself states which lines are in scope.\n\
103 - Do not report subjective style issues, and do not report anything a\n\
104 formatter or linter would catch: those run separately and deterministically\n\
105 \n\
106 Return your analysis as valid JSON matching this exact schema:\n\
107 {{\n\
108 \"{issues}\": [\n\
109 {{\n\
110 \"{line}\": <line_number>,\n\
111 \"{severity}\": \"<{severities}>\",\n\
112 \"{category}\": \"<bug|security|performance|maintainability>\",\n\
113 \"{message}\": \"<clear description of the issue>\",\n\
114 \"{suggestion}\": \"<specific recommendation for fixing>\",\n\
115 \"{code_snippet}\": \"<the problematic code>\",\n\
116 \"{compile_failure}\": <true|false>\n\
117 }}\n\
118 ],\n\
119 \"{summary}\": \"<overall assessment of code quality>\"\n\
120 }}\n\
121 \n\
122 If no issues are found, return:\n\
123 {{\n\
124 \"{issues}\": [],\n\
125 \"{summary}\": \"No significant issues found. Code quality looks good.\"\n\
126 }}\n"
127 )
128}
129
130fn conventions_block(language: &LanguageSupport) -> String {
137 if language.conventions.is_empty() {
138 return String::new();
139 }
140 let mut out = format!("**{}-specific concerns:**\n", language.display_name);
141 for concern in language.conventions {
142 out.push_str("- ");
143 out.push_str(concern);
144 out.push('\n');
145 }
146 out
147}