Skip to content

feat: report triggered scanner names in evaluation results - #13

Open
f5-aryan wants to merge 1 commit into
mainfrom
feature/fetch-scanners-triggered-field
Open

f5-aryan wants to merge 1 commit into
mainfrom
feature/fetch-scanners-triggered-field

Conversation

@f5-aryan

Copy link
Copy Markdown
Collaborator

While decoupling this project from GitLab I found a commit that only ever existed there. Allan Healy wrote it on 6 May 2025 on a branch called reformat_input_and_output_csv_and_fetchscanners, and it never made the jump to GitHub during the v2.0 refactor. Deleting the GitLab project would have taken it with it.

What it does

Scan responses tell you a prompt was flagged, but not which scanner flagged it. The API returns opaque scanner IDs, and the readable names live behind a separate /scanners endpoint that's partitioned by source. This resolves those IDs to names and records them in a new scanners field on every result.

Why it's a rewrite rather than a cherry-pick

The original predates the pocketflow refactor so it wouldn't apply cleanly, and it had a few problems worth fixing on the way across.

  1. It called the API at module import time. Simply importing prompt_evaluator would have fired five HTTP requests. That breaks CI, which imports this module in tests/test_integration.py while mocking only requests.post. The lookup is now lazy and cached, so it runs once per evaluation run and never at import.
  2. The requests had no timeout. A hung lookup would stall the entire run. Every request now carries one.
  3. There was no error handling, so one bad source discarded the whole map. Sources now fail independently and the rest survive.
  4. Unknown IDs became the literal string "Unknown Scanner", which threw the ID away. They now fall back to the raw ID so you keep something traceable.

Scope

The field flows through all four output formats plus the false positive and false negative exports. CSV and TSV get a scanners column with names joined by semicolons. JSONL and Parquet keep the native list. Records written before this change still serialise, they just get an empty cell.

There's also a new --no-scanner-names flag for skipping the extra requests when you only care about pass or fail.

The other half of Allan's commit handled CSV input with separate prompt and expected columns. That's already covered by tools/enhanced_dataset_reader.py, so I left it out.

Testing

36 new tests in tests/test_scanner_resolution.py, registered in the core suite so CI picks them up. They cover map caching and force refresh, partial and total source failure, the raw ID fallback, malformed payloads, and serialisation across every output format.

The full runner passes 5 of 5 suites at 77 tests. The flake8 critical gate is clean, and bandit reports zero findings on prompt_evaluator.py, matching main.

Original work by Allan Healy, preserved via Co-Authored-By on the commit.


Warp conversation

Co-Authored-By: Warp agent@warp.dev

Ports the scanner-mapping work from the GitLab-only branch
reformat_input_and_output_csv_and_fetchscanners, which was never carried
across to GitHub during the v2.0 refactor and would have been lost when
the GitLab project is deleted.

Scan responses identify scanners by opaque ID only. This resolves those
IDs to human-readable names via the paged /scanners endpoint and records
which scanners flagged each prompt in a new "scanners" field.

Differences from the original implementation:
- The lookup is lazy and cached rather than run at import time, so
  importing the module no longer performs network I/O. The original
  would have fired five requests on import and broken CI, which imports
  this module while mocking only requests.post.
- Requests carry an explicit timeout, and a failing source is skipped
  rather than aborting the whole lookup.
- Unknown scanner IDs fall back to the raw ID instead of a placeholder,
  so the information is preserved rather than discarded.
- The field flows through all four output formats and the false
  positive and false negative exports.
- Adds --no-scanner-names to skip the lookup entirely.

The CSV input handling from the original commit was already superseded
by tools/enhanced_dataset_reader.py and was not ported.

Co-Authored-By: Allan Healy <allan.healy@calypsoai.com>
Co-Authored-By: Warp <agent@warp.dev>
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