harness: flag any only in exported signatures

The advisory fired on stringList(v any), which reads the open page object that
ADR-0002 mandates — so its false-positive rate was total, and a warning that is
always wrong teaches you to skim warnings. conventions.md bans interface{} as an
API escape hatch, which is what the check now looks for: any or interface{} in an
exported func or method signature. Verified by adding an exported func Do(x any)
and watching it fire, then reverting.
This commit is contained in:
Claude Opus 5
2026-07-30 01:46:48 +06:00
committed by bdeshi
parent c3fc89a913
commit b6806fa544
2 changed files with 8 additions and 5 deletions
+3 -2
View File
@@ -124,8 +124,9 @@ is a codebase still navigable by `go doc` and `git log` alone, years from now, w
instead of `log/slog`, `panic()` outside `cmd/`, and `time.Now()` outside a `clock.go` are stated
absolutely in `conventions.md`, so they exit non-zero. That last one exists because a Stage that reads
the clock without an expiry would serve staleness invisibly. A rule enforced as a suggestion teaches the agent to read every rule as one.
Softer signals `fmt.Errorf` without `%w`, `interface{}`, nesting past 4, exported-and-referenced-
once — stay advisory.
Softer signals stay advisory: `fmt.Errorf` without `%w`, nesting past 4, exported-and-referenced-once,
and `any` in an **exported** signature — only exported, because ADR-0002 mandates an open page object,
so unexported code reading frontmatter takes `any` legitimately and forever.
**STATUS markers in `docs/architecture.md`** give the target shape *and* what is legal today, so
the agent can read the endgame without building toward it.
+5 -3
View File
@@ -379,9 +379,11 @@ if [ -n "$panics" ]; then bad "panic() outside cmd/ — request-time failure deg
head_ "smells (advisory)"
nowrap=$(echo "$gofiles" | xargs grep -n 'fmt\.Errorf(' 2>/dev/null | grep -v '%w' | wc -l | tr -d ' ')
[ "${nowrap:-0}" -gt 0 ] && note "$nowrap fmt.Errorf without %w (wrap at package boundaries)"
# -H forces the filename even for a single file; comment lines are prose, where "any" is a word
anyuse=$(echo "$gofiles" | grep -v '_test\.go$' | xargs grep -Hn 'interface{}\|\bany\b' 2>/dev/null |
grep -vE ':[[:space:]]*//' | grep -v 'map\[string\]any' | cut -d: -f1 | sort -u || true)
# Only exported signatures: conventions.md bans interface{} as an API escape hatch, but ADR-0002 mandates
# an open page object, so unexported code reading Extra legitimately takes any and always will.
anyuse=$(echo "$gofiles" | grep -v '_test\.go$' |
xargs grep -HnE '^func (\([^)]*\) )?[A-Z][A-Za-z0-9_]*\(.*(\bany\b|interface\{\})' 2>/dev/null |
cut -d: -f1 | sort -u || true)
[ -n "$anyuse" ] && note "interface{} or any present (no empty interface for flexibility): $(echo "$anyuse" | tr '\n' ' ')"
deep=$(echo "$gofiles" | xargs awk '/^\t\t\t\t\t[^\t}]/ {print FILENAME; nextfile}' 2>/dev/null | sort -u || true)
[ -n "$deep" ] && note "nesting past 4 (conventions.md): $(echo "$deep" | tr '\n' ' ')"