diff --git a/apps/web/src/components/code-reviews/ReviewConfigForm.tsx b/apps/web/src/components/code-reviews/ReviewConfigForm.tsx
index 0e5875052d..81297cb529 100644
--- a/apps/web/src/components/code-reviews/ReviewConfigForm.tsx
+++ b/apps/web/src/components/code-reviews/ReviewConfigForm.tsx
@@ -454,7 +454,7 @@ export function ReviewConfigForm({
platform,
reviewStyle,
focusAreas,
- customInstructions: customInstructions.trim() || undefined,
+ customInstructions: customInstructions || undefined,
modelSlug: selectedModel,
thinkingEffort,
gateThreshold,
@@ -470,7 +470,7 @@ export function ReviewConfigForm({
platform,
reviewStyle,
focusAreas,
- customInstructions: customInstructions.trim() || undefined,
+ customInstructions: customInstructions || undefined,
modelSlug: selectedModel,
thinkingEffort,
gateThreshold,
@@ -1047,18 +1047,30 @@ export function ReviewConfigForm({
{/* Custom Instructions */}
-
+
{/* Save Button */}
diff --git a/apps/web/src/components/code-reviews/ReviewMdGuideContent.tsx b/apps/web/src/components/code-reviews/ReviewMdGuideContent.tsx
index f22926fab5..33d153b01c 100644
--- a/apps/web/src/components/code-reviews/ReviewMdGuideContent.tsx
+++ b/apps/web/src/components/code-reviews/ReviewMdGuideContent.tsx
@@ -27,7 +27,7 @@ const guidanceItems = [
const limits = [
'Hard safety, tooling, platform, and read-only constraints still apply.',
- 'Custom instructions and focus areas are still applied around repository guidance.',
+ 'Focus areas are still applied around repository guidance.',
'@ imports are not expanded. Keep the guidance directly in REVIEW.md.',
'Content is truncated after 10,000 characters.',
'Do not include secrets, credentials, tokens, or private operational data.',
diff --git a/apps/web/src/lib/code-reviews/prompts/generate-prompt.test.ts b/apps/web/src/lib/code-reviews/prompts/generate-prompt.test.ts
index f984af992a..9b1733af40 100644
--- a/apps/web/src/lib/code-reviews/prompts/generate-prompt.test.ts
+++ b/apps/web/src/lib/code-reviews/prompts/generate-prompt.test.ts
@@ -138,10 +138,12 @@ describe('resolveTemplate', () => {
// --- generateReviewPrompt (integration) ---
+const legacyCustomInstructions = 'Also consider account-level policy.';
+
const baseConfig = {
review_style: 'balanced' as const,
focus_areas: [],
- custom_instructions: '',
+ custom_instructions: legacyCustomInstructions,
model_slug: 'test-model',
} satisfies CodeReviewAgentConfig;
@@ -152,6 +154,8 @@ describe('generateReviewPrompt', () => {
expect(prompt).toContain('# WHAT TO REVIEW');
expect(prompt).toContain('Security vulnerabilities (injection, XSS, auth bypass)');
expect(prompt).not.toContain(`# ${REVIEW_INSTRUCTIONS_FILE} code review instructions`);
+ expect(prompt).not.toContain('# CUSTOM INSTRUCTIONS');
+ expect(prompt).not.toContain(legacyCustomInstructions);
});
it('replaces built-in review guidance with REVIEW.md instructions at the same prompt point', async () => {
@@ -164,7 +168,6 @@ describe('generateReviewPrompt', () => {
].join('\n');
const customConfig = {
...baseConfig,
- custom_instructions: 'Also consider account-level policy.',
focus_areas: ['security'],
} satisfies CodeReviewAgentConfig;
@@ -172,8 +175,8 @@ describe('generateReviewPrompt', () => {
repositoryReviewInstructions,
});
- expect(prompt).toContain('# CUSTOM INSTRUCTIONS');
- expect(prompt).toContain('Also consider account-level policy.');
+ expect(prompt).not.toContain('# CUSTOM INSTRUCTIONS');
+ expect(prompt).not.toContain(legacyCustomInstructions);
expect(prompt).toContain(`# ${REVIEW_INSTRUCTIONS_FILE} code review instructions`);
expect(prompt).toContain('Only flag regressions with direct evidence.');
expect(prompt).toContain('```ts\nconst markdown = true;\n```');
@@ -185,9 +188,6 @@ describe('generateReviewPrompt', () => {
expect(prompt).toContain('# COMMENT FORMAT');
expect(prompt).toContain('## Inline Comments API Call');
- expect(prompt.indexOf('# CUSTOM INSTRUCTIONS')).toBeLessThan(
- prompt.indexOf(`# ${REVIEW_INSTRUCTIONS_FILE} code review instructions`)
- );
expect(prompt.indexOf(`# ${REVIEW_INSTRUCTIONS_FILE} code review instructions`)).toBeLessThan(
prompt.indexOf('# FOCUS AREAS')
);
diff --git a/apps/web/src/lib/code-reviews/prompts/generate-prompt.ts b/apps/web/src/lib/code-reviews/prompts/generate-prompt.ts
index 5877d6a437..582fb73488 100644
--- a/apps/web/src/lib/code-reviews/prompts/generate-prompt.ts
+++ b/apps/web/src/lib/code-reviews/prompts/generate-prompt.ts
@@ -9,7 +9,7 @@
* 4. Adding dynamic context (existing comments table)
* 5. Selecting CREATE vs UPDATE summary command
* 6. Platform-specific template selection (GitHub vs GitLab)
- * 7. Injecting style guidance, custom instructions, and focus areas from config
+ * 7. Injecting style guidance and focus areas from config
* 8. Applying per-style comment format and summary format overrides
*/
@@ -22,7 +22,6 @@ import { logExceptInTest } from '@/lib/utils.server';
import type { CodeReviewPlatform } from '@/lib/code-reviews/core/schemas';
import { getPromptTemplateFeatureFlag, getPlatformConfig } from './platform-helpers';
import { PLATFORM } from '@/lib/integrations/core/constants';
-import { sanitizeUserInput } from './prompt-utils';
import { formatRepositoryReviewInstructions } from './repository-review-instructions';
import { getCurrentReviewSummaryForContext } from '../summary/history';
@@ -263,15 +262,10 @@ export async function generateReviewPrompt(
prompt += styleGuide + '\n\n';
}
- // 3. Custom instructions (user-provided, sanitized to prevent injection)
- if (config.custom_instructions) {
- prompt += '# CUSTOM INSTRUCTIONS\n\n' + sanitizeUserInput(config.custom_instructions) + '\n\n';
- }
-
- // 4. Hard constraints (MOST IMPORTANT - always included)
+ // 3. Hard constraints (MOST IMPORTANT - always included)
prompt += template.hardConstraints + '\n\n';
- // 5. Workflow with placeholders replaced
+ // 4. Workflow with placeholders replaced
// Use incremental workflow when we have a previous completed review SHA and a summary comment
if (
previousHeadSha &&
@@ -305,19 +299,19 @@ export async function generateReviewPrompt(
}
}
- // 6. What to review
+ // 5. What to review
prompt +=
(repositoryReviewInstructions
? formatRepositoryReviewInstructions(repositoryReviewInstructions)
: template.whatToReview) + '\n\n';
- // 7. Focus areas (if any selected)
+ // 6. Focus areas (if any selected)
if (config.focus_areas.length > 0) {
prompt +=
'# FOCUS AREAS\n\nPay special attention to: ' + config.focus_areas.join(', ') + '\n\n';
}
- // 8. Comment format (use style override if available, otherwise default)
+ // 7. Comment format (use style override if available, otherwise default)
const commentFormat = template.commentFormatOverrides?.[reviewStyle] ?? template.commentFormat;
prompt += commentFormat + '\n\n';
@@ -325,7 +319,7 @@ export async function generateReviewPrompt(
prompt += template.inlineCommentFooter + '\n\n';
}
- // 9. Dynamic context section (separator)
+ // 8. Dynamic context section (separator)
prompt += '---\n\n# CONTEXT FOR THIS ' + platformConfig.prTerm + '\n\n';
prompt += `**${platform === PLATFORM.GITLAB ? 'Project' : 'Repository'}:** ${repository}\n`;
prompt += `**${platformConfig.prTerm} Number:** ${pr}\n\n`;