From dca60f53ed01b6b7c774443d3f5447569b25a922 Mon Sep 17 00:00:00 2001 From: Prekzursil Date: Wed, 12 Aug 2026 02:35:56 +0300 Subject: [PATCH] fix(sast): ship an explicit gate-4 scan set (0 files were unscanned) Gate 4 has been scanning a file set it INHERITED from a vendor default rather than one this repo chose, and the difference is invisible in the gate output. Measured 2026-08-11 on the PINNED CI engine (opengrep v1.22.0 CLI on Linux, exactly the build reusable-quality.yml installs), controlled detector, one variable changed at a time: src/inline.go db.Query(fmt.Sprintf(...)) -> FIRES tests/inline.go byte-identical to the line above -> SILENT `paths.skipped` reported `none` while it happened, so nothing in the gate output revealed it, and pointing the scanner directly at a test path does not override it. The dropped set, enumerated with one identical vulnerable file per candidate path: `*_test.go` at ANY depth, plus the `test/` and `tests/` directories. The engine abandons the built-in template as soon as ANY `.semgrepignore` exists, so shipping this file restores the test tree. EFFECT ON THIS REPO, using its own gate-4 scan paths (backend frontend): 211 files scanned before, 211 after (+0), 0 findings either way. BOTH-STATES PROOF, run against this repo's own curated ruleset: the same `eval()` file in src/ and under tests/ with this .semgrepignore -> BOTH fire, gate exit 1 with it removed (control) -> src/ fires, tests/ INVISIBLE a clean `ast.literal_eval` file -> silent, gate exit 0 The control is the load-bearing half: a probe that is silent in the broken state measures nothing, so the hole is demonstrated rather than asserted. No exclusion was added to make any finding go away -- the finding count is unchanged. Every directory entry ships both the root-anchored and the nested form, because a bare `**/x/` does NOT match a root-level `x/` and fails open with no warning (measured with a positive control). Companion control-plane change -- the copyable template plus a non-blocking gate-4 warning for callers with no explicit scan set: Prekzursil/quality-zero-platform#289. --- .semgrepignore | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .semgrepignore diff --git a/.semgrepignore b/.semgrepignore new file mode 100644 index 00000000..81fef50f --- /dev/null +++ b/.semgrepignore @@ -0,0 +1,70 @@ +# opengrep / semgrep ignore — gate 4 (SAST). Adopted from quality-zero-platform +# docs/lean-gate/semgrepignore.template. +# +# ── WHY THIS FILE EXISTS ──────────────────────────────────────────────────── +# +# With NO `.semgrepignore` in the scanned root, opengrep falls back to a +# BUILT-IN ignore template that drops test code. Measured 2026-08-11 on the +# PINNED CI engine (opengrep v1.22.0 CLI on Linux, the exact build gate 4 +# installs), controlled detector, one variable changed at a time: +# +# src/inline.go db.Query(fmt.Sprintf(...)) -> FIRES +# tests/inline.go byte-identical to the line above -> SILENT +# +# and `paths.skipped` reported `none` while it happened, so NOTHING in the gate +# output revealed it. Pointing the scanner directly at `tests/` returns +# `paths.scanned: []`, so an explicit path argument does not override it either. +# +# The dropped set, enumerated with one identical vulnerable file per candidate +# path: `*_test.go` at ANY depth, plus the `test/` and `tests/` directories. +# (Python/TS test FILENAMES — `test_app.py`, `app_test.py`, `conftest.py`, +# `app.test.ts`, `app.spec.ts`, `__tests__/` — are NOT dropped; only the two +# directories are.) The engine abandons the built-in template as soon as ANY +# `.semgrepignore` exists, so shipping this file restores the test tree and +# makes the scanned set a DELIBERATE choice. +# +# Effect measured on THIS repo, using its own gate-4 scan paths (backend frontend): +# 211 files scanned before, 211 after — NO CHANGE TODAY, because nothing +# under those paths matches `*_test.go` or a `test/`/`tests/` directory right +# now. This file is still correct and load-bearing: it makes the scanned set a +# deliberate choice, so the FIRST test directory added here is scanned instead +# of being silently dropped. 0 findings either way. +# +# ── EDITING RULES ─────────────────────────────────────────────────────────── +# +# 1. NEVER add `*_test.go`, `test/`, `tests/`, `spec/` or `__tests__/`. +# First-party test code is first-party code — it handles credentials, builds +# queries and shells out. Re-excluding it restores the exact hole this file +# closes. +# 2. Every directory entry ships BOTH the root-anchored and the nested form: a +# bare `**/x/` does NOT match a root-level `x/`, and it fails open with no +# warning. Measured with a positive control — `**/vendor/` left a root-level +# `vendor/pkg/b.go` scanned while `vendor/` excluded both trees. +# 3. An exclusion is a statement about SCOPE ("this is not our source"), never +# about severity. Do not use this file to make a finding go away. + +.git/ + +# Vendored third-party source. Not ours to fix, and upstream style trips +# first-party rules. Secrets in these trees stay covered by gitleaks (gate 5), +# which scans independently of this file. +vendor/ +**/vendor/ +vendor_src/ +**/vendor_src/ +node_modules/ +**/node_modules/ + +# Installed dependencies (virtualenvs) — third-party bytes, not source. +.venv/ +**/.venv/ +venv/ +**/venv/ + +# Build output, generated from source that gate 4 already scans. +dist/ +**/dist/ +build/ +**/build/ +out/ +**/out/