Repository navigation
FIX: Extract Ruby gems required via subpaths or with parentheses in PackageHallucinationScorer (#3692) - #3693
Conversation
…ackageHallucinationScorer (microsoft#3692) Support Ruby gem subpath requires and parenthesized require/gem calls in PackageHallucinationScorer. Fixes microsoft#3692
Roman Lutz (romanlutz)
left a comment
There was a problem hiding this comment.
The additional Ruby syntax support is useful, but the newly matched inputs have correctness and performance problems. The concrete cases are inline.
|
Thanks for thorough review Roman Lutz (@romanlutz), addressed in the latest commit. |
Roman Lutz (romanlutz)
left a comment
There was a problem hiding this comment.
The update addresses the explicit feature extensions, interpolation examples, Windows paths, and the original overlapping-whitespace regex. I found two additional problems in the revised implementation. This pass is source-only: the new unbounded candidate expansion keeps the execution safety hold in place, so I did not run the updated code or tests.
…d avoid near-name false negatives (microsoft#3693) - Enforce limits on feature length (255) and path depth (5) to bound prefix candidate generation, falling back cleanly to the root segment on inputs exceeding limits. - Support multiline parenthesized require and gem calls with internal line breaks while keeping unparenthesized calls ReDoS-safe with strict horizontal spacing. - Remove arbitrary underscore stripping to prevent near-name false negatives (e.g. j_s_o_n, review_ghost). - Map standard Rails namespaces (e.g. active_support -> activesupport) explicitly. - Add tests for multiline calls via public scoring, deep path performance control, and negative near-name cases.
|
Roman Lutz (@romanlutz), thanks for the feedback! In the latest commit, we bounded candidate expansion to 255 chars / 5 segments (with a 4,096-component performance control test) and enabled multiline parenthesized |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…crosoft#3693) - Decouple feature path depth from candidate prefix depth by inspecting leading prefixes up to 5 segments longest-first. - Resolve 6+ segment paths like 'google/cloud/spanner/v1/spanner/client' to their registered gem 'google-cloud-spanner-v1'. - Retain root namespace alias evaluation (e.g., active_support -> activesupport) even when feature path length exceeds 255 chars. - Add test_ruby_scores_deep_subpath_owning_gem_correctly_async verifying public scoring of deep subpaths.
Roman Lutz (romanlutz)
left a comment
There was a problem hiding this comment.
i'll make a couple fixes but this looks great!
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use public scoring for the added Ruby regression cases after the expectation-aware hook migration. Update the NCC research index link to its canonical destination for strict documentation checks. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Description
PackageHallucinationScorerchecks model-generated code for imports or requires of non-existent packages (OWASP LLM02).In the Ruby ecosystem (
PackageEcosystem.RUBY), the extraction regex previously used([a-zA-Z0-9_-]+)and required whitespace immediately afterrequire/gem:This caused two detection gaps:
require 'active_support/core_ext',require 'aws-sdk-s3/resource',require 'google/cloud/storage',require 'fake_gem/core') were rejected because/was forbidden in the capture group.require("gem_name"),require ("gem_name"), andgem("rails", "~> 7.0")failed because whitespace was strictly demanded directly following the method name.This PR:
(?:\s*\(|\s+)and subpath specifiers[^'\"\s]+forrequire, and optional parentheses forgem._extract_package_references(reference.split("/", 1)[0]) and ignores local relative and absolute paths (not reference.startswith((".", "/"))), bringing Ruby to architectural parity with the JavaScript ecosystem.Fixes #3692
Tests and Documentation
test_ruby_extracts_subpath_and_parenthesized_requirestesting subpath requires, parenthesized requires, version constraints, and indentation.test_ruby_ignores_relative_and_absolute_pathsverifying that relative paths (./,../), absolute paths (/),require_relative, and comments are ignored.test_ruby_scores_hallucinated_subpath_package_asyncverifying end-to-end scoring where known subpath packages scoreFalseand hallucinated subpath packages scoreTruewith accurate rationale and metadata.test_package_hallucination_scorer.pypass.test_package_hallucination.pypass.tests/unit/score/regex/pass.ruff checkandruff format.