Skip to content

fix: security, correctness & robustness sweep across lib/commands#87

Merged
NagyVikt merged 1 commit into
mainfrom
fix/cue-security-robustness-sweep
Jun 29, 2026
Merged

fix: security, correctness & robustness sweep across lib/commands#87
NagyVikt merged 1 commit into
mainfrom
fix/cue-security-robustness-sweep

Conversation

@NagyVikt

Copy link
Copy Markdown
Contributor

Summary

A bug-review sweep of src/lib and src/commands surfaced via 4 read-only audit agents, then verified individually against current main and covered by typecheck + tests. Every change is a defensive guard or a correctness fix with no behaviour change for legitimate inputs.

13 files, +131/−28. Independent review confirmed the 6 security/correctness fixes correct with no regressions.

Security

  • pr-posterwriteFilesToWorktree now refuses paths that escape the worktree (../../.bashrc); the root + sep boundary also blocks the ${root}-evil sibling-prefix trick.
  • scan-plugins — rejects an absolute or ..-containing manifest.skills from an untrusted plugin.json (was resolve(dir, manifest.skills) → arbitrary-dir scan).
  • credentials-sync — OAuth creds written atomically (tmp + rename) so a crash/concurrent reader never sees a half-written credentials file.
  • cwd-resolver — malformed repo-defaults.json is caught instead of throwing out of resolveProfileForCwd.

Correctness

  • skill-dependenciesparseExplicitDeps now parses the YAML block-sequence requires_mcps: form, not only inline arrays. Block-form deps were silently dropped → MCP-dependency starvation. Exported + 7 unit tests.
  • skill-linter — R008 slugifies anchor refs the same way headings are slugified, eliminating false-positive broken-link errors on headings with &/(/).

Robustness

  • runtime-materializersyncMcpsIntoClaudeJson no longer stub-rewrites .claude.json on a transient read error (EMFILE/EACCES); it rewrites only on ENOENT / parse error, preserving session/auth state.
  • telemetry-ingest, shared-profiles — atomic tmp+rename writes (the latter's doc comment already claimed atomicity it didn't have).
  • shared-profiles — profile fetch bounded by a 10s AbortSignal.timeout.
  • statushomedir() fallback instead of the literal "~" (which join never expands).
  • skills, init — handle non-zero subprocess exits instead of crashing the wizard / treating a failed install as success.

Test plan

  • bun run typecheck — clean
  • bun test on all touched suites — 226/226 pass, incl. 7 new skill-dependencies parser tests
  • Independent read-only code review of the security/correctness changes — all CORRECT, no regressions
  • CI green on this PR

Notes

Each fix was re-verified against current main (the audit originally ran on a stale branch). One audit finding — a pair-suggestions.ts typecheck break — was already fixed on main and is intentionally excluded. Three other audit findings were judged false-positives (inheritance depth-vs-width, an intentional cluster sort, a cosmetic regex) and intentionally not changed.

🤖 Generated with Claude Code

Bug-review sweep findings, each verified against current main and covered
by typecheck + tests. No behaviour change for legitimate inputs.

Security:
- pr-poster: guard writeFilesToWorktree against path traversal (../ escape)
- scan-plugins: reject absolute / ".." plugin manifest skills paths
- credentials-sync: atomic tmp+rename write of OAuth credentials
- cwd-resolver: try/catch malformed repo-defaults.json instead of throwing

Correctness:
- skill-dependencies: parse YAML block-sequence requires_mcps (not just inline
  arrays) so block-form deps are no longer silently dropped (+ unit tests)
- skill-linter: slugify R008 anchor refs to match heading slugs (no false
  positives on headings with & ( ) etc.)

Robustness:
- runtime-materializer: don't stub-rewrite .claude.json on a transient read
  error (EMFILE/EACCES) — only on ENOENT / parse error — to preserve auth state
- telemetry-ingest, shared-profiles: atomic tmp+rename writes
- shared-profiles: bound profile fetch with a 10s AbortSignal timeout
- status: use homedir() fallback instead of literal "~"
- skills, init: handle non-zero subprocess exits instead of crashing/ignoring
@NagyVikt NagyVikt merged commit f86beeb into main Jun 29, 2026
4 checks passed
@NagyVikt NagyVikt deleted the fix/cue-security-robustness-sweep branch June 29, 2026 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant