crashappsec / crashappsec/react-registry
Codebase audit (improve, 2026-06-11): 10 vetted findings + direction options
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Context
This is the output of an advisor-style codebase audit (the [shadcn/improve](https://github.com/shadcn/improve) skill) run on 2026-06-11 against commit `ec4448c` (branch `feat/brand-tokens-consumption`). All nine audit categories were covered via parallel read-only agents, and **every finding below was hand-verified against the cited code** before making this list — 9 of 20 raw findings were rejected as false positives or by-design (ledger at the bottom).
Detailed, self-contained executor plans for every item exist in a `plans/` directory generated by the same session (one file per finding, with drift checks, verification commands, scope boundaries, and STOP conditions). They are not yet committed; this issue is the durable summary for consideration later.
Verification baseline at audit time: `npm run lint` and `npx tsc -b` both exit 0; gitleaks/vitest/a11y/visual CI gates green.
## Vetted findings (by leverage)
| # | Finding | Category | Impact | Effort | Risk |
|---|---------|----------|--------|--------|------|
| 1 | **CI never typechecks or lints.** `ci.yml` (48 lines) runs gitleaks, registry build, staleness gate, vitest — no `tsc`, no `eslint` in any workflow. The registry ships raw source, so a type error merged here breaks *consumer* builds while our CI stays green | Tests/CI | High | S | LOW |
| 2 | **Build-critical scripts have zero tests.** `scripts/build-theme-tokens.mjs` and `scripts/version-registry.mjs` are the product pipeline (token canon + versioned paths) and are untested | Tests | High | M | LOW |
| 3 | **Registry output barely validated.** `src/test/registry-build.test.ts` checks `theme.json` only — 1 of ~69 items. An item dropped from the build is a silent consumer 404 | Tests | High | S | LOW |
| 4 | **Reusable refresh workflow needs supply-chain hardening.** `registry-refresh.yml` runs unpinned `npx shadcn@latest` in consumer CI (write-token checkouts), actions are tag-pinned not SHA-pinned, `items` input unvalidated. Note: not a live injection — env-var indirection and quoting hold today; this is defense-in-depth for the consumer fleet | Security | Med-High | S | LOW |
| 5 | **No CLAUDE.md/AGENTS.md and no one-command verify.** Contributors/agents re-derive the token pipeline and the 4-command verification sequence every session | DX | Med | S | LOW |
| 6 | **Index-as-key in all 3 blocks.** `service-table.tsx:68`, `service-detail-header.tsx:87`, `stat-card-row.tsx:60` — reordered/filtered lists mis-attach DOM state in consumer apps. Natural keys (`name`/`label`) exist; no API change needed | Correctness | Med | S | LOW |
| 7 | **`next-themes` is a dead dependency.** `package.json` lists it; nothing imports it (the toaster deliberately reads the document root instead) | Debt | Low | S | LOW |
| 8 | **Brand-tokens pin has no refresh automation.** Pinned to `brand-visual#v1.0.1` with no bump process — consumers of this registry get auto-refresh PRs, but the registry's own canon updates only when a human remembers | Deps | Med | S | LOW |
| 9 | **Storybook built 2-3x per event; Playwright browsers re-downloaded every run.** No `actions/cache` anywhere. Verdict after investigation: cache Playwright (cheap win); skip cross-workflow Storybook artifact sharing (racy, complex, ~2-4 min saved) | Perf/CI | Low-Med | S | LOW |
| 10 | **26 individual `@radix-ui/react-*` packages lag shadcn's unified `radix-ui` migration.** Affects this repo and every registry item's consumer-facing `dependencies` array. Mechanical but wide; should land only after the test net (#1-#3) | Migration | Med | L | MED |
Recommended execution order: 1 → 5 → (2, 3, 4 in any order) → 6/7/8/9 → 10.
## Direction options (maintainer's call)
- **Package the adherence lint as an installable registry item.** `.adherence.oxlintrc.json` is called "the canonical brand checklist" yet consumers hand-copy it, and CONTRIBUTING already documents its portability problems. `npx shadcn add @crashoverride/adherence-lint` + the existing refresh workflow would version and distribute it.
- **Consumer adoption kit for Chalk / Ocular / con4m / COMPASS.** The refresh workflow exists and README names these consumers, but nothing ships them turnkey onboarding. A `docs/adoption/` kit (checklist + ready-to-commit caller workflow) turns infrastructure into fleet coverage.
- **Token-bump visual impact report.** The visual suite knows exactly which stories a token bump restyles; refresh PRs say only "upstream published changes". Bridging them ("this bump visually changes 12 stories") makes silent restyles reviewable.
- **Console onboarding blocks** — deliberately *not* recommended yet: README explicitly scopes Console out; pre-building console blocks front-runs that strategic decision.
## Considered and rejected (do not re-audit)
- Toaster `useCallback` "bug" — false positive (`[]` deps = stable identity, cleanup correct)
- "Command injection" in refresh inputs — mitigated today; residue became finding #4
- "Heavy deps (recharts etc.) hit all consumers" — wrong model; per-item `registry.json` deps drive consumer installs
- Playwright sharding — suite too small for baseline-merge complexity
- README "60+ components" vs 64 — accurate as written
- `sidebar.tsx` 779-LOC refactor — vendored stock shadcn; splitting diverges from upstream
- `debug-storybook.log` hygiene — already ignored (`*storybook.log`)
- uuid moderate vulns via `@storybook/test-runner` chain — devDep-only, fix would downgrade test-runner; revisit upstream
- Shallow smoke tests — by-design per CONTRIBUTING; block tests verified meaningful
- Prettier/pre-commit hooks — CI is the gate; repo-wide reformat churn not worth it now
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Contributor guide
Assessment
This issue has not been assessed yet.