CodeVetter · Repo Unpack · Risk map
nextlevelbuilder/ui-ux-pro-max-skill
The codebase is defensively written (closed decision-rule grammar, slug sanitization, atomic writes, calibrated abstention), but risk concentrates in (a) triple-mirrored data that must stay byte-identical, (b) dead/legacy install paths in the CLI, (c) a hand-rolled CSV parser in the gallery, (d) doc drift, and (e) CI-only network surfaces (GitHub API token, Google Fonts key, npm install of pinned packages). The symlinked gallery data file also contradicts the repo's stated no-symlink rule.
- Triple-mirror consistency is the biggest blast radius: a CSV edited in src/ but not re-synced silently ships stale data through both the npm CLI and the Claude plugin; mitigation is sync-assets.mjs --check in CI, but local edits still rely on the human running `npm run sync:assets`.
- Dead code: init.ts keeps a legacy ZIP-install path (tryGitHubInstall -> installFromZip -> extractZip shelling out to `unzip`/PowerShell Expand-Archive) gated on options.legacy, but index.ts never registers a --legacy flag, so the entire network-download + shell-out path is unreachable from the CLI.
- extractZip interpolates zipPath/destDir into a shell command string (`unzip -o "${zipPath}"`, powershell -Command) — a command-injection shape that is currently dead code but would be exploitable if the legacy flag were ever re-exposed. (inferred)
- update.ts shells out to npm install -g; it mitigates with execFileSync + explicit args + a semver regex gate on the tag, and shell:true only on Windows — but a compromised or malformed GitHub release feed remains the trust boundary.
- The gallery contains a second, hand-written CSV parser (parseCSVLine/splitCSVRecords) independent of Python's csv module; divergence in quoting/CRLF handling would surface only as a runtime throw ('Unterminated quoted CSV field') or misparsed styles.
- gallery/data/styles.csv is a symlink to ../../src/ui-ux-pro-max/data/styles.csv even though CLAUDE.md states the repo avoids symlinks because git-on-Windows checks them out as text pointer files — the gallery would read a path string instead of CSV on such a checkout. (inferred)
- Doc drift: CONTRIBUTING.md tells contributors to edit 'data/rules.csv' (the real file is ui-reasoning.csv) and references a .factory/ directory that does not exist at repo root; README install commands list platforms like 'antigravity' that map to an 'agent.json' template name via AI_TO_PLATFORM indirection.
- Search correctness is threshold-tuned by hand (_DOMAIN_SCORE_FLOORS like style 4.3, icons 5.8, _STACK_THRESHOLD 3.6 + coverage 1/3) and pinned by a calibration version string; a CSV content change can flip abstention behavior repo-wide, which is why the relevance fingerprint gate exists.
- The only network egress in shipped runtime code is cli/src/utils/github.ts (GitHub releases API, optional bearer token from --token/UI_PRO_MAX_GITHUB_TOKEN/GITHUB_TOKEN); refresh-catalogs.yml additionally uses GOOGLE_FONTS_API_KEY and `npm install` of pinned phosphor packages in a sandboxed weekly job.
- Persistence writes outside the repo by design (--output-dir defaults to cwd); safe_slug prevents traversal but nothing stops an agent from pointing --output-dir at an arbitrary directory — mitigated only by SKILL.md instruction text, not code. (inferred)
- bump-versions.yml auto-opens a PR editing three JSON manifests on release publish; skill/plugin manifests (2.13.0) and cli/package.json (2.5.0) are already out of step between releases, so version drift is normal rather than an error.
- Sub-skill directories (.claude/skills/{design,brand,banner-design,ui-styling,slides,design-system}) contain their own scripts/tests not covered by this report's read set; the bundled-skill CI contract treats them as shipped surface, so bugs there ship through every install. (inferred)