Skip to content

feat(context): AI-readiness gate, doc-truth rules, and 30% faster scans (re-land #44)#46

Merged
alxxjohn merged 15 commits into
mainfrom
feat/ai-ready-and-tuning-mainline
Jul 16, 2026
Merged

feat(context): AI-readiness gate, doc-truth rules, and 30% faster scans (re-land #44)#46
alxxjohn merged 15 commits into
mainfrom
feat/ai-ready-and-tuning-mainline

Conversation

@alxxjohn

Copy link
Copy Markdown
Contributor

Summary

Re-lands #44 against main. #44 was stacked on feat/performance-category and its merge landed on that feature branch instead of main, so none of its changes made it into main or the 1.0.0 release PR (#45). This PR carries exactly that delta (63 files; full 774-test suite green; content identical to the reviewed #44 state).

See #44 for the full description and review discussion. Highlights:

  • ~30% faster cold scans / ~24% warm — corpus-routed quality AI checks, zero-allocation rolling clone hash, behavior proven byte-identical
  • Enforceable AI-readiness scorerepo_legibility warn/fail thresholds, history + report -legibility-history, honest component calibration (dogfooded at warn-threshold 85)
  • Doc-truth rulescontext.undocumented-commands, context.oversized-agent-doc, context.doc-link-rot, README drift parity; dogfooding fixed 17 real defects in our own docs

Merging this will update release PR #45 so 1.0.0 includes these changes — merge this before accepting the release PR.

🤖 Generated with Claude Code

alxxjohn and others added 15 commits July 16, 2026 12:22
Adds three Agent Context rules: context.undocumented-commands (high-signal
Makefile targets / npm scripts no agent doc or README mentions),
context.oversized-agent-doc (agent instruction files over the
max_agent_doc_lines budget, default 600), and context.doc-link-rot (markdown
links in agent docs and the root README that resolve to nothing; external
URLs and anchors exempt, no network I/O). Broadens context.readme-drift to
the same full prose extraction agent docs get, and moves markdown-link
checking out of the drift extractor so a broken link is reported once.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The broadened readme-drift and new doc-link-rot rules flagged our own README:
14 machine-absolute doc links and two search-path candidates written as
repo paths that do not exist. Repoint the links relatively, reword the
config-discovery sentence, and document make fmt in CLAUDE.md so the
undocumented-commands rule passes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e components

- context_rules.legibility_warn_threshold / legibility_fail_threshold gate
  the repo_legibility score via a new context.legibility-threshold rule
  (fires when the score falls BELOW the threshold, since legibility is
  good-high; 0 disables, fail must be <= warn)
- agent_docs component now gated on substance (25 x min(non-blank,10)/10)
  and reduced -2 per unresolvable agent-doc reference (capped at 10)
- doc_accuracy penalty is proportional: round(20 x broken/total refs)
  instead of a flat -4 that saturated at 5 references
- context_economy ramps linearly to zero at 25% oversized instead of 10%
- navigability ignores conventional basenames (index.ts, __init__.py,
  mod.rs, main.go, ...) for both the score and context.ambiguous-symbol
  findings; context_rules.ambiguous_symbol_ignore replaces the default set

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- trend persisted per target at <cache>.legibility-history.<ext> following
  the slop/perf history pattern; artifacts annotated with previous_score
  and delta on subsequent scans
- context_rules.legibility_history toggles persistence (nil = enabled),
  legibility_history_limit caps retained entries (default 100)
- codeguard report -legibility-history prints the recorded trend,
  mirroring -slop-history and -perf-history

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- threshold warn/fail/disabled/pass paths plus config validation ordering
- history persistence, delta annotation, and toggle-off behavior
- calibration proofs: substance-gated agent_docs, proportional
  doc_accuracy, softened context_economy curve, conventional-basename
  ignore list and its replace semantics
- report -legibility-history CLI trend, empty-history, and mode-flag
  exclusivity
- updated artifact expectations to the recalibrated formulas

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rmulas

- rewrite the Agent Context section: new config keys, score-below-threshold
  semantics, history + report flag, recalibrated component formulas, and
  the conventional-basename ignore list with replace semantics
- dogfood: warn threshold 85 in the self-scan config (repo scores 100) and
  exclude the legibility history file from scanning

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The quality AI checks bypassed the per-scan file corpus: they re-walked
the target and re-read the full source corpus 4-5 times per scan
(dominant test framework, error style, naming convention, plus the
per-file pass), and re-parsed every Go file that the corpus had already
parsed. This made the quality section the scan's wall-clock critical
path, with syscalls at ~41% of warm CPU.

- add ListTargetFiles/ReadTargetFile hooks to checks/support.Context,
  wired to the corpus (mirroring VisitTargetFiles); nil-safe fallbacks
  for unit-test contexts live in quality_ai_corpus.go
- route every walk-enumerated AI-check read (Go/Python/script targets,
  workspace package.json discovery) through the hooks; fixed-filename
  reads (go.mod, root package.json) stay direct to preserve their
  uncapped-read semantics
- replace the redundant parser.ParseFile(..., 0) with the shared
  ParseComments corpus parse (support.ParseGoSource); drop the fn.Doc
  "go:" directive exemption that the mode-0 parse had kept latent so
  findings stay byte-identical (see NOTE in quality_ai_dead_code.go)
- collapse the three Go repo-dominant style signals into one corpus
  pass (goRepoStyleProfile); each signal is an independent per-file
  sum, so the fold is behavior-identical

Differential check: old vs new binaries scanning an identical pristine
tree produce byte-identical JSON findings (modulo generated_at).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The clone detector re-hashed every threshold-token window from scratch,
converting each token to []byte twice per window (~226 MB of
allocations per scan), and lowercased every token at tokenize time
(~175 MB more).

- cloneToken now stores the original-case source slice (no per-token
  ToLower copy; tokens are ASCII-only by the token regex) plus a
  FNV-1a hash of the ASCII-lowercased text computed once at tokenize
  time
- window grouping uses a rolling polynomial hash over the per-token
  hashes: O(1) per slide instead of O(threshold) bytes hashed, and
  zero allocations
- token equality folds ASCII case with a hash short-circuit, which is
  exactly the historical lowercased-value comparison

The hash function is not behavior-bearing: every candidate bucket is
verified token-by-token in sharedCloneLength, so equal windows always
group and colliding unequal windows are discarded. The new differential
test pins findings captured verbatim from the pre-rewrite algorithm on
a fixture covering three-way clones, case normalization,
overlapping-window merging, and below-threshold duplicates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CountLines allocated a string copy of the file plus a split slice on
every call (~17.6 MB per scan). Count newline bytes in place instead,
preserving the exact legacy semantics (all trailing newlines trimmed,
empty input is one line). The new unit test cross-checks every edge
case against the legacy strings-based formula.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Note in the architecture doc that the per-scan file corpus memoizes
walks, reads, and parses and that the quality AI checks now share it;
record the corpus read-cap semantics, the latent fn.Doc dead-code
exemption, and the clone-hash verification invariant in the knowledge
base.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… rules (#44)

## Summary

Stacked on #41. Three tracks, built by parallel agents and integrated
sequentially: codeguard's own scan gets measurably faster, the
`repo_legibility` score becomes an enforceable and trended
**AI-readiness gate**, and four new rules keep a repo's docs truthful
for both AI agents and humans.

## 1. Scan performance (behavior-preserving, measured)

| | before | after |
|---|---|---|
| Cold scan (this repo) | ~0.69 s | **~0.49 s** (−30%) |
| Warm scan | ~0.60 s | **~0.46 s** (−24%) |

- Quality's AI checks previously bypassed the shared scan corpus — 4–5
redundant full-corpus reads per scan (syscalls were 41% of warm CPU).
New `ListTargetFiles`/`ReadTargetFile` corpus hooks route them all
through one cached read; the redundant mode-0 re-parse now reuses the
shared ParseComments AST.
- Clone detector: tokens hashed once at tokenize time + O(1) rolling
window hash, zero per-window allocations (was ~226 MB churn/scan). Hash
is not behavior-bearing — every bucket pairing is still verified
token-by-token.
- One-pass dominant-style profile (test framework + error style +
naming) replaces three corpus sweeps; allocation-free `CountLines`.
- **Proof of identical behavior**: old vs new binaries produce
byte-identical findings JSON on the same tree; a differential clone test
captures the OLD algorithm's output verbatim and asserts the new one
reproduces it. One semantic trap was found and neutralized: a `fn.Doc`
directive exemption that never fired under the old parse mode would have
silently activated — removed with a NOTE.

## 2. Enforceable AI-readiness score

`repo_legibility` (0–100, explainable components) previously could not
gate a build or show a trend. Now:
- `context_rules.legibility_warn_threshold` /
`legibility_fail_threshold` — fires `context.legibility-threshold` when
the score falls **below** the floor (legibility is good-high; semantics
documented), message carries the component breakdown.
- History at `<cache>.legibility-history.<ext>` with
previous_score/delta, plus `codeguard report -legibility-history`.
- **Calibration fixes**: an empty CLAUDE.md no longer scores the full 25
agent-docs points (substance-gated + drift-penalized); context-economy
ramps linearly to zero at 25% oversized (was a cliff at 10%);
doc-accuracy penalty is proportional (broken/total) instead of
saturating at 5 refs; conventional basenames (`index.ts`, `__init__.py`,
`mod.rs`, `types.go`, …) no longer count as ambiguous — configurable via
`ambiguous_symbol_ignore`.
- Dogfooded: this repo runs with `legibility_warn_threshold: 85` as a
live gate.

## 3. Doc-truth rules (Agent Context)

| Rule | What it catches |
|---|---|
| `context.undocumented-commands` | high-signal Makefile targets / npm
scripts (build, test, lint, fmt, …) that no agent doc or README mentions
|
| `context.oversized-agent-doc` | agent docs larger than
`max_agent_doc_lines` (600) — they consume the context budget they exist
to save |
| `context.doc-link-rot` | markdown links in agent docs/README pointing
at nonexistent files (relative + repo-absolute; no network I/O) |
| README drift parity | `context.readme-drift` now gets the same full
prose extraction as agent docs, not just shell fences |

**Dogfooding found 17 real defects in our own docs** — README links
baked to absolute `/Users/...` machine paths, references to nonexistent
config filenames, and `make fmt` documented nowhere. All fixed, none
waived.

## Verification
774 tests / 9 packages, go vet, gofmt, golangci-lint 0 issues,
cache-cleared self-scan 0 fail with the legibility gate active. Docs
fully updated: Agent Context section rewritten (new rules, recalibrated
formulas, threshold/history semantics), architecture doc gained a corpus
paragraph, and three new gotchas captured in .claude/knowledge/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Re-lands PR #44, which was stacked on feat/performance-category and merged
into that branch instead of main.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@alxxjohn
alxxjohn merged commit 75b3f02 into main Jul 16, 2026
14 checks passed
@alxxjohn
alxxjohn deleted the feat/ai-ready-and-tuning-mainline branch July 16, 2026 17:00
alxxjohn added a commit that referenced this pull request Jul 16, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.0.0](v0.8.3...v1.0.0)
(2026-07-16)


### ⚠ BREAKING CHANGES

* promote performance rules to their own opt-in check section
([#41](#41))
* the performance rules' ids renamed from quality.* to performance.*
(quality.n-plus-one-query -> performance.n-plus-one-query,
quality.go.alloc-in-loop -> performance.go.alloc-in-loop,
quality.sync-io-in-request-path -> performance.sync-io-in-request-path,
quality.unbounded-goroutines-in-loop ->
performance.unbounded-goroutines-in-loop, plus the typescript/javascript
mirrors and quality.python.sync-io-in-async). Their detect_* toggles
moved from quality_rules to performance_rules, and the section is
opt-in: set checks.performance: true to keep running these rules, and
update any waivers or baselines that reference the old ids.

### Features

* 30% faster scans, enforceable AI-readiness score, and doc-truth rules
([#44](#44))
([718dd08](718dd08))
* **context:** add AI-and-human-readiness rules and broaden README drift
([6caac9a](6caac9a))
* **context:** AI-readiness gate, doc-truth rules, and 30% faster scans
([1f4f130](1f4f130))
* **context:** AI-readiness gate, doc-truth rules, and 30% faster scans
(re-land [#44](#44))
([#46](#46))
([75b3f02](75b3f02))
* **context:** enforceable legibility threshold and recalibrated score
components
([604dd52](604dd52))
* **context:** persist repo_legibility score history with report flag
([e54f643](e54f643))
* **parsers:** wire the Python tree-sitter grammar and upgrade Python
N+1 detection
([07a0b24](07a0b24))
* **performance:** add AI-assisted semantic performance lens
([eabd7fe](eabd7fe))
* **performance:** add diff-only loop-nesting complexity regression rule
([2e8bcef](2e8bcef))
* **performance:** add framework-aware rules for Django, SQLAlchemy,
React, and Express
([b49ce7b](b49ce7b))
* **performance:** add loop-hygiene, concurrency, and memory-pressure
rules
([54bfca9](54bfca9))
* **performance:** add measured budgets and benchmark regression gates
([2c5e4ba](2c5e4ba))
* **performance:** publish a performance_score artifact with history and
report flag
([5c5a738](5c5a738))
* promote performance rules to their own opt-in check section
([ede8b37](ede8b37))
* promote performance rules to their own opt-in check section
([#41](#41))
([81a575b](81a575b))
* suggest enabling the performance section in scan output
([81d9d46](81d9d46))


### Performance Improvements

* **quality:** hash clone tokens once and roll the window hash
([bbf5b69](bbf5b69))
* **quality:** route AI check reads through the shared scan corpus
([b271cfb](b271cfb))
* **runner:** count lines by scanning bytes instead of allocating
([17a4593](17a4593))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
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