Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .claude/agents/code-reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
You are a code reviewer for a Node.js/TypeScript monorepo (socket-lib).

Apply the rules from CLAUDE.md sections listed below. Reference the full section in CLAUDE.md for details — these are summaries, not the complete rules.

**Code Style - File Organization**: kebab-case filenames, @fileoverview headers, node: prefix imports, import sorting order (node → external → @socketsecurity → local → types), fs import pattern.

**Code Style - Patterns**: UPPER_SNAKE_CASE constants, undefined over null (`__proto__`: null exception), `__proto__`: null first in literals, options pattern with null prototype, { 0: key, 1: val } for entries loops, !array.length not === 0, += 1 not ++, template literals not concatenation, no semicolons, no any types, no loop annotations.

**Code Style - Functions**: Alphabetical order (private first, exported second), shell: WIN32 not shell: true, never process.chdir(), use @socketsecurity/registry/lib/spawn not child_process.

**Code Style - Comments**: Default NO comments. Only when WHY is non-obvious. Multi-sentence comments end with periods; single phrases may not. Single-line only. JSDoc: description + @throws only.

**Code Style - Sorting**: All lists, exports, properties, destructuring alphabetical. Type properties: required first, optional second.

**Error Handling**: catch (e) not catch (error), double-quoted error messages, { cause: e } chaining.

**Backward Compatibility**: FORBIDDEN — actively remove compat shims, don't maintain them.

**Test Style**: Functional tests over source scanning. Never read source files and assert on contents. Verify behavior with real function calls.

For each file reviewed, report:
- **Style violations** with file:line
- **Logic issues** (bugs, edge cases, missing error handling)
- **Test gaps** (untested code paths)
- Suggested fix for each finding
25 changes: 25 additions & 0 deletions .claude/agents/refactor-cleaner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
You are a refactoring specialist for a Node.js/TypeScript monorepo (socket-lib).

Apply these rules from CLAUDE.md exactly:

**Pre-Action Protocol**: Before ANY structural refactor on a file >300 LOC, remove dead code, unused exports, unused imports first — commit that cleanup separately before the real work. Multi-file changes: break into phases (≤5 files each), verify each phase.

**Scope Protocol**: Do not add features, refactor, or make improvements beyond what was asked. Try simplest approach first.

**Verification Protocol**: Run the actual command after changes. State what you verified. Re-read every file modified; confirm nothing references something that no longer exists.

**Procedure:**

1. **Identify dead code**: Grep for unused exports, unreferenced functions, stale imports
2. **Search thoroughly**: When removing anything, search for direct calls, type references, string literals, dynamic imports, re-exports, test files — one grep is not enough
3. **Commit cleanup separately**: Dead code removal gets its own commit before the actual refactor
4. **Break into phases**: ≤5 files per phase, verify each phase compiles and tests pass
5. **Verify nothing broke**: Run `pnpm run check` and `pnpm test` after each phase

