feat(checks): unify inspection scope in checks/scope.ts

Single source of truth for what pygienium inspects (implementation-code
extensions, exclude dirs, .d.ts/.min.* exclusions) shared by recon,
dead-code, deep-modules, defensive-guards, comments, and complexity.
Every scan task and agent prompt injects the shared scope rules instead
of copy-pasted per-check lists.
This commit is contained in:
2026-08-09 16:45:29 -04:00
parent 581436ed23
commit 2caeb2f790
10 changed files with 268 additions and 112 deletions

View File

@@ -48,6 +48,7 @@ import {
type CheckDefinition,
type CheckScope,
} from "./registry.js";
import { isScopeSource, scopeRulesMarkdown } from "./scope.js";
/** Output directory for this check's persistent reports. */
export function defensiveGuardsOutputDir(cwd: string): string {
@@ -64,26 +65,6 @@ export function changesPath(cwd: string): string {
return join(defensiveGuardsOutputDir(cwd), "changes.md");
}
/** Source extensions this check inspects. */
const DEFENSIVE_GUARDS_EXTENSIONS = new Set([
".ts",
".tsx",
".js",
".jsx",
".mjs",
".cjs",
".py",
".rb",
".go",
".rs",
".java",
".kt",
".swift",
".php",
".cs",
".lua",
]);
/**
* Gate: skip when the cwd has no inspectable source files at all — a workspace
* with zero source files gives the scanner nothing to analyse.
@@ -93,9 +74,7 @@ function defensiveGuardsGate(cwd: string): string | undefined {
try {
const entries = readdirSync(cwd);
for (const entry of entries) {
const dot = entry.lastIndexOf(".");
const ext = dot === -1 ? "" : entry.slice(dot).toLowerCase();
if (DEFENSIVE_GUARDS_EXTENSIONS.has(ext)) {
if (isScopeSource(entry)) {
found = true;
break;
}
@@ -137,6 +116,8 @@ function buildDefensiveGuardsScanTask(cwd: string, scope: CheckScope): string {
`reason.`,
`Then emit a one-line summary referencing the findings path.`,
``,
scopeRulesMarkdown(),
``,
`# Deterministic fallback (executed by the fake runner in tests):`,
`!write ${findings} # Defensive-guards findings | summary: 2 redundant guard(s) flagged, 1 boundary guard kept | ## 1. ${target}/noise.ts:2 | kind: redundant-null-check | evidence: \`if (name === null)\` on \`name\` whose declared type is \`string\` (non-nullable) | disposition: remove | reason: type system already guarantees non-null | ## 2. ${target}/noise.ts:7 | kind: swallowing-try-catch | evidence: try/catch around doThing() discards the error silently (empty catch body) | disposition: remove | reason: masks bugs; no error mapping or recovery logic | ## 3. ${target}/boundary.ts:2 | kind: parsing-guard | evidence: try/catch around JSON.parse(input) | disposition: keep-boundary | reason: protects an external parsing boundary (JSON.parse of untrusted input)`,
`!echo defensive-guards: 2 redundant, 1 boundary kept — see ${findings}`,