feat(check): buildNotFoundOutput adoption + bare-name reclass (0.19.1) — CA-034 round 2#123
feat(check): buildNotFoundOutput adoption + bare-name reclass (0.19.1) — CA-034 round 2#123thebenignhacker wants to merge 1 commit intomainfrom
Conversation
…e-name reclass (CA-034 round 2) Three `check --json` not-found emit sites now go through `buildNotFoundOutput` from `@opena2a/check-core`: - npm git-style translated error (src/cli.ts ~9131) - PyPI 404 (src/cli.ts ~8609) - GitHub 404 / code-128 (src/cli.ts ~8526) Bare names on npm 404 no longer fall through to the skill-identifier resolver. Previously `hackmyagent check totally-nonexistent-pkg-xyz789` emitted `Invalid skill identifier` on stderr with no JSON; it now emits the canonical NotFoundOutput shape and exits 1. Scoped names (`@scope/name`) still attempt skill fallback on npm 404. Closes the data-layer half of F2 (not-found shape) and F3 (git-style miss) parity fixtures. F4 (skill fallback) path is unchanged. Release 0.19.1.
There was a problem hiding this comment.
Claude Code Review
VERDICT: APPROVE
SUMMARY: This PR adopts buildNotFoundOutput from @opena2a/check-core across three not-found code paths (npm git-style miss, PyPI 404, GitHub 404) and reclassifies bare npm misses to emit the canonical NotFoundOutput shape instead of falling through to the skill resolver. All changes are data-layer transformations that delegate to a shared, already-reviewed primitive. The new test is CI-skipped (network dependency) but provides local regression coverage. No security, correctness, or breaking interface issues introduced.
Verification performed:
- Checked all
buildNotFoundOutputcall sites for user-controlled input → all arguments are either constant strings or validated package names from prior classifier stages - Verified bare-name reclassifier logic: scoped names still fall through to skill resolver (line 376–378), bare names exit early with
NotFoundOutput(lines 365–377) - Confirmed
writeJsonStdoutis a safe wrapper (not shell-interpolated) - No command injection vectors: no
child_processcalls modified, test usesspawnSyncwith array arguments (not shell-interpolated) - No prototype pollution: plain object literals passed to
buildNotFoundOutput, no dynamic key assignment from user input - Exit code behavior correct: bare-name miss exits 1 (line 387), scoped-name miss preserves existing flow
Reviewed 5 files changed (8811 bytes)
ML-DSA-44 benchmark (ubuntu-latest, c6i.xlarge-class)Budget (AIComply D17): sign p99 < 2.5ms, verify p99 < 1.5ms. |
Summary
Closes the data-layer half of F2 (not-found shape) and F3 (git-style miss) parity
fixtures in opena2a-parity.
check --jsonnot-found emit sites now go throughbuildNotFoundOutputfrom
@opena2a/check-core— npm git-style translated error, PyPI 404, GitHub 404.hackmyagent check totally-nonexistent-pkg-xyz789previously emittedInvalid skill identifieron stderr with no JSON; it now emits the canonicalNotFoundOutput shape and exits 1. Scoped names (
@scope/name) still attempt skillfallback on npm 404.
__tests__/checker/check-not-found-json.test.tsregression test (CI-skipped —needs network + built
dist/cli.js; local dev exercises the real shape).Parent brief
briefs/check-core-adoption-round2-not-found.md(PR A).Test plan
npm run build— cleannpx vitest run __tests__/checker/— 66/66 pass (1 new)npx vitest run— 1712 pass / 16 skipped / 10 todonode dist/cli.js check totally-nonexistent-pkg-xyz789 --json --ci→{name, found:false, error, ecosystem:"npm"}node dist/cli.js check anthropic/code-review --json --ci→{name, found:false, error, errorHint, ecosystem:"github"}node dist/cli.js check pip:totally-nonexistent-xyz789 --json --ci→{name, found:false, error, ecosystem:"pypi"}node dist/cli.js check @totally-nonexistent/pkg-xyz789 --json --ci --offline→ still routes to skill resolverhackmyagent secure .→ 98/100 (pre-existing LOW on CLAUDE.md size, unchanged from main)feedback_sibling_symlink_lockfile_breaks_ci— all@opena2a/*entries resolved toregistry.npmjs.orgtarballs, no"link": true.Publish timing
v0.19.1tag created locally only. Publish budget today (2026-04-22) is 3/3 —tag push + TP workflow run scheduled for tomorrow.
Follow-ups