Skip to content
Open
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-registry).

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-registry).

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/release-changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Run the `/release` skill starting from the changelog phase.

If you want the full release pipeline (quality gate → security gate → changelog → version bump), run `/release` instead.
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`
12 changes: 12 additions & 0 deletions .claude/ops/queue.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
schema_version: 1

phase_order:
quality-scan: [env-check, dep-update, tools-install, cleanup, structural, scan-scope, scans, aggregate, report, complete]
security-scan: [env-check, agentshield, zizmor, grade-report]
updating: [env-check, npm-update, validate, report]
ci-cascade: [identify, layer-prs, layer-4-update, propagate, verify]
release: [quality-gate, security-gate, changelog, version-bump]

# 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`
87 changes: 87 additions & 0 deletions .claude/skills/ci-cascade/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
name: ci-cascade
description: Execute the GitHub Actions SHA pin cascade when a socket-registry action changes. Creates PRs in dependency order, waits for merges, and propagates the final SHA to all consuming repos.
---

# CI SHA Pin Cascade

Implements the cascade procedure defined in CLAUDE.md § "GitHub Actions SHA Pin Cascade (CRITICAL)".

## When to Use

- After modifying any GitHub Action in `.github/actions/`
- After modifying a reusable workflow in `.github/workflows/ci.yml` or `provenance.yml`
- When a dependency (Node.js version, pnpm version, sfw-free) changes in an action

## Procedure

Follow `_shared/env-check.md` to initialize a queue run entry for `ci-cascade`.

Follow the layer order exactly. Each layer gets its own PR. Never combine layers.

### Phase 1: Identify what changed

Update queue: advance `current_phase` in `.claude/ops/queue.yaml`

Determine which layer was modified:
- Layer 1 (leaf actions): checkout, install, debug, setup-git-signing, cleanup-git-signing, run-script, artifacts, cache-npm-packages
- Layer 2a (setup): references debug
- Layer 2b (setup-and-install): references checkout, setup, install
- Layer 3 (reusable workflows): ci.yml, provenance.yml
- Layer 4 (local wrappers): _local-not-for-reuse-*

### Phase 2: Create PRs in order

Update queue: advance `current_phase` in `.claude/ops/queue.yaml`

Starting from the layer above the change, create a PR for each layer:

1. **Get current SHA**: `git fetch origin main && git rev-parse origin/main`
2. **Create branch**: `git checkout -b chore/ci-cascade-layer-N`
3. **Update refs**: Replace old SHA with new SHA in all files at this layer
4. **Verify**: `grep -rn "SocketDev/socket-registry" .github/ | grep "@" | grep -v "<new-sha>"`
5. **Don't clobber**: Never replace third-party SHAs (actions/checkout, actions/upload-artifact, etc.)
6. **Commit**: `chore(ci): bump socket-registry action refs to main (<short-sha>)`
7. **Push and create PR**
8. **Wait for merge** before proceeding to next layer

### Phase 3: Update Layer 4 (local wrappers)

Update queue: advance `current_phase` in `.claude/ops/queue.yaml`

After Layer 3 merges, get the **propagation SHA** (Layer 3 merge SHA). Update the `_local-not-for-reuse-*` workflows to pin to this SHA. Create a PR, merge it.

The Layer 4 merge SHA is NOT used for external pinning — external repos pin to the Layer 3 SHA because that's where the reusable workflows (ci.yml, provenance.yml) were updated.

### Phase 4: Propagate to external repos

Update queue: advance `current_phase` in `.claude/ops/queue.yaml`

All external repos pin to the **propagation SHA** (Layer 3 merge SHA).

For each repo:
1. Update all `SocketDev/socket-registry/.github/` refs to the propagation SHA
2. Push directly to main where allowed (socket-btm, socket-sbom-generator, ultrathink)
3. Create PRs where branch protection requires it (socket-cli, socket-lib, socket-sdk-js, socket-packageurl-js)

### Phase 5: Verify

Update queue: advance `current_phase` in `.claude/ops/queue.yaml`

For each updated repo, confirm no old SHAs remain:
```bash
grep -rn "SocketDev/socket-registry" .github/ | grep "@" | grep -v "<propagation-sha>"
```

### Completion

Output a HANDOFF block per `_shared/report-format.md`:

```
=== HANDOFF: ci-cascade ===
Status: {pass|fail}
Summary: {one-line: "Propagated SHA XXXXX to N repos"}
=== END HANDOFF ===
```

Update queue: `status: done`, write completion timestamp.
Loading
Loading