Apply B5 from 2026-04-30 scrum — scanner skip-list scoped to harness self

Opus-only BLOCK from the cross-lineage scrum: pre-fix SkipDirs
basename-matched bin/build/dist/target/reports for ANY repo,
silently excluding legitimate source dirs on real targets. The
lakehouse Rust repo has reports/ holding markdown; some Java/
Python/Go projects use bin/ as a source dir; target/ is project-
specific. Skipping them globally produced silent false-negative
scans the operator would never know about.

Fix: trim SkipDirs to dirs that are universally not source code —
.git, .hg, .svn (VCS metadata); node_modules, vendor (dep caches);
__pycache__, .venv, venv (Python envs); .idea, .vscode (editor state).
Removed: bin, build, dist, target, reports.

For the harness's own self-skip (it shouldn't scan its own bin/
or reports/), added path-scoped skip via selfSkipsFor — detects
"this is the harness repo" by the presence of BOTH
cmd/review-harness/ AND internal/analyzers/ subdirs (combination
unique to this codebase), then skips the absolute paths bin/ and
reports/ for that scan only.

Two regression tests:
- TestWalk_DoesNotSkipBinReportsInTargetRepo plants files under
  bin/, reports/, build/, dist/, target/ in a synthetic target
  repo; asserts all 5 appear in scan, while .git/ + node_modules/
  + vendor/ are still skipped.
- TestWalk_SelfSkipsBinReportsInHarnessRepo plants the harness's
  marker dirs (cmd/review-harness/, internal/analyzers/) plus
  bin/ + reports/ + ordinary src/; asserts self-skip fires on
  bin/+reports/ but real src/ scans normally.

Compiled artifacts inside bin/ are filtered by the analyzers'
isTextLike extension check (.exe / .dll / .so), so target repos
with bin/ holding compiled output don't waste cycles decoding it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude (review-harness setup)
2026-04-30 01:34:45 -05:00
co-authored by Claude Opus 4.7
parent 305f5b9ac0
commit ab550a7c5a
2 changed files with 202 additions and 17 deletions
+75 -17
View File
@@ -14,26 +14,51 @@ import (
)
// SkipDirs is the default skip-list. Matches dir basenames anywhere
// in the tree (not just at root). Includes the harness's own output
// dir so review-on-self doesn't loop.
// in the tree (not just at root). Limited to dirs that are universally
// not source code — VCS metadata, dependency caches, language-specific
// virtual environments, editor state.
//
// Scrum fix B5 (Opus BLOCK, 2026-04-30): pre-fix this list also
// included `bin`, `build`, `dist`, `target`, `reports`. Those names
// have legitimate source-dir uses on target repos:
// - lakehouse Rust has `reports/` with markdown documentation
// - Java/Maven projects have `target/` build output but Gradle
// projects don't — and some projects use `target/` as a source dir
// - some Python projects keep scripts in `bin/`
//
// Skipping them globally produced silent false-negative scans on
// real targets. The harness's own self-skip is now path-scoped (see
// SkipPathsAbsolute below), not basename-scoped, so reviewing the
// harness against itself doesn't recurse into its own bin/reports
// while reviewing other repos with those names still works.
//
// Compiled binaries inside bin/ are filtered by the analyzers'
// isTextLike extension check (.exe / .dll / .so / etc.), so the
// scan doesn't waste time decoding them.
var SkipDirs = map[string]bool{
".git": true,
".hg": true,
".svn": true,
"node_modules": true,
"vendor": true,
"target": true, // Rust
"dist": true,
"build": true,
"__pycache__": true,
".venv": true,
"venv": true,
"bin": true, // golangLAKEHOUSE convention; harness's own too
".idea": true,
".vscode": true,
"reports": true, // harness's own output
".git": true,
".hg": true,
".svn": true,
"node_modules": true,
"vendor": true,
"__pycache__": true,
".venv": true,
"venv": true,
".idea": true,
".vscode": true,
}
// SkipPathsAbsolute is checked when scanning the harness's own repo —
// these are absolute paths (resolved from the repoPath at scan time)
// that the harness should never recurse into. Today: `bin/` (the
// review-harness binary lands here) and `reports/` (per-run output).
//
// Populated via PathScopedSkipsForSelf when the scanner detects it's
// scanning its own tree (heuristic: target path contains both
// `cmd/review-harness` AND `internal/analyzers`). Empty otherwise so
// other repos see the more permissive default skip-list.
var SkipPathsAbsolute = map[string]bool{}
// File is one entry in the scan result.
type File struct {
Path string // relative to repo root
@@ -72,6 +97,13 @@ func Walk(repoPath string, countLines bool) (*Result, error) {
LanguageBreakdown: map[string]int{},
}
// Path-scoped self-skip: when scanning the harness's own tree,
// also skip the dirs that hold its build artifacts + run output.
// Path-scoped (not basename-scoped) so other repos that happen
// to have `bin/` or `reports/` still get scanned. See SkipDirs
// docstring for B5 background.
pathSkips := selfSkipsFor(abs)
walkErr := filepath.WalkDir(abs, func(p string, d fs.DirEntry, walkErr error) error {
if walkErr != nil {
return nil // best-effort; permission errors etc. are silent
@@ -80,6 +112,9 @@ func Walk(repoPath string, countLines bool) (*Result, error) {
if SkipDirs[d.Name()] && p != abs {
return filepath.SkipDir
}
if pathSkips[p] {
return filepath.SkipDir
}
return nil
}
// Skip dotfiles at file level (.gitignore etc. are interesting,
@@ -138,6 +173,29 @@ func Walk(repoPath string, countLines bool) (*Result, error) {
return res, nil
}
// selfSkipsFor returns absolute paths to skip when scanning the
// harness's own tree (where `bin/` is build output and `reports/`
// is per-run runtime data). Empty when scanning anything else, so
// target repos with legitimate `bin/` / `reports/` directories
// don't get those silently excluded.
//
// Heuristic: harness self-detected when the target absolute path
// contains both `cmd/review-harness` AND `internal/analyzers`
// directories — that combination doesn't appear in arbitrary repos.
func selfSkipsFor(abs string) map[string]bool {
cmdMarker := filepath.Join(abs, "cmd", "review-harness")
intMarker := filepath.Join(abs, "internal", "analyzers")
st1, err1 := os.Stat(cmdMarker)
st2, err2 := os.Stat(intMarker)
if err1 != nil || err2 != nil || !st1.IsDir() || !st2.IsDir() {
return nil
}
return map[string]bool{
filepath.Join(abs, "bin"): true,
filepath.Join(abs, "reports"): true,
}
}
// interestingDotfile lets a few well-known dotfiles through despite
// the leading-dot filter. Keeps the scan honest about config files
// that often hold the real risk (e.g. committed .env).