Skip to content

feat: add pre-debate hallucination filter (#428)#433

Merged
justn-hyeok merged 1 commit intomainfrom
feat/hallucination-filter-428
Apr 1, 2026
Merged

feat: add pre-debate hallucination filter (#428)#433
justn-hyeok merged 1 commit intomainfrom
feat/hallucination-filter-428

Conversation

@justn-hyeok
Copy link
Copy Markdown
Collaborator

@justn-hyeok justn-hyeok commented Apr 1, 2026

Summary

  • L1 리뷰어가 생성한 evidence documents를 L2 debate 전에 실제 diff와 대조하여 hallucination을 필터링하는 모듈 추가
  • diff에 존재하지 않는 파일, diff hunk 범위 밖의 라인, 날조된 코드 인용을 검출하여 제거 또는 confidence 감소
  • 모델 호출 없이 순수 문자열 매칭으로 동작 (zero model cost)

Changes

  • New: packages/core/src/pipeline/hallucination-filter.ts - 3단계 검증 로직 (파일 존재, 라인 범위, 코드 인용)
  • Updated: packages/core/src/pipeline/orchestrator.ts - LEARNING 단계 이후, CONFIDENCE 계산 이전에 hallucination filter 삽입
  • New: packages/core/src/tests/hallucination-filter.test.ts - 9개 테스트 케이스

Test plan

  • 파일이 diff에 없는 finding → 제거됨
  • 파일이 diff에 있고 라인이 hunk 안 → 유지됨
  • 파일이 diff에 있지만 라인이 hunk 밖 → 제거됨
  • 날조된 코드 인용 → confidence 감소
  • 실제 코드 인용 → 패널티 없음
  • rule source → 항상 유지
  • unknown filePath → 유지
  • 빈 docs → 빈 결과
  • mixed valid/invalid → 올바른 분리

Closes #428

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added hallucination detection and filtering to the analysis pipeline. The system now automatically removes or reduces confidence scores for findings that may be false positives by validating them against actual code changes. This enhancement improves the accuracy and reliability of detected findings.

Validates evidence documents against actual diff before L2 debate:
- Remove findings referencing files not in diff
- Remove findings with line ranges outside diff hunks
- Penalize confidence for fabricated code quotes

Zero model cost. Catches obvious hallucinations like references
to bundled dependency files or non-existent code patterns.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions bot added the size/L <500 lines label Apr 1, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 1, 2026

📝 Walkthrough

Walkthrough

A new hallucination filter module validates evidence documents against the actual diff content before pipeline confidence computation. The filter removes findings when their filePath or lineRange don't match the diff, and penalizes confidence for code quotes not present in the diff. The filter is integrated into the pipeline orchestrator after learned-pattern dismissal.

Changes

Cohort / File(s) Summary
Hallucination Filter Implementation
packages/core/src/pipeline/hallucination-filter.ts
New module introducing FilterResult interface and filterHallucinations() function. Validates evidence documents by checking: (1) filePath exists in diff file list, (2) lineRange overlaps diff hunks with tolerance, (3) backtick-wrapped code quotes in problem text exist in diff. Non-rule-sourced findings failing checks are removed; confidence is halved for fabricated quotes.
Pipeline Integration
packages/core/src/pipeline/orchestrator.ts
Integrated hallucination filter into pipeline after learned-pattern dismissal filtering. Dynamically imports filter, processes allEvidenceDocs with filteredDiffContent, logs removal count, and passes filtered results to downstream processing.
Test Coverage
packages/core/src/tests/hallucination-filter.test.ts
Comprehensive test suite validating filter behavior: filePath matching, lineRange overlap detection, confidence penalization for fabricated quotes, rule-sourced finding retention, unknown filePath handling, and mixed input processing.

Sequence Diagram

sequenceDiagram
    participant Pipeline
    participant HallucinationFilter
    participant DiffParser
    participant DocumentValidator

    Pipeline->>HallucinationFilter: filterHallucinations(allEvidenceDocs, diffContent)
    HallucinationFilter->>DiffParser: Parse diff content
    DiffParser-->>HallucinationFilter: filePaths set, hunkMap
    
    loop For each EvidenceDocument
        HallucinationFilter->>DocumentValidator: Validate filePath in diff
        DocumentValidator-->>HallucinationFilter: exists or not
        alt filePath not in diff
            HallucinationFilter->>HallucinationFilter: Mark as removed
        else filePath exists
            HallucinationFilter->>DocumentValidator: Validate lineRange overlap
            alt lineRange overlaps hunk
                HallucinationFilter->>DocumentValidator: Check code quotes in diff
                alt quotes found
                    HallucinationFilter->>HallucinationFilter: Keep with original confidence
                else quotes not found
                    HallucinationFilter->>HallucinationFilter: Halve confidence, keep
                end
            else lineRange no overlap
                HallucinationFilter->>HallucinationFilter: Mark as removed
            end
        end
    end
    
    HallucinationFilter-->>Pipeline: FilterResult {filtered, removed}
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related issues

Poem

🐰 A whisker-twitch of joy!
Hallucinations filtered out with care,
File paths and line ranges cross-checked fair,
Code quotes now verified before debate—
Layer One stands firm at the pipeline gate! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add pre-debate hallucination filter (#428)' clearly summarizes the main change: introduction of a pre-debate hallucination filter module.
Linked Issues check ✅ Passed All coding requirements from #428 are met: hallucination-filter.ts implements three validation checks (file existence, line range, code quote), returns FilterResult interface, integrates into orchestrator pipeline after L1 before L2 threshold, and comprehensive tests cover all scenarios.
Out of Scope Changes check ✅ Passed All changes are directly aligned with #428 objectives: new hallucination-filter module with validation logic, orchestrator integration, and comprehensive tests. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/hallucination-filter-428

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@codeagora-bot codeagora-bot bot left a comment

Choose a reason for hiding this comment

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

CodeAgora Review

📋 Triage: 4 must-fix · 4 verify · 5 ignore

Verdict: 🔴 REJECT · 4 critical · 9 warning

All three CRITICAL findings have high confidence (75–90%) and survived debate; the strongest (d002) shows an undefined computeValue() call that will break compilation, while d003 documents a stray backtick that will also break syntax, and d001 identifies a logic flaw that can silently drop evidence. None of these were debunked—only one reviewer dissented on d001 and d003 without producing counter-evidence—so the change is unsafe to merge.

Blocking Issues

Severity File Line Issue Confidence
🔴 CRITICAL packages/core/src/pipeline/hallucination-filter.ts 54–61 Incorrect Handling of Line Ranges in Hallucination Filter 🟡 64%
🔴 CRITICAL src/utils.ts 10–12 Undefined computeValue in utils.ts 🟢 82%
🔴 CRITICAL src/index.ts 7–7 Syntax Error – stray backtick in index.ts 🟢 93%
🔴 CRITICAL src/index.ts 2–2 Unused / Potentially Missing Import newModule in index.ts 🟢 87%
9 warning(s)
Severity File Line Issue Confidence
🟡 WARNING packages/core/src/pipeline/hallucination-filter.ts 73 Inconsistent Confidence Calculation for Fabricated Code Quotes 🟡 44%
🟡 WARNING packages/core/src/pipeline/hallucination-filter.ts 47 Potential Null Pointer Exception in Hallucination Filter 🟡 54%
🟡 WARNING packages/core/src/pipeline/hallucination-filter.ts 42 Inconsistent Handling of Unknown File Paths 🟡 48%
🟡 WARNING packages/core/src/pipeline/orchestrator.ts 743 Potential Insecure Use of console.log in Orchestrator 🟡 56%
🟡 WARNING packages/core/src/pipeline/hallucination-filter.ts 24 Missing Sanitization of Shell Args in Hallucination Filter 🟡 78%
🟡 WARNING packages/core/src/pipeline/hallucination-filter.ts 28 Potential Resource Leak in Hallucination Filter 🟡 72%
🟡 WARNING packages/core/src/pipeline/hallucination-filter.ts 54 Potential Off-by-One Error in Hallucination Filter 🟡 46%
🟡 WARNING packages/core/src/pipeline/hallucination-filter.ts 81 No Confidence Penalty for Non-Hallucinated Documents 🔴 32%
🟡 WARNING packages/core/src/pipeline/hallucination-filter.ts 47 No Error Handling for File Existence Check 🟡 42%
Issue distribution (4 file(s))
File Issues
packages/core/src/pipeline/hallucination-filter.ts ████████████ 9
src/index.ts ███ 2
src/utils.ts █ 1
packages/core/src/pipeline/orchestrator.ts █ 1
Agent consensus log (3 discussion(s))
✅ d001 — 1 round(s), consensus → CRITICAL

Verdict: CRITICAL — Majority consensus (2/3 agree)

✅ d002 — 1 round(s), consensus → CRITICAL

Verdict: CRITICAL — All supporters agreed on the issue

✅ d003 — 1 round(s), consensus → CRITICAL

Verdict: CRITICAL — Majority consensus (2/3 agree)


CodeAgora · Session: 2026-04-01/001


// Check 2: Line range overlaps with diff hunks
if (doc.filePath !== 'unknown' && doc.lineRange[0] > 0) {
const hunks = hunkMap.get(doc.filePath);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 CRITICAL — Incorrect Handling of Line Ranges in Hallucination Filter

Confidence: 🟡 64%

Problem: In packages/core/src/pipeline/hallucination-filter.ts:54-61

The current implementation of the hallucination filter has a logical flaw in how it handles line ranges. Specifically, it checks if doc.lineRange[0] > 0 before verifying if the line range overlaps with any diff hunks. This condition is unnecessary and could potentially lead to incorrect filtering of evidence documents.

Evidence:

  1. The condition doc.lineRange[0] > 0 is not required because the subsequent check hunks.some(([start, end]) => ...) will correctly handle all line ranges, including those that start at or below line 0.
  2. The current implementation may incorrectly remove evidence documents that have line ranges starting at 0 or below, which could be valid.
Suggested change
const hunks = hunkMap.get(doc.filePath);
// Check 2: Line range overlaps with diff hunks
if (doc.filePath !== 'unknown') {
const hunks = hunkMap.get(doc.filePath);
if (hunks && hunks.length > 0) {
const HUNK_TOLERANCE = 10; // Allow some tolerance for context lines
const overlaps = hunks.some(([start, end]) =>
doc.lineRange[0] <= end + HUNK_TOLERANCE &&
doc.lineRange[1] >= start - HUNK_TOLERANCE
);
if (!overlaps) {
removed.push(doc);
continue;
}
}
}
🔍 Individual Reviews (2 reviewers)

r-scout 💬 meta-llama/llama-4-scout-17b-16e-instruct (🔴 CRITICAL)

Problem: In packages/core/src/pipeline/hallucination-filter.ts:54-61 The current implementation of the hallucination filter has a logical flaw in how it handles line ranges. Specifically, it checks if `doc....

Evidence:

  • The condition doc.lineRange[0] > 0 is not required because the subsequent check `hunks.some(([start, end]) => ......
  • The current implementation may incorrectly remove evidence documents that have line ranges starting at 0 or below, which could be valid.

Suggestion: Remove the unnecessary condition doc.lineRange[0] > 0 to ensure that all line ranges are properly checked for overlap with diff hunks....

r-llama31 💬 llama-3.1-8b-instant (🟡 WARNING)

Problem: In packages/core/src/pipeline/hallucination-filter.ts:54-65 The hallucination filter function uses the `hunkMap....

Evidence:

  • Lack of null check for the get() function result.
  • Potential off-by-one error if the get() function returns undefined.

Suggestion: Add a null check for the get() function result to prevent potential off-by-one errors. ---

Flagged by: r-scout, r-llama31  |  CodeAgora

const codeQuotes = doc.problem.match(/`([^`]{10,})`/g);
if (codeQuotes && codeQuotes.length > 0) {
let fabricatedCount = 0;
for (const quote of codeQuotes) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 WARNING — Inconsistent Confidence Calculation for Fabricated Code Quotes

Confidence: 🟡 44%

Problem: In packages/core/src/pipeline/hallucination-filter.ts:73-84

The confidence calculation for fabricated code quotes seems inconsistent. It checks if more than half of the code quotes are fabricated, and if so, it reduces the confidence by half. However, this approach may not be suitable for all cases.

Evidence:

  1. The current implementation only checks if more than half of the code quotes are fabricated, which may not be sufficient to determine the overall confidence.
  2. The reduction of confidence by half may be too harsh, as it does not take into account the severity of the fabricated code quotes.
  3. There is no consideration for the case where all code quotes are fabricated, which should likely result in a significant reduction in confidence.
Suggested change
for (const quote of codeQuotes) {
if (fabricatedCount > 0) {
const confidenceReduction = (fabricatedCount / codeQuotes.length) * 0.5;
doc.confidence = Math.round((doc.confidence ?? 50) * (1 - confidenceReduction));
}

Flagged by: r-llama33  |  CodeAgora

}

// Check 1: File exists in diff
if (doc.filePath !== 'unknown' && !diffFiles.has(doc.filePath)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 WARNING — Potential Null Pointer Exception in Hallucination Filter

Confidence: 🟡 54%

Problem: In packages/core/src/pipeline/hallucination-filter.ts:47-51

The doc.filePath is checked for existence in the diffFiles set, but it is not checked for null or undefined. If doc.filePath is null or undefined, a null pointer exception may occur.

Evidence:

  1. The doc.filePath is not explicitly checked for null or undefined before being used in the diffFiles.has() method.
  2. The diffFiles set is created from the extractFileListFromDiff() function, which may return null or undefined if the diff content is invalid.
Suggested change
if (doc.filePath !== 'unknown' && !diffFiles.has(doc.filePath)) {
if (doc.filePath !== null && doc.filePath !== undefined && !diffFiles.has(doc.filePath)) {
removed.push(doc);
continue;
}
🔍 Individual Reviews (2 reviewers)

r-llama33 💬 llama-3.3-70b-versatile (🟡 WARNING)

Problem: In packages/core/src/pipeline/hallucination-filter.ts:47-51 The doc.filePath is checked for existence in the diffFiles set, but it is not checked for null or undefined. If `doc....

Evidence:

  • The doc.filePath is not explicitly checked for null or undefined before being used in the diffFiles.has() method.
  • The diffFiles set is created from the extractFileListFromDiff() function, which may return null or undefined if the diff content is invalid.

Suggestion: Add a null check for doc.filePath before using it in the diffFiles.has() method: ```typescript if (doc.filePath !== null && doc.filePath !== undefined && !diffFiles.has(doc.filePath)) { removed....

r-llama31 💬 llama-3.1-8b-instant (🟡 WARNING)

Problem: In packages/core/src/pipeline/hallucination-filter.ts:47-50 The hallucination filter function does not handle errors when checking file existence....

Evidence:

  • Lack of error handling for file existence check.
  • Potential unhandled errors and unexpected behavior.

Suggestion: Add error handling for file existence check to handle potential errors and ensure expected behavior. --- No issues found.

Flagged by: r-llama33, r-llama31  |  CodeAgora

for (const doc of docs) {
// Skip rule-based findings (they come from static analysis, not LLM)
if (doc.source === 'rule') {
filtered.push(doc);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 WARNING — Inconsistent Handling of Unknown File Paths

Confidence: 🟡 48%

Problem: In packages/core/src/pipeline/hallucination-filter.ts:42-44

The hallucination filter checks if the doc.source is 'rule' and if so, it skips the file existence check. However, it does not handle the case where the doc.filePath is 'unknown' consistently.

Evidence:

  1. The doc.filePath is checked for existence in the diffFiles set, but if it is 'unknown', the check is skipped.
  2. The makeDoc() function in the test cases creates evidence documents with filePath set to 'unknown', but the hallucination filter does not handle this case consistently.
Suggested change
filtered.push(doc);
if (doc.filePath === 'unknown') {
filtered.push(doc);
continue;
}

Flagged by: r-llama33  |  CodeAgora

}

// === HALLUCINATION FILTER: Remove findings referencing non-existent code (#428) ===
const { filterHallucinations } = await import('./hallucination-filter.js');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 WARNING — Potential Insecure Use of console.log in Orchestrator

Confidence: 🟡 56%

Problem: In packages/core/src/pipeline/orchestrator.ts:743-748

The orchestrator function logs sensitive information (e.g., removed findings) to the console using console.log. This could potentially leak sensitive information to unauthorized parties if the console output is exposed.

Evidence:

  1. Logging sensitive information (e.g., removed findings) to the console without proper redaction or sanitization.
  2. Lack of secure logging practices in the orchestrator function.

Suggestion: Use a secure logging library (e.g., bunyan, loglevel) to log sensitive information and ensure proper redaction and sanitization. Alternatively, use a secure logging framework to prevent sensitive information from being exposed.


Flagged by: r-llama31  |  CodeAgora

* 3. Code quote: inline code in problem text should exist in diff
*/
export function filterHallucinations(
docs: EvidenceDocument[],
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 WARNING — Missing Sanitization of Shell Args in Hallucination Filter

Confidence: 🟡 78%

Problem: In packages/core/src/pipeline/hallucination-filter.ts:24-26

The hallucination filter function uses the diffContent parameter, which is not sanitized for shell args. This could potentially lead to shell injection vulnerabilities if the diffContent string contains shell metacharacters.

Evidence:

  1. Lack of sanitization for shell args (e.g., no use of sanitizeShellArg() or similar).
  2. Potential for shell injection vulnerabilities if diffContent contains shell metacharacters.

Suggestion: Use a sanitization function (e.g., sanitizeShellArg()) to properly sanitize the diffContent string for shell args.


Flagged by: r-llama31  |  CodeAgora

diffContent: string,
): FilterResult {
const diffFiles = new Set(extractFileListFromDiff(diffContent));
const diffRanges = parseDiffFileRanges(diffContent);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 WARNING — Potential Resource Leak in Hallucination Filter

Confidence: 🟡 72%

Problem: In packages/core/src/pipeline/hallucination-filter.ts:28-36

The hallucination filter function creates a Map of file -> hunk ranges, but the Map is not cleared or disposed of after use. This could potentially lead to a resource leak if the function is called multiple times without clearing the Map.

Evidence:

  1. Creation of a Map without proper disposal or clearing.
  2. Potential resource leak if the function is called multiple times.

Suggestion: Clear or dispose of the Map after use to prevent potential resource leaks. Alternatively, use a weak Map or a garbage-collected Map to allow the Map to be collected by the garbage collector.


✅ Discussion d001 — 1 round(s), consensus

Verdict: CRITICAL — Majority consensus (2/3 agree)

Flagged by: r-llama31  |  CodeAgora


// Check 2: Line range overlaps with diff hunks
if (doc.filePath !== 'unknown' && doc.lineRange[0] > 0) {
const hunks = hunkMap.get(doc.filePath);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 WARNING — Potential Off-by-One Error in Hallucination Filter

Confidence: 🟡 46%

Problem: In packages/core/src/pipeline/hallucination-filter.ts:54-65

The hallucination filter function uses the hunkMap.get() function to get the hunks for a file, but it does not check if the get() function returns undefined. This could potentially lead to an off-by-one error if the get() function returns undefined.

Evidence:

  1. Lack of null check for the get() function result.
  2. Potential off-by-one error if the get() function returns undefined.

Suggestion: Add a null check for the get() function result to prevent potential off-by-one errors.


🔍 Individual Reviews (2 reviewers)

r-scout 💬 meta-llama/llama-4-scout-17b-16e-instruct (🔴 CRITICAL)

Problem: In packages/core/src/pipeline/hallucination-filter.ts:54-61 The current implementation of the hallucination filter has a logical flaw in how it handles line ranges. Specifically, it checks if `doc....

Evidence:

  • The condition doc.lineRange[0] > 0 is not required because the subsequent check `hunks.some(([start, end]) => ......
  • The current implementation may incorrectly remove evidence documents that have line ranges starting at 0 or below, which could be valid.

Suggestion: Remove the unnecessary condition doc.lineRange[0] > 0 to ensure that all line ranges are properly checked for overlap with diff hunks....

r-llama31 💬 llama-3.1-8b-instant (🟡 WARNING)

Problem: In packages/core/src/pipeline/hallucination-filter.ts:54-65 The hallucination filter function uses the `hunkMap....

Evidence:

  • Lack of null check for the get() function result.
  • Potential off-by-one error if the get() function returns undefined.

Suggestion: Add a null check for the get() function result to prevent potential off-by-one errors. ---

Flagged by: r-scout, r-llama31  |  CodeAgora

}
// If majority of code quotes are fabricated, penalize confidence
if (fabricatedCount > codeQuotes.length / 2) {
doc.confidence = Math.round((doc.confidence ?? 50) * 0.5);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 WARNING — No Confidence Penalty for Non-Hallucinated Documents

Confidence: 🔴 32%

Problem: In packages/core/src/pipeline/hallucination-filter.ts:81-83

The hallucination filter function does not penalize confidence for non-hallucinated documents. This could potentially lead to incorrect confidence scores being assigned to non-hallucinated documents.

Evidence:

  1. Lack of confidence penalty for non-hallucinated documents.
  2. Potential incorrect confidence scores being assigned to non-hallucinated documents.

Suggestion: Add a confidence penalty for non-hallucinated documents to ensure accurate confidence scores are assigned.


Flagged by: r-llama31  |  CodeAgora

}

// Check 1: File exists in diff
if (doc.filePath !== 'unknown' && !diffFiles.has(doc.filePath)) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 WARNING — No Error Handling for File Existence Check

Confidence: 🟡 42%

Problem: In packages/core/src/pipeline/hallucination-filter.ts:47-50

The hallucination filter function does not handle errors when checking file existence. This could potentially lead to unhandled errors and unexpected behavior.

Evidence:

  1. Lack of error handling for file existence check.
  2. Potential unhandled errors and unexpected behavior.

Suggestion: Add error handling for file existence check to handle potential errors and ensure expected behavior.


No issues found.

🔍 Individual Reviews (2 reviewers)

r-llama33 💬 llama-3.3-70b-versatile (🟡 WARNING)

Problem: In packages/core/src/pipeline/hallucination-filter.ts:47-51 The doc.filePath is checked for existence in the diffFiles set, but it is not checked for null or undefined. If `doc....

Evidence:

  • The doc.filePath is not explicitly checked for null or undefined before being used in the diffFiles.has() method.
  • The diffFiles set is created from the extractFileListFromDiff() function, which may return null or undefined if the diff content is invalid.

Suggestion: Add a null check for doc.filePath before using it in the diffFiles.has() method: ```typescript if (doc.filePath !== null && doc.filePath !== undefined && !diffFiles.has(doc.filePath)) { removed....

r-llama31 💬 llama-3.1-8b-instant (🟡 WARNING)

Problem: In packages/core/src/pipeline/hallucination-filter.ts:47-50 The hallucination filter function does not handle errors when checking file existence....

Evidence:

  • Lack of error handling for file existence check.
  • Potential unhandled errors and unexpected behavior.

Suggestion: Add error handling for file existence check to handle potential errors and ensure expected behavior. --- No issues found.

Flagged by: r-llama33, r-llama31  |  CodeAgora

@codeagora-bot
Copy link
Copy Markdown

codeagora-bot bot commented Apr 1, 2026

src/utils.ts:10-12

🔴 CRITICAL — Undefined computeValue in utils.ts

Confidence: 🟢 82%

Problem: In src/utils.ts:10-12

The function helper now calls computeValue() which is neither imported nor defined anywhere in the project. This causes a TypeScript compilation error and, if compiled, a runtime ReferenceError when helper is invoked.

Evidence:

  1. Line 11: const b = computeValue();computeValue is not defined in this file.
  2. No import statement for computeValue is present in utils.ts.
  3. The surrounding code (const a = 1;) expects a numeric value, implying computeValue should return a number, but its absence breaks type safety.
function computeValue(): number {
  // Implement the intended logic
  return 42; // placeholder
}
✅ Discussion d002 — 1 round(s), consensus

Verdict: CRITICAL — All supporters agreed on the issue

Flagged by: r-gpt-oss  |  CodeAgora

@codeagora-bot
Copy link
Copy Markdown

codeagora-bot bot commented Apr 1, 2026

src/index.ts:7-7

🔴 CRITICAL — Syntax Error – stray backtick in index.ts

Confidence: 🟢 93%

Problem: In src/index.ts:7

A stray backtick () appears after the closing brace of main()` which makes the file syntactically invalid, preventing it from compiling.

Evidence:

  1. The code ends with:
  2. This syntax error halts TypeScript compilation for the entire src package.
export function main() {
  return helper();
}

Flagged by: r-gpt-oss  |  CodeAgora

@codeagora-bot
Copy link
Copy Markdown

codeagora-bot bot commented Apr 1, 2026

src/index.ts:2-2

🔴 CRITICAL — Unused / Potentially Missing Import newModule in index.ts

Confidence: 🟢 87%

Problem: In src/index.ts:2

newModule is imported from ./new-module.js but never used anywhere in the file. If new-module.js does not exist, this static import will cause a runtime failure when the module is loaded.

Evidence:

  1. Line 2: import { newModule } from './new-module.js'; – no subsequent reference to newModule.
  2. No import guard or conditional import is present; the module will be resolved at startup.
  3. If the file new-module.js is absent, Node.js will throw a module resolution error during startup, causing the CLI to crash.
  // import { newModule } from './new-module.js'; // unused, remove
  
✅ Discussion d003 — 1 round(s), consensus

Verdict: CRITICAL — Majority consensus (2/3 agree)

Flagged by: r-gpt-oss  |  CodeAgora

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/pipeline/hallucination-filter.ts`:
- Around line 54-67: The current logic skips overlap validation when
hunkMap.get(doc.filePath) is missing, so treat missing or empty hunk lists as
"no overlap" and remove the doc; modify the block around
hunkMap.get(doc.filePath) (referencing hunkMap, doc, HUNK_TOLERANCE, removed) to
explicitly check for a missing/empty hunks array and push the document into
removed with continue, and only perform the tolerance-based overlaps check when
hunks is a non-empty array.
- Around line 28-29: The diff-file parsers may both return empty results and the
current logic then removes all non-`unknown` LLM findings; change the logic in
hallucination-filter.ts so that if both extractFileListFromDiff(diffContent) and
parseDiffFileRanges(diffContent) produce no metadata (diffFiles is empty AND
diffRanges is empty), you skip/disable the diff-based filtering step that
removes non-`unknown` findings rather than applying it. Locate references to
diffFiles and diffRanges and the removal code handling non-`unknown` LLM
findings, and add an early guard that only runs that heuristic when at least one
of the parser results is non-empty.
- Around line 69-86: The code only checks doc.problem for backtick-wrapped code
and mutates doc.confidence in place; update the logic in hallucination-filter.ts
to scan all relevant text fields (doc.problem, doc.issueTitle, doc.suggestion,
and each item in doc.evidence[]) for backtick-wrapped code snippets using the
existing regex, aggregate fabricatedCode counts across all those sources, and if
majority fabricated reduce confidence; do not mutate the original doc — create a
shallow copy (e.g., newDoc = { ...doc }) and set newDoc.confidence before
pushing (replace filtered.push(doc) with filtered.push(newDoc)) so the helper
remains pure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 79538f20-db48-48aa-9c10-cf296b444231

📥 Commits

Reviewing files that changed from the base of the PR and between a2b9067 and ee3a140.

📒 Files selected for processing (3)
  • packages/core/src/pipeline/hallucination-filter.ts
  • packages/core/src/pipeline/orchestrator.ts
  • packages/core/src/tests/hallucination-filter.test.ts

Comment on lines +28 to +29
const diffFiles = new Set(extractFileListFromDiff(diffContent));
const diffRanges = parseDiffFileRanges(diffContent);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fail open when diff parsing returns no file metadata.

If extractFileListFromDiff() and parseDiffFileRanges() both fail to extract anything from a non-empty diff, Line 48 removes every non-unknown LLM finding. A parser miss should disable this heuristic, not wipe the whole L1 signal.

💡 Minimal guard
 export function filterHallucinations(
   docs: EvidenceDocument[],
   diffContent: string,
 ): FilterResult {
   const diffFiles = new Set(extractFileListFromDiff(diffContent));
   const diffRanges = parseDiffFileRanges(diffContent);
+  if (docs.length > 0 && diffContent.trim() && diffFiles.size === 0 && diffRanges.length === 0) {
+    return { filtered: [...docs], removed: [] };
+  }

Also applies to: 47-50

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/pipeline/hallucination-filter.ts` around lines 28 - 29, The
diff-file parsers may both return empty results and the current logic then
removes all non-`unknown` LLM findings; change the logic in
hallucination-filter.ts so that if both extractFileListFromDiff(diffContent) and
parseDiffFileRanges(diffContent) produce no metadata (diffFiles is empty AND
diffRanges is empty), you skip/disable the diff-based filtering step that
removes non-`unknown` findings rather than applying it. Locate references to
diffFiles and diffRanges and the removal code handling non-`unknown` LLM
findings, and add an early guard that only runs that heuristic when at least one
of the parser results is non-empty.

Comment on lines +54 to +67
if (doc.filePath !== 'unknown' && doc.lineRange[0] > 0) {
const hunks = hunkMap.get(doc.filePath);
if (hunks && hunks.length > 0) {
const HUNK_TOLERANCE = 10; // Allow some tolerance for context lines
const overlaps = hunks.some(([start, end]) =>
doc.lineRange[0] <= end + HUNK_TOLERANCE &&
doc.lineRange[1] >= start - HUNK_TOLERANCE
);
if (!overlaps) {
removed.push(doc);
continue;
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle files with no parsed hunk ranges explicitly.

When hunkMap.get(doc.filePath) is missing, Lines 55-66 skip the overlap check and keep the document. That means a line-based finding is treated as “validated” even though no hunk overlap was checked at all.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/pipeline/hallucination-filter.ts` around lines 54 - 67, The
current logic skips overlap validation when hunkMap.get(doc.filePath) is
missing, so treat missing or empty hunk lists as "no overlap" and remove the
doc; modify the block around hunkMap.get(doc.filePath) (referencing hunkMap,
doc, HUNK_TOLERANCE, removed) to explicitly check for a missing/empty hunks
array and push the document into removed with continue, and only perform the
tolerance-based overlaps check when hunks is a non-empty array.

Comment on lines +69 to +86
// Check 3: Code quote verification
// Extract inline code from problem text (backtick-wrapped)
const codeQuotes = doc.problem.match(/`([^`]{10,})`/g);
if (codeQuotes && codeQuotes.length > 0) {
let fabricatedCount = 0;
for (const quote of codeQuotes) {
const code = quote.slice(1, -1); // Remove backticks
if (!diffContent.includes(code)) {
fabricatedCount++;
}
}
// If majority of code quotes are fabricated, penalize confidence
if (fabricatedCount > codeQuotes.length / 2) {
doc.confidence = Math.round((doc.confidence ?? 50) * 0.5);
}
}

filtered.push(doc);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Scan all finding text for fabricated code quotes.

Only doc.problem is inspected here. Backticks in issueTitle, evidence[], or suggestion keep full confidence even though they ship downstream with the finding. While touching this, return a copied document instead of mutating doc.confidence in place so the helper stays pure.

🔎 Expand quote sources without mutating the input
-    const codeQuotes = doc.problem.match(/`([^`]{10,})`/g);
+    const quoteSources = [doc.issueTitle, doc.problem, ...doc.evidence, doc.suggestion];
+    const codeQuotes = [...new Set(
+      quoteSources.flatMap((text) => text.match(/`([^`]{10,})`/g) ?? [])
+    )];
+    const nextDoc = { ...doc };
+
     if (codeQuotes && codeQuotes.length > 0) {
       let fabricatedCount = 0;
       for (const quote of codeQuotes) {
         const code = quote.slice(1, -1); // Remove backticks
         if (!diffContent.includes(code)) {
           fabricatedCount++;
         }
       }
       // If majority of code quotes are fabricated, penalize confidence
       if (fabricatedCount > codeQuotes.length / 2) {
-        doc.confidence = Math.round((doc.confidence ?? 50) * 0.5);
+        nextDoc.confidence = Math.round((nextDoc.confidence ?? 50) * 0.5);
       }
     }
 
-    filtered.push(doc);
+    filtered.push(nextDoc);
As per coding guidelines, "Prefer functional style with pure functions and immutable data structures."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/pipeline/hallucination-filter.ts` around lines 69 - 86, The
code only checks doc.problem for backtick-wrapped code and mutates
doc.confidence in place; update the logic in hallucination-filter.ts to scan all
relevant text fields (doc.problem, doc.issueTitle, doc.suggestion, and each item
in doc.evidence[]) for backtick-wrapped code snippets using the existing regex,
aggregate fabricatedCode counts across all those sources, and if majority
fabricated reduce confidence; do not mutate the original doc — create a shallow
copy (e.g., newDoc = { ...doc }) and set newDoc.confidence before pushing
(replace filtered.push(doc) with filtered.push(newDoc)) so the helper remains
pure.

@justn-hyeok justn-hyeok merged commit 3fb3400 into main Apr 1, 2026
2 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L <500 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Layer 1 — pre-debate hallucination filter (file/line/quote verification)

1 participant