Quality, budgets and evidence
Issues #31–#32. npm run check executes DOM and native suites with test counts. Native module mocks demonstrate roles/state/callback/lifecycle contracts; real packed Expo/Metro consumers demonstrate platform resolution. Neither is physical output or assistive-technology certification.
Gates inspect actual generated package exports, platform imports, tokens/cue hashes, scoped anti-drift exceptions, packed consumer installs, every copyable example, SSR/hydration/StrictMode, docs static route/base paths, visual/browser states and measured gzip/assets. Negative tests deliberately introduce invalid exports, stale token output, budget regression, cross-platform imports and copied/obsolete tokens to prove failure paths.
Budgets are regression limits from the initial candidate measurements, not claims of production savings:
| Metric | Measured initial | Limit | Reason |
|---|---|---|---|
| Individual DOM Button gzip (React external) | 706 B | 850 B | ~20% API/behavior fix headroom, overlay/audio/chart excluded |
| Individual AmountInput gzip | 325 B | 400 B | Small labelled primitive, ~23% headroom |
| Native Switch gzip (React/RN external) | 1,383 B; 1,870 B after #67 | 2,200 B | Raised for #67: the shared Text now carries the font-scale cap and Korean/Chinese script tracking, Switch the token-role track and the Android thumb token. ~18% headroom; verifies no Slider/SVG/overlay/feedback imports |
| Platform-neutral feedback contract gzip | 962 B | 1,200 B | ~25% headroom without device engines |
| Docs JS gzip, all lazy chunks | 204,877 B | 240,000 B | ~17% headroom; includes chart/code examples, not initial-load-only |
| Docs CSS | 124,111 B (with resizable drawer and per-place number motion) | 125,000 B | Tight headroom against the current Next CSS output; the gesture example remains lazy-loaded and Vaul injects its own runtime CSS rather than adding a second bundled stylesheet |
| Sans + Mono assets | 592,796 B | 600,000 B | Pins two approved faces; new script/face requires explicit review |
Native fixture faces from @bloxwap/hig/native-fonts (Sans 400/600, Mono 400) | 1,278,880 B | 1,400,000 B | Only the three registered faces; optional CJK and other weights stay unloaded. Every generated face hash is checked |
| Font binaries in web/shared tarballs (tokens, contracts, react, feedback, native) | 0 files | 0 files | Native faces ship only in @bloxwap/hig/native-fonts (#64); release:dry-run fails otherwise and records packedSizes |
| Native four-cue WAV assets | 103,618 B | 110,000 B | ~6% headroom; no full engine/catalog assets |
The actual build report is evidence/quality-report.json. The committed copy, the release report and the browser acceptance files were copied from a Linux CI run (evidence/ci-refresh.json, #98), not regenerated locally. GitHub Actions now runs on self-hosted macOS ARM64 Mac minis; see CI runners. Failed quality and browser jobs upload fresh copies for review; green runs skip the upload. Bundles use explicit external React/RN peers, so figures measure HIG runtime contribution, not total installed/Metro app size. Production app/Pro/native before/after deltas require owning-repository builds and reviewed baselines; do not invent a percentage improvement. Export/dependency graph reports and packed tests enforce separation, while owning migrations must measure complete apps with equal data/toolchain.
Exceptions require path/rule, owner, reason and expiry. Approved brand geometry is exempt from literal-palette detection until review; unrelated primitive/palette copies fail. New repositories should run scoped gates on migrated surfaces and keep dated residuals rather than blanket exemptions.
Physical release review remains pending: iPhone Safari, Android Chrome, native iOS and Android, VoiceOver/TalkBack, large text/RTL, color/font fidelity, actual SFX/haptic output/latency/settings/interruption/background behavior. Coordinate upstream haptic#9. Release artifacts cannot change those “pending” rows into passes.
Versioned visual regressions
The catalog browser gate captures and runs axe on every shipped state. Button, Field and Input additionally compare eight versioned mobile/reduced-motion screenshots in tests/visual-baselines/<process.platform>/ (linux or darwin), and Slider compares two keyboard-focused captures (comfortable and compact density). Geometry changes fail; pixel changes above 2% fail after a 24-channel-value antialias tolerance on every OS. tests/visual.test.ts deliberately changes geometry and pixels to prove the gate fails. Baselines record current candidate rendering on that OS, not approved product parity or native-device fidelity. Do not reuse another OS image or raise the thresholds to hide a runner difference. Review an intentional change using CI captures, then run HIG_UPDATE_VISUALS=1 node scripts/catalog-browser-smoke.mjs against the production docs preview and commit the reviewed baseline images for that platform.