Skip to content

docs(knowledge): record scan-precision findings and correct an unenforced invariant - #188

Open
alxxjohn wants to merge 3 commits into
mainfrom
fp/scan-precision-notes
Open

alxxjohn wants to merge 3 commits into
mainfrom
fp/scan-precision-notes

Conversation

@alxxjohn

Copy link
Copy Markdown
Contributor

Documentation only — two files under .claude/knowledge/, +20/−1. These were written alongside the work in #184 but landed on a branch that had already been merged into the integration branch, so they missed that PR.

The correction is the reason this is worth landing rather than dropping:

TestBuiltinGateCoversPatterns did not exist. architecture-boundaries.md asserted it enforced the secret scanner's gate-superset invariant — that every built-in credential pattern has its required literal in the pre-check gate. Grepping every branch found the name only in that file. The invariant was documented but unenforced, which for a security scanner means a pattern added without its gate literal would silently stop detecting. #184 added the test for real, generated from regexp/syntax rather than hand-maintained; this corrects the note and records the two generator subtleties (the parser factors (?:ghp|gho|ghu) into gh[opu], so branches hide inside character classes; and a class representative must prefer a word character or a trailing \b is defeated).

Also recorded, each verified during the audit:

  • A corpus budget miss was becoming a work skip — VisitTargetFiles continued past over-budget files, so cross-file passes were fed a truncated stream whose cut point was a scheduling race.
  • The Go AST budget counted source bytes while retaining trees, which expand 8.4–9.0×, so a 64 MiB cap admitted ~576 MiB of live AST.
  • Map iteration plus an early exit is a findings-nondeterminism bug class here; two confirmed instances, and a sweep found seven further candidates that are benign existence checks.
  • Budget exhaustion is necessary but not sufficient for nondeterminism — it depends whether the dropped files produce findings.
  • A git archive snapshot cannot reproduce exclusion or budget behaviour, since it omits the gitignored build output those mechanisms exist to prune.
  • appendCommonLineFindings runs on every line of every non-Go file, despite the name.
  • make([]T, 0, N) allocates where make([]T, 0) does not — ~1 GB per scan pass in one hot helper.

🤖 Generated with Claude Code

alxxjohn and others added 3 commits October 19, 2026 16:10
From the performance and rule-portfolio agent round:

- a corpus budget miss must never become a work skip; the old design made
  VisitTargetFiles continue past over-budget files, truncating cross-file
  passes at a scheduling-dependent point
- the Go AST budget counted source bytes while retaining trees, so the
  64 MiB cap admitted ~576 MiB of live AST
- TypeScript targets' dominant memory consumer is the node child process,
  which no corpus budget bounds
- IsSDKFacadeFile hardcodes pkg/codeguard, making two fail-level design
  rules false positives on every other repository
- five emitted performance rule IDs are absent from the catalog, so
  `explain` fails for findings the tool just printed
- codeguard does have an inline suppression directive (correcting an
  earlier note), but prefix globs parse and then silently never match

Plus measurement corrections: budget exhaustion is necessary but not
sufficient for nondeterminism, git archive snapshots cannot reproduce
exclusion or budget behaviour, and cross-branch A/B needs a shared base.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two confirmed instances (clone candidate selection, data-clump selection)
where iterating a Go map and then breaking at a cap or returning the first
match made findings depend on scheduling. Records the shape to look for and
notes that a sweep found seven further candidates, all benign existence
checks.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ings

TestBuiltinGateCoversPatterns was documented here as enforcing the secret
scanner's gate-superset invariant, but it did not exist anywhere in the tree
- the only occurrence of the name was this file. It exists now, generated
from regexp/syntax rather than hand-maintained, along with the equivalent
for the new per-line gates.

Also records that appendCommonLineFindings runs on every non-Go line despite
its name, that builtinGatePasses has a latent non-ASCII false negative the
newer gates avoid, that the SDK facade exemption is asymmetric by rule on
purpose, and that make([]T, 0, N) allocates where make([]T, 0) does not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant