feat(AGENT-25): add [scan] include/exclude path filters#17
Merged
Conversation
Add `[scan] include` and `[scan] exclude` globs to .agentshield.toml, relative to the scan root. `exclude` wins when both match. The filter runs before source-file collection/parsing across all adapters (MCP, OpenClaw, Hermes, CrewAI, LangChain, GPT Actions, Cursor Rules) and is surfaced in `scan --explain` as "Path filters". - src/config/mod.rs: parse include/exclude, compile glob patterns, precedence (included && !excluded) - adapters: apply path filter before collecting source files - src/ux.rs: report active path filters in --explain output - README.md / AGENTS.md: document the new config keys; reference the local Huly skill at skills/huly/SKILL.md - tests/path_filters.rs: include-only, exclude-only, exclude-wins precedence, and explain visibility
Code review found that `[scan] exclude`/`include` filtered parsed source
files but not metadata read directly from the scan root, so excluded
files still produced findings — violating the acceptance criterion
"Excluded files do not produce findings".
Thread `ScanPathFilter` into the MCP `tools.json` load path and into the
shared `parse_dependencies` / `parse_provenance` helpers (used by all
adapters), gating every root-relative metadata file
(requirements.txt, Pipfile.lock, poetry.lock, uv.lock, package.json,
package-lock.json, pyproject.toml, tools.json) on `allows_path`.
Reproduced before fix: `exclude = ["package.json"]` still emitted
SHIELD-009/SHIELD-012; `exclude = ["tools.json"]` still emitted
SHIELD-008. All suppressed after the fix; detectors still fire when
the files are not excluded.
- src/adapter/mcp.rs: gate tools.json load + parse_dependencies/
parse_provenance metadata files on the path filter
- src/adapter/{crewai,cursor_rules,gpt_actions,hermes,langchain}.rs:
pass the active filter into the shared helpers
- tests/path_filters.rs: regression tests for excluded package.json,
requirements.txt, and tools.json metadata findings
Collaborator
Author
|
Review follow-up for AGENT-25 addressed on this branch. Fixed in
Fixed in
Local verification passed:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements AGENT-25:
[scan] includeand[scan] excludeglob filters in.agentshield.toml, relative to the scan root.excludewins when both match. The filter runs before source-file collection/parsing across all adapters (MCP, OpenClaw, Hermes, CrewAI, LangChain, GPT Actions, Cursor Rules) and is surfaced inscan --explainasPath filters.Two commits:
feat(AGENT-25)— the feature: config parsing, glob compilation, precedence (included && !excluded), per-adapter filtering, and--explainvisibility. Docs (README.md,AGENTS.md) and the local Huly skill reference. Addstests/path_filters.rs(include-only, exclude-only, exclude-wins precedence, explain visibility).fix(AGENT-25)— closes a bypass found in code review (see below).Code review fix (metadata-derived findings)
Review found the first commit filtered parsed source files but not metadata read directly from the scan root, so excluded files still produced findings — violating the acceptance criterion "Excluded files do not produce findings".
Reproduced before the fix:
exclude = ["package.json"]still emittedSHIELD-009/SHIELD-012located atpackage.jsonexclude = ["tools.json"]still emittedSHIELD-008from excluded tool metadataFix threads
ScanPathFilterinto the MCPtools.jsonload path and into the sharedparse_dependencies/parse_provenancehelpers (used by all adapters), gating every root-relative metadata file onallows_path:requirements.txt,Pipfile.lock,poetry.lock,uv.lock,package.json,package-lock.json,pyproject.toml,tools.json.Added regression tests for
exclude = ["package.json"],["requirements.txt"], and["tools.json"]— these failed before the fix (RED) and pass after (GREEN).Test plan
cargo test— 253 passedcargo test --all-features— 328 passedcargo test --no-default-features— 247 passedcargo clippy --all-targets --all-features -- -D warnings— no issuescargo fmt --all -- --check— cleangit diff --check— cleanexcludeactive → 0 findings; withoutexclude→ findings return (detectors intact)Closes AGENT-25.