Skip to content

feat: implement intelligence gate for API veracity (de-hallucination)#37

Open
LarytheLord wants to merge 2 commits intomainfrom
feature/dehallucination-gate
Open

feat: implement intelligence gate for API veracity (de-hallucination)#37
LarytheLord wants to merge 2 commits intomainfrom
feature/dehallucination-gate

Conversation

@LarytheLord
Copy link
Copy Markdown

@LarytheLord LarytheLord commented May 4, 2026

Summary

  • Implement a veracity verification layer in the review import pipeline that detects and rejects hallucinated library APIs in AI-suggested fixes
  • Add --verify-veracity flag to desloppify review --import to toggle the check
  • Python plugin with AST-based import tracking, alias resolution, and verification against 35+ stdlib modules
  • 6 test cases covering valid APIs, hallucinated methods, pathlib, import as, from import, and from import as patterns

Architecture

The feature adds a VeracityPlugin abstract interface (desloppify/intelligence/review/veracity.py) that language configs can implement. The Python plugin (desloppify/languages/python/veracity.py) tracks imports/aliases via AST and verifies attribute accesses against the local environment.

Integration points:

  • desloppify/app/cli_support/parser_groups_admin_review_options_core.py — CLI flag
  • desloppify/app/commands/review/cmd.py — flag wiring through review options
  • desloppify/app/commands/review/importing/flags.py — import config
  • desloppify/app/commands/review/importing/parse.py — parse options
  • desloppify/intelligence/review/importing/holistic.py — passes flag to validation
  • desloppify/intelligence/review/importing/holistic_issue_flow.py — runs veracity check, rejects hallucinated issues
  • desloppify/languages/python/__init__.py — wires PythonVeracityPlugin into Python config
  • desloppify/languages/_framework/base/types.py — adds veracity_plugin field to LangConfig
  • desloppify/data/global/SKILL.md + docs/SKILL.md — version 7, veracity documentation

Test Results

5530 passed, 152 skipped

Related

Summary by CodeRabbit

  • New Features

    • Added --verify-veracity CLI flag to validate suggested fixes against actual Python APIs and reject hallucinated methods.
    • Detects and prevents false suggestions that reference non-existent modules or methods during import operations.
  • Documentation

    • Updated guidance recommending --verify-veracity for import operations to catch hallucinated API suggestions.

… support

- Track import aliases (import x as y, from x import y) for accurate
  module resolution during hallucination checks
- Expand safe module list from 6 to 35+ stdlib modules
- Handle from-import and aliased-import patterns in AST verification
- Add 3 new test cases covering import-as, from-import, and from-import-as
- Sync docs/SKILL.md with veracity documentation and bump version to 7
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

📝 Walkthrough

Walkthrough

Adds a veracity verification campaign to intercept and reject hallucinated API suggestions during import. Introduces a --verify-veracity CLI flag, threads configuration through the import pipeline, implements VeracityPlugin interface with Python-specific AST-based verification, and integrates the veracity check into the holistic issue import flow.

Changes

Veracity Verification Campaign

Layer / File(s) Summary
Interface & Types
desloppify/intelligence/review/veracity.py
Defines VeracityIssue TypedDict and abstract VeracityPlugin base class with verify_suggestion(suggestion: str, *, project_root: str | None = None) method.
CLI Flag & Options
desloppify/app/cli_support/parser_groups_admin_review_options_core.py
Adds --verify-veracity boolean flag to the core options argument group.
Configuration Wiring
desloppify/app/commands/review/cmd.py, desloppify/app/commands/review/importing/flags.py, desloppify/app/commands/review/importing/parse.py
Threads verify_veracity from CLI args through ReviewOptionsReviewImportConfigImportParseOptions.
Language Framework Integration
desloppify/languages/_framework/base/types.py
Adds veracity_plugin: VeracityPlugin | None attribute to LangRuntimeContract and LangConfig.
Python Plugin Implementation
desloppify/languages/python/veracity.py
Implements PythonVeracityPlugin with AST parsing, import alias resolution, and importlib introspection to detect missing attributes on modules.
Language Package Wiring
desloppify/languages/python/__init__.py
Instantiates PythonVeracityPlugin() and passes it to PythonConfig.
Import Pipeline Integration
desloppify/intelligence/review/importing/holistic.py, desloppify/intelligence/review/importing/holistic_issue_flow.py
Updates import_holistic_issues and validate_and_build_issues to accept verify_veracity flag; conditionally loads plugin from registry and rejects issues with verification errors.
Verification Tests
desloppify/languages/python/tests/test_py_veracity.py
Comprehensive pytest cases covering valid suggestions, hallucinated methods (e.g., os.path.non_existent_method()), and import aliasing scenarios.
Documentation & Version Bump
desloppify/app/skill_docs.py, desloppify/data/global/SKILL.md, docs/SKILL.md, ISSUE_DEHALLUCINATION.md
Bumps SKILL_VERSION to 7, updates skill docs with --verify-veracity usage guidance, and documents the feature spec.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI Parser
    participant Config as Review Config
    participant Holistic as holistic.py
    participant Flow as holistic_issue_flow.py
    participant Registry as Language Registry
    participant Plugin as VeracityPlugin
    participant AST as AST Parser

    CLI->>Config: --verify-veracity flag
    Config->>Holistic: ReviewImportConfig(verify_veracity=True)
    Holistic->>Flow: verify_veracity=True
    
    loop For each issue
        Flow->>Registry: get_lang_config()
        Registry->>Plugin: Load veracity_plugin
        
        alt Has suggestion
            Flow->>Plugin: verify_suggestion(suggestion)
            Plugin->>AST: parse Python code blocks
            AST->>Plugin: AST tree
            Plugin->>Plugin: resolve imports & attributes
            Plugin->>Plugin: importlib.import_module()
            Plugin->>Flow: VeracityIssue[] or []
        end
        
        alt Verification errors
            Flow->>Flow: Skip issue, add to rejected
        else No errors
            Flow->>Flow: Import issue normally
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 7 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (7 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the main campaign: implementing a veracity gate for API de-hallucination, which is precisely what this changeset accomplishes across the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No Hardcoded Secrets Or Credentials ✅ Passed Comprehensive investigation across all modified files found no hardcoded secrets, API keys, tokens, passwords, or credentials in the PR's codebase.
No Speciesist Idioms ✅ Passed PR investigation found no speciesist idioms in code or documentation changes; reference table educates proper terminology mapping.
No Tier 3 Data Committed ✅ Passed PR contains no Tier 3 sensitive data; abstract animal advocacy terminology used for design/threat modeling only, not operational details or real identities.

✏️ 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 feature/dehallucination-gate
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feature/dehallucination-gate
  • 🛠️ fix NAV violations: Commit on current branch
  • 🛠️ fix NAV violations: Create PR

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
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

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

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: 5

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

Inline comments:
In `@desloppify/app/commands/review/cmd.py`:
- Around line 194-195: The --verify-veracity flag is being set but never
forwarded to the import path; update the import flow to accept and forward this
kwarg: add verify_veracity=opts.verify_veracity when calling
import_holistic_issues in desloppify/app/commands/review/importing/cmd.py (and
the other call around the 211–212 region), and modify the wrapper in
desloppify/intelligence/review/__init__.py to accept a verify_veracity parameter
and pass it through to the underlying import function so the flag reaches
import_holistic_issues.

In `@desloppify/languages/python/veracity.py`:
- Around line 109-147: The two broad "except Exception: pass" blocks in
veracity.py (around the import/attribute resolution logic that checks
module_path, parent_path, and obj attributes) must not swallow unexpected
errors; replace them with specific handlers and surface verifier failures as
veracity issues: keep the existing ImportError handling, explicitly catch
AttributeError or known expected exceptions, and for any other Exception create
and return a veracity issue dict (same shape as the existing hallucination
return: keys "method","module","message","code_block") containing the exception
message and context (e.g., f"Verifier error while resolving {module_path}:
{exc}") so the failure is reported instead of silently accepting the suggestion;
ensure these changes reference the same logic around module import/parent_module
and obj attribute checks in the code paths using module_path, parent_path,
actual_attr, and attr_name.
- Around line 46-48: The verifier only extracts fenced blocks labeled "python"
and only accepts attribute calls whose base is ast.Name, so suggestions like
unlabeled/fenced diff/suggestion blocks and calls like Path("x").missing() are
missed; update _extract_python_blocks to also match unlabeled/fenced blocks and
common suggestion shapes (e.g., ```diff```, ```suggestion```, and plain
```...``` blocks) so Python code in those blocks is captured, and update
_verify_attribute_call to unwrap call/attribute chains: when checking the base
accept ast.Attribute and ast.Call by peeling ast.Call to its func and resolving
nested ast.Attribute/ast.Name (e.g., recognize func names like "Path" or
attribute chains like "pathlib.Path") before validating the attribute access, so
both Path("...").foo and pathlib.Path("...").foo forms pass verification.

In `@ISSUE_DEHALLUCINATION.md`:
- Around line 3-23: The markdown headings in ISSUE_DEHALLUCINATION.md need a
blank line after them to satisfy MD022; insert an empty line immediately after
the headings "## Goal", "## Context", "## Specification", and "## Definition of
Done" so that each heading is followed by a single blank line and the file
passes the linter.
- Line 8: Update the documentation reference so it points to the actual module
path used in this campaign: replace the incorrect
`intelligence/review/importing/holistic.py` with
`desloppify/intelligence/review/importing/holistic.py` wherever the spec
mentions the import-flow implementation (notably the `import_holistic_issues`
implementation), ensuring any follow-up investigations reference the real file
location.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8b137331-fe65-4405-8c03-428b8acc5ea8

📥 Commits

Reviewing files that changed from the base of the PR and between 99b4442 and ff34082.

📒 Files selected for processing (15)
  • ISSUE_DEHALLUCINATION.md
  • desloppify/app/cli_support/parser_groups_admin_review_options_core.py
  • desloppify/app/commands/review/cmd.py
  • desloppify/app/commands/review/importing/flags.py
  • desloppify/app/commands/review/importing/parse.py
  • desloppify/app/skill_docs.py
  • desloppify/data/global/SKILL.md
  • desloppify/intelligence/review/importing/holistic.py
  • desloppify/intelligence/review/importing/holistic_issue_flow.py
  • desloppify/intelligence/review/veracity.py
  • desloppify/languages/_framework/base/types.py
  • desloppify/languages/python/__init__.py
  • desloppify/languages/python/tests/test_py_veracity.py
  • desloppify/languages/python/veracity.py
  • docs/SKILL.md

Comment on lines +194 to 195
verify_veracity=opts.verify_veracity,
),
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 | ⚡ Quick win

--verify-veracity still does not reach the import campaign.

These fields are populated here, but desloppify/app/commands/review/importing/cmd.py:326-330 still calls import_holistic_issues(...) without verify_veracity, and desloppify/intelligence/review/__init__.py:90-109 drops the kwarg in its wrapper. As shipped, desloppify review --import --verify-veracity behaves the same as without the flag.

Also applies to: 211-212

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

In `@desloppify/app/commands/review/cmd.py` around lines 194 - 195, The
--verify-veracity flag is being set but never forwarded to the import path;
update the import flow to accept and forward this kwarg: add
verify_veracity=opts.verify_veracity when calling import_holistic_issues in
desloppify/app/commands/review/importing/cmd.py (and the other call around the
211–212 region), and modify the wrapper in
desloppify/intelligence/review/__init__.py to accept a verify_veracity parameter
and pass it through to the underlying import function so the flag reaches
import_holistic_issues.

Comment on lines +46 to +48
def _extract_python_blocks(self, text: str) -> list[str]:
"""Extract code from ```python ... ``` blocks."""
return re.findall(r"```python\s+(.*?)```", text, re.DOTALL)
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 | 🏗️ Heavy lift

The verifier misses common suggestion shapes, so the gate is easy to bypass.

_extract_python_blocks() only scans fenced python blocks, so diff or unlabeled suggestion blocks are ignored, and _verify_attribute_call() bails unless the base resolves to ast.Name, which misses common forms like pathlib.Path("x").missing() / Path("x").missing(). That leaves real imported fixes outside the campaign’s coverage.

Also applies to: 77-92

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

In `@desloppify/languages/python/veracity.py` around lines 46 - 48, The verifier
only extracts fenced blocks labeled "python" and only accepts attribute calls
whose base is ast.Name, so suggestions like unlabeled/fenced diff/suggestion
blocks and calls like Path("x").missing() are missed; update
_extract_python_blocks to also match unlabeled/fenced blocks and common
suggestion shapes (e.g., ```diff```, ```suggestion```, and plain ```...```
blocks) so Python code in those blocks is captured, and update
_verify_attribute_call to unwrap call/attribute chains: when checking the base
accept ast.Attribute and ast.Call by peeling ast.Call to its func and resolving
nested ast.Attribute/ast.Name (e.g., recognize func names like "Path" or
attribute chains like "pathlib.Path") before validating the attribute access, so
both Path("...").foo and pathlib.Path("...").foo forms pass verification.

Comment on lines +109 to +147
try:
# We check if it's in our safe list OR if it's already in sys.modules
# (which means it's already loaded in this environment)
import sys
if root_package in self.SAFE_MODULES or root_package in sys.modules:
# Try to import the specific module path
try:
module = importlib.import_module(module_path)
if not hasattr(module, attr_name):
return {
"method": attr_name,
"module": module_path,
"message": f"Hallucinated API detected: '{module_path}.{attr_name}' does not exist.",
"code_block": block
}
except ImportError:
# If we can't import the submodule, it might be a method call
# on an object, which we don't handle well yet.
# e.g. os.path.join().exists()
# In that case, we try to import the parent and see if it has the attribute.
parent_path = ".".join(module_path.split(".")[:-1])
if parent_path:
try:
parent_module = importlib.import_module(parent_path)
actual_attr = module_path.split(".")[-1]
if hasattr(parent_module, actual_attr):
# The 'module_path' was actually parent.attr
obj = getattr(parent_module, actual_attr)
if not hasattr(obj, attr_name):
return {
"method": attr_name,
"module": module_path,
"message": f"Hallucinated API detected: '{module_path}.{attr_name}' does not exist.",
"code_block": block
}
except Exception:
pass
except Exception:
pass
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 | ⚡ Quick win

Do not fail open on verifier exceptions.

Both except Exception: pass blocks turn verifier failures into silent accepts. For a de-hallucination gate, unexpected resolver errors should surface or produce a veracity issue instead of letting the suggestion through.

As per coding guidelines, "Use specific exception handling, never catch-all blocks; AI suppresses errors and removes safety checks".

🧰 Tools
🪛 Ruff (0.15.12)

[error] 144-145: try-except-pass detected, consider logging the exception

(S110)


[warning] 144-144: Do not catch blind exception: Exception

(BLE001)


[error] 146-147: try-except-pass detected, consider logging the exception

(S110)


[warning] 146-146: Do not catch blind exception: Exception

(BLE001)

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

In `@desloppify/languages/python/veracity.py` around lines 109 - 147, The two
broad "except Exception: pass" blocks in veracity.py (around the
import/attribute resolution logic that checks module_path, parent_path, and obj
attributes) must not swallow unexpected errors; replace them with specific
handlers and surface verifier failures as veracity issues: keep the existing
ImportError handling, explicitly catch AttributeError or known expected
exceptions, and for any other Exception create and return a veracity issue dict
(same shape as the existing hallucination return: keys
"method","module","message","code_block") containing the exception message and
context (e.g., f"Verifier error while resolving {module_path}: {exc}") so the
failure is reported instead of silently accepting the suggestion; ensure these
changes reference the same logic around module import/parent_module and obj
attribute checks in the code paths using module_path, parent_path, actual_attr,
and attr_name.

Comment thread ISSUE_DEHALLUCINATION.md
Comment on lines +3 to +23
## Goal
Prevent AI agents from proposing "slop" fixes that utilize hallucinated library methods or deprecated APIs. This is a common failure mode where agents invent methods that "should" exist but do not.

## Context
- **Repository:** `desloppify`
- **Location of Logic:** `intelligence/review/importing/holistic.py` (specifically `import_holistic_issues`).
- **Target Language (Phase 1):** Python.

## Specification
1. **Detection:** Intercept incoming `ReviewIssuePayload` during the import process.
2. **Extraction:** Identify code blocks within the `suggestion` field.
3. **Verification (Python):**
* Extract imported modules and method calls from the suggested code.
* Verify these calls against the local project environment (e.g., `sys.modules`, `pkg_resources`, or by inspecting the AST of installed packages).
* Reuse logic from `desloppify/languages/python/detectors/deps_resolution.py` if applicable.
4. **Feedback:** If a hallucinated API is detected:
* Reject the specific issue.
* Return a `VerificationIssue` to the agent with a clear message: `"Hallucinated API detected: [method_name]. Please verify against the actual library structure and refactor."`
5. **Configuration:** Allow this check to be toggled via a new flag `--verify-veracity`.

## Definition of Done
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 | 🟡 Minor | ⚡ Quick win

Fix heading spacing (MD022) to keep the spec lint-clean.

Add a blank line after headings at Line 3, Line 6, Line 11, and Line 23.

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 3-3: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 6-6: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 11-11: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 23-23: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

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

In `@ISSUE_DEHALLUCINATION.md` around lines 3 - 23, The markdown headings in
ISSUE_DEHALLUCINATION.md need a blank line after them to satisfy MD022; insert
an empty line immediately after the headings "## Goal", "## Context", "##
Specification", and "## Definition of Done" so that each heading is followed by
a single blank line and the file passes the linter.

Comment thread ISSUE_DEHALLUCINATION.md

## Context
- **Repository:** `desloppify`
- **Location of Logic:** `intelligence/review/importing/holistic.py` (specifically `import_holistic_issues`).
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 | 🟡 Minor | ⚡ Quick win

Correct the spec path for the import-flow implementation.

Line 8 references intelligence/review/importing/holistic.py, but the implemented path in this campaign is desloppify/intelligence/review/importing/holistic.py. This can send follow-up investigation to the wrong location.

Suggested doc fix
-- **Location of Logic:** `intelligence/review/importing/holistic.py` (specifically `import_holistic_issues`).
+- **Location of Logic:** `desloppify/intelligence/review/importing/holistic.py` (specifically `import_holistic_issues`).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **Location of Logic:** `intelligence/review/importing/holistic.py` (specifically `import_holistic_issues`).
- **Location of Logic:** `desloppify/intelligence/review/importing/holistic.py` (specifically `import_holistic_issues`).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ISSUE_DEHALLUCINATION.md` at line 8, Update the documentation reference so it
points to the actual module path used in this campaign: replace the incorrect
`intelligence/review/importing/holistic.py` with
`desloppify/intelligence/review/importing/holistic.py` wherever the spec
mentions the import-flow implementation (notably the `import_holistic_issues`
implementation), ensuring any follow-up investigations reference the real file
location.

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.

1 participant