2 Commits

Author SHA1 Message Date
Vijay Janapa Reddi
be58ac3eac Avoid false math percent warnings across spans 2026-06-17 22:27:29 -04:00
Vijay Janapa Reddi
daf744bb73 feat(audit): wave 7 phase 1 — release-gate defect catalog (8 new scanners)
Adds eight new audit-check modules covering the defect classes flagged
during the prior copyedit pass for the release gate. Each scanner
follows the canonical `check(file_path, text, scope, start_counter)`
shape and emits `Issue` objects compatible with the audit-ledger and
accept-list pipeline.

Defect-class coverage (A-H per the pre-Wave-6 mapping):

- A. **bare_attribution** — detects `Author et al. YEAR` / `Author and
     Author (YEAR)` / `Surname (YEAR)` style hand-typed attributions
     without an adjacent `[@cite]`. Six regex patterns; suppresses
     well-known FP classes (footnote bold heads, product-year tags,
     paths with `[@cite]` on the same or adjacent line). 0 hits at
     HEAD (Waves 4+6 fixed the originals); serves as regression guard.

- B. **duplicate_citation** — detects `[@key]` cited 3+ times within a
     50-line sliding window. Confidence=low (advisory). Skips footnote-
     definition bodies (re-citation is normal). 3 genuine over-citation
     candidates surfaced at HEAD (`tschand2025`, `kairouz2021`,
     `dixit2021silent` — each cited inline in body prose + nearby
     `Source: [@key]` fig-cap).

- C. **math_notation_render** — five patterns for math rendering bugs:
     adjacent math spans (`$\sim$$15%$`), literal `100s W` plurals,
     missing `\mu` in unit prefixes, bare `\times` without surrounding
     space, bare `%` inside math. 12 hits at HEAD — mostly `\times`
     spacing in vol1/model_serving + vol1/training Python display math.

- D. **unresolved_xref** — cross-file source-level check that every
     `@sec-X`, `@fig-X`, `@tbl-X`, `@eq-X`, `@lst-X` reference resolves
     to a defined ID. Both per-file `check()` and corpus-wide
     `scan_corpus(root)` entrypoints. 0 hits at HEAD (binder check refs
     baseline is clean); the source-level scanner closes the gap by
     emitting in the unified ledger format for the release-gate.

- E. **longtable_continuity** — detects pipe tables with 25+ rows OR
     8+ columns OR `{tbl-colwidths=...}` paired with 20+ dense rows.
     1 candidate at HEAD (`vol1/backmatter/appendix_assumptions:623`,
     a 23-row Unit Definitions table). Optional `verify_rendered_pdf`
     stub documented for future render-output wiring.

- F. **sec_slug_placement** — detects `{#sec-...}`, `{#fig-...}`,
     `{#tbl-...}`, `{#eq-...}`, `{#lst-...}` IDs at end-of-paragraph
     on a non-heading/non-caption/non-blockquote line (Quarto parse
     failure mode). 0 hits at HEAD; earlier audit waves already cleaned
     this defect class.

- G. **footnote_numbering** — per-file integrity check: missing defs,
     orphan defs, duplicate defs, plus a NEW category `footnote-numeric-id`
     that flags bare `[^1]` / `[^2]` style refs (signal of unconverted
     draft footnotes — book uses descriptive names everywhere). 0 hits
     at HEAD; sits as regression guard.

- H. **layout_proxies** — source-level proxies for layout defects.
     Four categories: `orphan-heading` (heading with 1-2 lines of body
     before next heading), `figure-without-caption`, `runt-callout`,
     `empty-section`. 289 orphan-heading + 8 empty-section hits at
     HEAD — most are advisory; the design-doc docstring at top of the
     file specifies the future render-output Scanner H+ (pdfplumber
     bbox inspection for true page-level orphans, HTML figcaption
     verification, cross-page table fragment detection).

Registry wire-up (`book/tools/audit/scan.py`):
- All 8 categories added to `CHECK_REGISTRY` under a "Wave 7" comment.
- Audit scan post-commit: total 879 issues, 15 accepted, 551 deferred
  (notation-consistency parked), 313 open from new scanners (mostly
  the 289 orphan-heading advisories).

Wave 7 Phase 1 of release-prep tooling. Phase 2 wires `binder check
release` as a CLI entrypoint that runs these eight scanners against
both rendered output and source, and wires it into `validate-dev` CI.
2026-05-17 22:27:37 -04:00