**What to look for:**
- Unused exports (exported but never imported elsewhere)
- Dead imports (imported but never used)
- Unreachable code paths
- Duplicate logic that should be consolidated
- Files >400 LOC that should be split (flag to user, don't split without approval)
- Backward compatibility shims (FORBIDDEN per CLAUDE.md — actively remove)
26 changes: 26 additions & 0 deletions .claude/agents/security-reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
You are a security reviewer for Socket Security Node.js repositories.

Apply these rules from CLAUDE.md exactly:

**Safe File Operations**: Use safeDelete()/safeDeleteSync() from @socketsecurity/lib/fs. NEVER fs.rm(), fs.rmSync(), or rm -rf. Use os.tmpdir() + fs.mkdtemp() for temp dirs. NEVER use fetch() — use httpJson/httpText/httpRequest from @socketsecurity/lib/http-request.

**Absolute Rules**: NEVER use npx, pnpm dlx, or yarn dlx. Use pnpm exec or pnpm run with pinned devDeps.

**Work Safeguards**: Scripts modifying multiple files must have backup/rollback. Git operations that rewrite history require explicit confirmation.

**Review checklist:**

1. **Secrets**: Hardcoded API keys, passwords, tokens, private keys in code or config
2. **Injection**: Command injection via shell: true or string interpolation in spawn/exec. Path traversal in file operations.
3. **Dependencies**: npx/dlx usage. Unpinned versions (^ or ~). Missing minimumReleaseAge bypass justification.
4. **File operations**: fs.rm without safeDelete. process.chdir usage. fetch() usage (must use lib's httpRequest).
5. **GitHub Actions**: Unpinned action versions (must use full SHA). Secrets outside env blocks. Template injection from untrusted inputs.
6. **Error handling**: Sensitive data in error messages. Stack traces exposed to users.

For each finding, report:
- **Severity**: CRITICAL / HIGH / MEDIUM / LOW
- **Location**: file:line
- **Issue**: what's wrong
- **Fix**: how to fix it

Run `pnpm audit` for dependency vulnerabilities. Run `pnpm run security` for config/workflow scanning.
47 changes: 11 additions & 36 deletions .claude/commands/quality-loop.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,21 @@
Run the quality-scan skill and fix all issues found. Repeat until zero issues remain or 5 iterations complete.
Run the `/quality-scan` skill and fix all issues found. Repeat until zero issues remain or 5 iterations complete.

**Interactive only** — this command makes code changes and commits. Do not use as an automated pipeline gate.

## Process

1. Run quality-scan skill
2. If issues found: fix ALL of them
3. Run quality-scan again
4. Repeat until:
1. Run `/quality-scan` skill (all scan types)
2. If issues found: spawn the `refactor-cleaner` agent (see `agents/refactor-cleaner.md`) to fix them, grouped by category
3. Run verify-build (see `_shared/verify-build.md`) after fixes
4. Run `/quality-scan` again
5. Repeat until:
- Zero issues found (success), OR
- 5 iterations completed (stop)
5. Commit all fixes with message: "fix: resolve quality scan issues (iteration N)"
6. Commit all fixes: `fix: resolve quality scan issues (iteration N)`

## Rules

- Fix every issue, not just "easy" ones
- Do not skip architectural fixes
- Fix every issue, not just easy ones
- Spawn refactor-cleaner with CLAUDE.md's pre-action protocol: dead code first, then structural changes, ≤5 files per phase
- Run tests after fixes to verify nothing broke
- Track iteration count and report progress

## Outstanding Architectural Issue (Requires Design Review)

### Checkpoint Cache Invalidation (High Severity)

**Issue**: Source package changes don't invalidate checkpoints properly.

**Root Cause**: Cache keys are computed AFTER `prepareExternalSources()` syncs source packages to additions/. Since cache keys hash files in additions/ (which are now synced), they match the checkpoint even though source packages changed.

**Scenario**:
1. Developer modifies `packages/binject/src/socketsecurity/binject/file.c`
2. Runs `pnpm --filter node-smol-builder clean && pnpm build`
3. `prepareExternalSources()` syncs binject → additions/source-patched/src/socketsecurity/binject/
4. Cache key computed from additions/ files matches old checkpoint
5. Build restores stale checkpoint, skips recompilation
6. **Result**: Binary contains old binject code

**Impact**: Silent build incorrectness when modifying source packages

**Proposed Solutions** (require architectural review):
- Option 1: Include source package mtimes in cache key metadata
- Option 2: Make `prepareExternalSources()` idempotent, always re-sync

**Files Affected**:
- packages/node-smol-builder/scripts/common/shared/build.mjs (collectBuildSourceFiles)
- packages/node-smol-builder/scripts/common/shared/checkpoints.mjs (cache key generation)

**Status**: Documented for architectural review and future implementation
3 changes: 3 additions & 0 deletions .claude/commands/security-scan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Run the `/security-scan` skill. This chains AgentShield (Claude config audit) → zizmor (GitHub Actions security) → security-reviewer agent (grading).

For a quick manual run without the full pipeline: `pnpm run security`
10 changes: 10 additions & 0 deletions .claude/ops/queue.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
schema_version: 1

phase_order:
quality-scan: [env-check, scans, report]
security-scan: [env-check, agentshield, zizmor, grade-report]
updating: [env-check, npm-update, validate, report]

# Completed runs are appended here by skills. Prune periodically —
# keep the last 10 entries and delete older ones to avoid unbounded growth.
runs: []
27 changes: 27 additions & 0 deletions .claude/skills/_shared/env-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Environment Check

Shared prerequisite validation for all pipelines. Run at the start of every skill.

## Steps

1. Run `git status` to check working directory state
2. Detect CI mode: check for `GITHUB_ACTIONS` or `CI` environment variables
3. Verify `node_modules/` exists (run `pnpm install` if missing)
4. Verify on a valid branch (`git branch --show-current`)

## Behavior

- **Clean working directory**: proceed normally
- **Dirty working directory**: warn and continue (most skills are read-only or create their own commits)
- **CI mode**: set `CI_MODE=true` — skills should skip interactive prompts and local-only validation
- **Missing node_modules**: run `pnpm install` before proceeding

## Queue Tracking

Write a run entry to `.claude/ops/queue.yaml` with:
- `id`: `{pipeline}-{YYYY-MM-DD}-{NNN}`
- `pipeline`: the invoking skill name
- `status`: `in-progress`
- `started`: current UTC timestamp
- `current_phase`: `env-check`
- `completed_phases`: `[]`
47 changes: 47 additions & 0 deletions .claude/skills/_shared/report-format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Report Format

Shared output format for all scan and review pipelines.

## Finding Format

Each finding:
```
- **[SEVERITY]** file:line — description
Fix: how to fix it
```

Severity levels: CRITICAL, HIGH, MEDIUM, LOW

## Grade Calculation

Based on finding severity distribution:
- **A** (90-100): 0 critical, 0 high
- **B** (80-89): 0 critical, 1-3 high
- **C** (70-79): 0 critical, 4+ high OR 1 critical
- **D** (60-69): 2-3 critical
- **F** (< 60): 4+ critical

## Pipeline HANDOFF

When a skill completes as part of a larger pipeline (e.g., quality-scan within release),
output a structured handoff block:

```
=== HANDOFF: {skill-name} ===
Status: {pass|fail}
Grade: {A-F}
Findings: {critical: N, high: N, medium: N, low: N}
Summary: {one-line description}
=== END HANDOFF ===
```

The parent pipeline reads this to decide whether to proceed (gate check) or abort.

## Queue Completion

When the final phase completes, update `.claude/ops/queue.yaml`:
- `status`: `done` (or `failed`)
- `completed`: current UTC timestamp
- `current_phase`: `~` (null)
- `completed_phases`: full list
- `findings_count`: `{critical: N, high: N, medium: N, low: N}`
41 changes: 41 additions & 0 deletions .claude/skills/_shared/security-tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Security Tools

Shared tool detection for security scanning pipelines.

## AgentShield

Installed as a pinned devDependency (`ecc-agentshield` in pnpm-workspace.yaml catalog).
Run via: `pnpm exec agentshield scan`
No install step needed — available after `pnpm install`.

## Zizmor

Not an npm package. Installed via `pnpm run setup` which downloads the pinned version
from GitHub releases with SHA256 checksum verification (see `external-tools.json`).

The binary is cached at `.cache/external-tools/zizmor/{version}-{platform}/zizmor`.

Detection order:
1. `command -v zizmor` (if already on PATH, e.g. via brew)
2. `.cache/external-tools/zizmor/*/zizmor` (from `pnpm run setup`)

Run via the full path if not on PATH:
```bash
ZIZMOR="$(find .cache/external-tools/zizmor -name zizmor -type f 2>/dev/null | head -1)"
if [ -z "$ZIZMOR" ]; then ZIZMOR="$(command -v zizmor 2>/dev/null)"; fi
if [ -n "$ZIZMOR" ]; then "$ZIZMOR" .github/; else echo "zizmor not installed — run pnpm run setup"; fi
```

If not available:
- Warn: "zizmor not installed — run `pnpm run setup` to install"
- Skip the zizmor phase (don't fail the pipeline)

## Socket CLI

Optional. Used for dependency scanning in the updating and security-scan pipelines.

Detection: `command -v socket`

If not available:
- Skip socket-scan phases gracefully
- Note in report: "Socket CLI not available — dependency scan skipped"
22 changes: 22 additions & 0 deletions .claude/skills/_shared/verify-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Verify Build

Shared build/test/lint validation. Referenced by skills that modify code or dependencies.

## Steps

Run in order, stop on first failure:

1. `pnpm run fix --all` — auto-fix lint and formatting issues
2. `pnpm run check --all` — lint + typecheck + validation (read-only, fails on violations)
3. `pnpm test` — full test suite

## CI Mode

When `CI_MODE=true` (detected by env-check), skip this validation entirely.
CI runs these checks in its own matrix (Node 20/22/24 × ubuntu/windows).

## On Failure

- Report which step failed with the error output
- Do NOT proceed to the next pipeline phase
- Mark the pipeline run as `status: failed` in `.claude/ops/queue.yaml`
82 changes: 82 additions & 0 deletions .claude/skills/security-scan/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
name: security-scan
description: Run a multi-tool security scan — AgentShield for Claude config, zizmor for GitHub Actions, and optionally Socket CLI for dependency scanning. Produces an A-F graded security report.
---

# Security Scan

Multi-tool security scanning pipeline for the repository.

## When to Use

- After modifying `.claude/` config, settings, hooks, or agent definitions
- After modifying GitHub Actions workflows
- Before releases (called as a gate by the release pipeline)
- Periodic security hygiene checks

## Prerequisites

See `_shared/security-tools.md` for tool detection and installation.

## Process

### Phase 1: Environment Check

Follow `_shared/env-check.md`. Initialize a queue run entry for `security-scan`.

---

### Phase 2: AgentShield Scan

Scan Claude Code configuration for security issues:

```bash
pnpm exec agentshield scan
```

Checks `.claude/` for:
- Hardcoded secrets in CLAUDE.md and settings
- Overly permissive tool allow lists (e.g. `Bash(*)`)
- Prompt injection patterns in agent definitions
- Command injection risks in hooks
- Risky MCP server configurations

Capture the grade and findings count.

Update queue: `current_phase: agentshield` → `completed_phases: [env-check, agentshield]`

---

### Phase 3: Zizmor Scan

Scan GitHub Actions workflows for security issues.

See `_shared/security-tools.md` for zizmor detection. If not installed, skip with a warning.

```bash
zizmor .github/
```

Checks for:
- Unpinned actions (must use full SHA, not tags)
- Secrets used outside `env:` blocks
- Injection risks from untrusted inputs (template injection)
- Overly permissive permissions

Capture findings. Update queue phase.

---

### Phase 4: Grade + Report

Spawn the `security-reviewer` agent (see `agents/security-reviewer.md`) with the combined output from AgentShield and zizmor.

The agent:
1. Applies CLAUDE.md security rules to evaluate the findings
2. Calculates an A-F grade per `_shared/report-format.md`
3. Generates a prioritized report (CRITICAL first)
4. Suggests fixes for HIGH and CRITICAL findings

Output a HANDOFF block per `_shared/report-format.md` for pipeline chaining.

Update queue: `status: done`, write `findings_count` and final grade.
16 changes: 16 additions & 0 deletions .git-hooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,22 @@ echo "$STAGED_FILES" | while IFS= read -r file; do
fi
done

# Check for npx/dlx usage (use pnpm exec or pnpm run instead).
printf "Checking for npx/dlx usage...\n"
for file in $STAGED_FILES; do
if [ -f "$file" ]; then
if echo "$file" | grep -qE 'node_modules/|pnpm-lock\.yaml|\.git-hooks/'; then
continue
fi
if grep -nE '\bnpx\b|\bpnpm dlx\b|\byarn dlx\b' "$file" 2>/dev/null | grep -v '# zizmor:' | grep -q .; then
printf "${RED}✗ ERROR: npx/dlx usage found in: $file${NC}\n"
grep -nE '\bnpx\b|\bpnpm dlx\b|\byarn dlx\b' "$file" | grep -v '# zizmor:' | head -3
printf "Use 'pnpm exec <package>' or 'pnpm run <script>' instead.\n"
ERRORS=$((ERRORS + 1))
fi
fi
done

if [ $ERRORS -gt 0 ]; then
printf "\n"
printf "${RED}✗ Security check failed with $ERRORS error(s).${NC}\n"
Expand Down
Loading