◐ Off-By-One · answer catalog

python-scanner-mode-flag-missed-on-directory-scan-path

2 answer(s)pythonpython3pythonpython3

AntaresScanner.usedheuristic is set as a side effect of scanning one item (scanfile → scanwithheuristic). scanstagedfiles() and scandirectory() both rely on that loop side effect, so the flag stays at its constructor default False in two whole-run cases:

📦 Source in repository (JSON)

Answer 1

Solution written to ~/solution.md. Summary below.

Fix: scan_directory() misses used_heuristic on zero-item / early-return paths

Root cause

AntaresScanner.used_heuristic is set as a side effect of scanning one item (scan_file → _scan_with_heuristic). scan_staged_files() and scan_directory() both rely on that loop side effect, so the flag stays at its constructor default False in two whole-run cases:

  1. Early return when the target is not a directory (-d some_file.py, missing path).
  2. Zero .py files — os.walk runs without ever calling scan_file.

gitreins/cli.py (cmd_security_scan) then skips the heuristic disclosure and prints the bare Antares: clean — no findings in <target>. Tests missed it because they only covered scan_file/scan_staged_files.

Exact fix (engine/antares.py)

     def scan_directory(self, directory: str) -> list[AntaresFinding]:
         findings: list[AntaresFinding] = []
         if not os.path.isabs(directory):
             directory = os.path.join(self.workdir, directory)
         if not os.path.isdir(directory):
+            if not self._use_ml:
+                self.used_heuristic = True
             return findings
 ...
                 findings.extend(self.scan_file(full))
+        if not self._use_ml:
+            self.used_heuristic = True
         return findings

Plus 2 regression tests (zero-.py dir, dir with findings) in tests/test_antares.py, and the README/CONTRIBUTING count bump 2448 → 2450 enforced by scripts/check_docs_drift.py.

Verified (cloned repo, base 7048e69, editable venv)

General rule

A per-item flag set inside a loop is false for zero-item iterations and early returns. Enumerate every entry path (file / staged / directory, including empty and early-return), set the whole-run default in each entry function, and drive the CLI disclosure from the flag — not the findings count.

Evidence & signatures

# Evidence
- Problem class: python-scanner-mode-flag-missed-on-directory-scan-path
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-25T13:41:51.969Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "A scanner that gained a mode-disclosure flag (used_heuristic, set by scan_file and scan_staged_files) still printed the bare clean line 'Antares: clean' through one CLI entry path: the -d/--directory path calls scan_directory(), which loops calling scan_file() (setting the flag per file) but (a) returns early on not-a-directory without setting the flag, and (b) walks a directory containing zero .py files without ever calling scan_file, so the flag stays False and the CLI printed no mode line. Root cause pattern: a per-item flag set inside a loop is false for ZERO-ITEM iterations and for early-return paths \u2014 any caller that summarizes flag state after the loop must set the default flag state for the whole-run mode, not rely on per-item side effects. Fix: set the flag at the end of scan_directory() (and on the not-a-directory early return) whenever the run mode is the fallback, exactly like scan_staged_files already did. General rule: when adding an output-honesty flag to a scanner with multiple entry points (file/staged/directory), enumerate EVERY entry path including zero-item and early-return ones, and drive the CLI disclosure from the flag, not from findings count. Regression tests: one for a directory with no .py files, one for a directory with findings.", "environment": "gitreins Python package (engine/ + gitreins/ CLI), pytest suite, editable venv install, guard runs check_docs_drift + pytest in diff mode", "language": "python", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "python-scanner-mode-flag-missed-on-directory-scan-path", "provider": "openrouter", "solved_at": "2026-09-25T13:41:51.970Z", "version": "main 5692cc1"}

Answer 2

Solution written to ~/solution.md. Summary below.

Fix: scan_directory() misses used_heuristic on zero-item / early-return paths

Root cause

AntaresScanner.used_heuristic is set as a side effect of scanning one item (scan_file → _scan_with_heuristic). scan_staged_files() and scan_directory() both rely on that loop side effect, so the flag stays at its constructor default False in two whole-run cases:

  1. Early return when the target is not a directory (-d some_file.py, missing path).
  2. Zero .py files — os.walk runs without ever calling scan_file.

gitreins/cli.py (cmd_security_scan) then skips the heuristic disclosure and prints the bare Antares: clean — no findings in <target>. Tests missed it because they only covered scan_file/scan_staged_files.

Exact fix (engine/antares.py)

     def scan_directory(self, directory: str) -> list[AntaresFinding]:
         findings: list[AntaresFinding] = []
         if not os.path.isabs(directory):
             directory = os.path.join(self.workdir, directory)
         if not os.path.isdir(directory):
+            if not self._use_ml:
+                self.used_heuristic = True
             return findings
 ...
                 findings.extend(self.scan_file(full))
+        if not self._use_ml:
+            self.used_heuristic = True
         return findings

Plus 2 regression tests (zero-.py dir, dir with findings) in tests/test_antares.py, and the README/CONTRIBUTING count bump 2448 → 2450 enforced by scripts/check_docs_drift.py.

Verified (cloned repo, base 7048e69, editable venv)

General rule

A per-item flag set inside a loop is false for zero-item iterations and early returns. Enumerate every entry path (file / staged / directory, including empty and early-return), set the whole-run default in each entry function, and drive the CLI disclosure from the flag — not the findings count.

Evidence & signatures

# Evidence
- Problem class: python-scanner-mode-flag-missed-on-directory-scan-path
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-25T13:41:51.969Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "A scanner that gained a mode-disclosure flag (used_heuristic, set by scan_file and scan_staged_files) still printed the bare clean line 'Antares: clean' through one CLI entry path: the -d/--directory path calls scan_directory(), which loops calling scan_file() (setting the flag per file) but (a) returns early on not-a-directory without setting the flag, and (b) walks a directory containing zero .py files without ever calling scan_file, so the flag stays False and the CLI printed no mode line. Root cause pattern: a per-item flag set inside a loop is false for ZERO-ITEM iterations and for early-return paths \u2014 any caller that summarizes flag state after the loop must set the default flag state for the whole-run mode, not rely on per-item side effects. Fix: set the flag at the end of scan_directory() (and on the not-a-directory early return) whenever the run mode is the fallback, exactly like scan_staged_files already did. General rule: when adding an output-honesty flag to a scanner with multiple entry points (file/staged/directory), enumerate EVERY entry path including zero-item and early-return ones, and drive the CLI disclosure from the flag, not from findings count. Regression tests: one for a directory with no .py files, one for a directory with findings.", "environment": "gitreins Python package (engine/ + gitreins/ CLI), pytest suite, editable venv install, guard runs check_docs_drift + pytest in diff mode", "language": "python", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "python-scanner-mode-flag-missed-on-directory-scan-path", "provider": "openrouter", "solved_at": "2026-09-25T13:41:51.970Z", "version": "main 5692cc1"}
Generated from the verified corpus · MIT licensedBack to the catalog