Skip to content

fix(analyzer): stop EA1 from matching multiline gaps and markdown bold spans - #414

Closed
AmirF194 wants to merge 1 commit into
NVIDIA:mainfrom
AmirF194:fix/405-ea1-multiline-bold-false-positive
Closed

fix(analyzer): stop EA1 from matching multiline gaps and markdown bold spans#414
AmirF194 wants to merge 1 commit into
NVIDIA:mainfrom
AmirF194:fix/405-ea1-multiline-bold-false-positive

Conversation

@AmirF194

Copy link
Copy Markdown
Contributor

Fixes #405.

Root cause

EA1_PATTERNS[0] in static_patterns_excessive_agency.py is
(?:tools?|permissions?)\s*:\s*\[?\s*['"]?\*['"]?\s*\]?. Python's \s matches
newlines regardless of re.MULTILINE, so the gap the pattern allows between the
colon and the wildcard value is unbounded across blank lines and paragraphs, and
the pattern has no check that the matched * is a standalone token rather than the
first * of a **bold** span. Two shapes both produce a false-positive EA1
finding on prose that grants no tool access: a blank-line gap (tool:\n\n**Input Schema:**) and a markdown bold heading (**API Coverage vs. Workflow Tools:**).

Fix

Replace the pattern with (?:tools?|permissions?)\s*:[ \t]*\[?[ \t]*['"]?\*(?!\*|\w)['"]?[ \t]*\]?:
restricts the gap to spaces/tabs (no longer crosses a blank line) and adds a
negative lookahead so the matched * cannot be followed by another * or a word
character, so it can no longer be the first character of a bold span or an
identifier. The three real wildcard-grant shapes (tools: "*", tools: [*],
permissions: '*') still match.

Verification

  • New regression tests in tests/nodes/analyzers/test_static_patterns.py: the two
    false-positive shapes from the issue no longer produce an EA1 finding, and the
    three real wildcard shapes still produce EA1 at MEDIUM severity.
  • make lint and make format-check clean.
  • Full unit suite in a clean python:3.12-slim container: 2800 passed (2795
    existing + 5 new), 14 skipped, 4 xfailed, matching the repo's test-unit gate.
    Under --cov (the test-ci recipe), two unrelated tests in
    test_security_end_to_end.py fail; reproduced the same two failures 3/3 runs
    against unmodified main under the same --cov flag, so this is a pre-existing
    flake independent of this change, not a regression it introduces.
  • docker-smoke (image build plus tests/docker/smoke.sh) passes.

…d spans

Signed-off-by: Amir Fathi <amirfathi.me@gmail.com>
@AmirF194

Copy link
Copy Markdown
Contributor Author

#417 fixes the same two EA1 false positives in this file (the newline-spanning \s* gap and the missing standalone-asterisk check). This one opened about a day earlier and covers both. Happy to close in favor of #417 if that is preferred, or maintainers can pick.

@rng1995 rng1995 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[SkillSpector Review]\n\nApproved. The horizontal-whitespace boundary and wildcard lookahead close the EA1 false positives without hiding real wildcard declarations, and the regression coverage is adequate. This overlaps PR #417, so maintainers should merge only the preferred implementation. Current required checks pass.

@rng1995

rng1995 commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

[SkillSpector Maintainer]

Closing this PR as superseded by #417, which is now merged.

The production change here is technically correct and identical to the merged regex fix: replacing newline-matching whitespace after the EA1 key with horizontal whitespace and requiring the wildcard asterisk to be standalone. We selected #417 because its focused regression suite additionally covers the single-newline boundary, the unquoted tools: * form, and bolded named-tool prose.

This PR was opened first and independently identified both root causes. Thank you @AmirF194 for the accurate diagnosis, sound implementation, and validation work.

@rng1995 rng1995 closed this Aug 24, 2026
@AmirF194
AmirF194 deleted the fix/405-ea1-multiline-bold-false-positive branch August 24, 2026 21:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants