|
11 | 11 |
|
12 | 12 | **MANDATORY**: Review CLAUDE.md before any action. No exceptions. |
13 | 13 |
|
14 | | -- Before ANY structural refactor on a file >300 LOC: remove dead code, unused exports, unused imports first -- commit that cleanup separately |
15 | | -- Multi-file changes: break into phases (<=5 files each), verify each phase before the next |
16 | | -- When pointed to existing code as a reference: study it before building |
17 | | -- Work from raw error data, not theories -- if a bug report has no error output, ask for it |
| 14 | +- Before ANY structural refactor on a file >300 LOC: remove dead code/unused exports/imports first — commit separately |
| 15 | +- Multi-file changes: break into phases (≤5 files each), verify each phase before the next |
| 16 | +- Study existing code before building |
| 17 | +- Work from raw error data, not theories — if a bug report has no error output, ask for it |
18 | 18 | - On "yes", "do it", or "go": execute immediately, no plan recap |
19 | 19 |
|
20 | 20 | ## VERIFICATION PROTOCOL |
21 | 21 |
|
22 | | -**MANDATORY**: Before claiming any task is complete: |
23 | | - |
24 | | -1. Run the actual command -- execute the script, run the test, check the output |
| 22 | +1. Run the actual command — execute, don't assume |
25 | 23 | 2. State what you verified, not just "looks good" |
26 | 24 | 3. **FORBIDDEN**: Claiming "Done" when any test output shows failures |
27 | | -4. If type-check or lint is configured, run it and fix ALL errors before reporting done |
28 | | -5. Re-read every file modified; confirm nothing references something that no longer exists |
| 25 | +4. Run type-check/lint if configured; fix ALL errors before reporting done |
| 26 | +5. Re-read every modified file; confirm nothing references removed items |
29 | 27 |
|
30 | 28 | ## CONTEXT & EDIT SAFETY |
31 | 29 |
|
32 | | -- After 10+ messages: re-read any file before editing it |
33 | | -- Read files >500 LOC in chunks using offset/limit |
34 | | -- Before every edit: re-read the file. After every edit: re-read to confirm |
35 | | -- When renaming: search for direct calls, type references, string literals, dynamic imports, re-exports, test files -- one grep is not enough |
| 30 | +- After 10+ messages: re-read files before editing |
| 31 | +- Read files >500 LOC in chunks (offset/limit) |
| 32 | +- Before every edit: re-read. After every edit: re-read to confirm |
| 33 | +- When renaming: search direct calls, type refs, string literals, dynamic imports, re-exports, tests |
| 34 | +- Tool results over 50K chars are silently truncated — narrow scope and re-run if incomplete |
| 35 | +- For tasks touching >5 files: use sub-agents with worktree isolation |
36 | 36 | - Never fix a display/rendering problem by duplicating state |
37 | 37 |
|
38 | | -## JUDGMENT & SCOPE |
| 38 | +## JUDGMENT PROTOCOL |
| 39 | + |
| 40 | +- If the user's request is based on a misconception, say so before executing |
| 41 | +- If you spot a bug adjacent to what was asked, flag it: "I also noticed X — want me to fix it?" |
| 42 | +- You are a collaborator, not just an executor |
| 43 | +- Fix warnings when you find them (lint, type-check, build, runtime) — don't leave them for later |
| 44 | + |
| 45 | +## SCOPE PROTOCOL |
39 | 46 |
|
40 | | -- If the request is based on a misconception, say so before executing |
41 | | -- If you spot a bug adjacent to what was asked, flag it |
42 | 47 | - Do not add features, refactor, or make improvements beyond what was asked |
43 | | -- Try the simplest approach first; flag architecture issues and wait for approval |
44 | | -- When asked to "make a plan," output only the plan -- no code until given the go-ahead |
| 48 | +- Simplest approach first; flag architectural flaws and wait for approval |
| 49 | +- When asked to "make a plan," output only the plan — no code until given the go-ahead |
| 50 | + |
| 51 | +## COMPLETION PROTOCOL |
| 52 | + |
| 53 | +- NEVER claim done at 80% — finish 100% before reporting |
| 54 | +- Fix forward: if an approach fails, analyze why, adjust, rebuild — not `git checkout` |
| 55 | +- After EVERY code change: build, test, verify, commit as a single atomic unit |
| 56 | +- Reverting requires explicit user approval |
45 | 57 |
|
46 | 58 | ## SELF-EVALUATION |
47 | 59 |
|
48 | | -- Before calling anything done: present what a perfectionist would reject vs. what a pragmatist would ship |
| 60 | +- Present two views before calling done: what a perfectionist would reject vs. what a pragmatist would ship |
49 | 61 | - After fixing a bug: explain why it happened and what category of bug it represents |
50 | | -- If a fix doesn't work after two attempts: stop, re-read top-down, state where the mental model was wrong |
| 62 | +- If a fix fails twice: stop, re-read top-down, state where the mental model was wrong |
51 | 63 | - If asked to "step back": drop everything, rethink from scratch |
52 | 64 |
|
53 | 65 | ## HOUSEKEEPING |
54 | 66 |
|
55 | | -- Before risky changes: offer to checkpoint |
56 | | -- If a file is getting unwieldy (>400 LOC): flag it |
| 67 | +- Offer to checkpoint before risky changes |
| 68 | +- Flag files >400 LOC for potential splitting |
57 | 69 |
|
58 | | -## Critical Rules |
| 70 | +## ABSOLUTE RULES |
59 | 71 |
|
60 | | -- **Fix ALL issues when asked** -- never dismiss issues as "pre-existing" |
| 72 | +- **Fix ALL issues when asked** — never dismiss as "pre-existing" |
61 | 73 | - Never create files unless necessary; always prefer editing existing files |
62 | 74 | - Forbidden to create docs unless requested |
63 | | -- 🚨 **NEVER use `npx`, `pnpm dlx`, or `yarn dlx`** -- use `pnpm exec <package>` for devDep binaries, or `pnpm run <script>` for package.json scripts |
| 75 | +- 🚨 **NEVER use `npx`, `pnpm dlx`, or `yarn dlx`** — use `pnpm exec <package>` or `pnpm run <script>` |
64 | 76 |
|
65 | 77 | ## EVOLUTION |
66 | 78 |
|
67 | 79 | If user repeats instruction 2+ times, ask: "Should I add this to CLAUDE.md?" |
68 | 80 |
|
69 | 81 | ## SHARED STANDARDS |
70 | 82 |
|
71 | | - |
72 | | - |
73 | | -- Commits: [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) `<type>(<scope>): <description>` -- NO AI attribution |
74 | | -- Scripts: Prefer `pnpm run foo --flag` over `foo:bar` scripts |
75 | | -- Dependencies: After `package.json` edits, run `pnpm install` to update `pnpm-lock.yaml` |
76 | | -- Backward Compatibility: 🚨 FORBIDDEN to maintain -- actively remove when encountered |
| 83 | +- Commits: [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) `<type>(<scope>): <description>` — NO AI attribution |
| 84 | +- Scripts: Prefer `pnpm run foo --flag` over `foo:bar` variants |
| 85 | +- Dependencies: After `package.json` edits, run `pnpm install` |
| 86 | +- Backward Compatibility: 🚨 FORBIDDEN to maintain — actively remove when encountered |
77 | 87 | - Safe Deletion: Use `safeDelete()` from `@socketsecurity/lib/fs` (NEVER `fs.rm/rmSync` or `rm -rf`) |
78 | | -- HTTP Requests: NEVER use `fetch()` -- use `httpJson`/`httpText`/`httpRequest` from `@socketsecurity/lib/http-request` |
| 88 | +- HTTP Requests: NEVER use `fetch()` — use `httpJson`/`httpText`/`httpRequest` from `@socketsecurity/lib/http-request` |
| 89 | +- File existence: ALWAYS `existsSync` from `node:fs`. NEVER `fs.access`, `fs.stat`-for-existence, or an async `fileExists` wrapper. Import: `import { existsSync, promises as fs } from 'node:fs'`. |
79 | 90 |
|
80 | 91 | ### Documentation Policy |
81 | 92 |
|
82 | | -Do NOT litter the repository with documentation files. Allowed locations: `docs/`, root `README.md`/`CHANGELOG.md`/`SECURITY.md`/`CLAUDE.md`, `packages/*/README.md`, `test/fixtures/*/README.md`, `test/*/README.md`. No ad-hoc markdown files. |
| 93 | +Do NOT litter the repo with markdown. Allowed: `docs/`, root `README.md`/`CHANGELOG.md`/`SECURITY.md`/`CLAUDE.md`, `packages/*/README.md`, `test/fixtures/*/README.md`, `test/*/README.md`. |
83 | 94 |
|
84 | | -**`.claude/` exception**: markdown files under `.claude/agents/`, `.claude/commands/`, `.claude/hooks/`, and `.claude/skills/` are allowed because the Claude harness reads them as configuration (agent definitions, command metadata, `SKILL.md` entrypoints, skill references). These are config, not analysis docs. Ad-hoc analysis/session notes in `.claude/` are still disallowed. |
| 95 | +**`.claude/` exception**: markdown under `.claude/agents/`, `.claude/commands/`, `.claude/hooks/`, `.claude/skills/` is allowed (harness-loaded config). Ad-hoc analysis/session notes still disallowed. |
85 | 96 |
|
86 | 97 | --- |
87 | 98 |
|
88 | | -## CLI-SPECIFIC |
| 99 | +## 🏗️ CLI-SPECIFIC |
89 | 100 |
|
90 | | -## Commands |
| 101 | +### Commands |
91 | 102 |
|
92 | | -- **Build**: `pnpm run build` (smart build) | `pnpm run build --force` | `pnpm run build:cli` (CLI only) | `pnpm run build:sea` |
93 | | -- **Test**: `pnpm test` (all from monorepo root) | `pnpm --filter @socketsecurity/cli run test:unit` |
| 103 | +- **Build**: `pnpm run build` (smart) | `--force` | `pnpm run build:cli` | `pnpm run build:sea` |
| 104 | +- **Test**: `pnpm test` (monorepo root) | `pnpm --filter @socketsecurity/cli run test:unit <path>` |
94 | 105 | - **Lint**: `pnpm run lint` | **Type check**: `pnpm run type` | **Check all**: `pnpm run check` |
95 | | -- **Fix**: `pnpm run fix` (auto-fix linting and formatting) |
96 | | -- **Dev**: `pnpm dev` (watch mode) | **Run built**: `node packages/cli/dist/index.js <args>` |
| 106 | +- **Fix**: `pnpm run fix` | **Dev**: `pnpm dev` (watch) | **Run built**: `node packages/cli/dist/index.js <args>` |
97 | 107 |
|
98 | | -### Testing -- CRITICAL |
| 108 | +### Testing |
99 | 109 |
|
100 | | -- 🚨 **NEVER USE `--` BEFORE TEST FILE PATHS** -- this runs ALL tests, not just specified files |
| 110 | +- 🚨 **NEVER use `--` before test file paths** — runs ALL tests |
101 | 111 | - Always build before testing: `pnpm run build:cli` |
102 | | -- Single file: `pnpm --filter @socketsecurity/cli run test:unit src/commands/specific/cmd-file.test.mts` |
103 | | -- Update snapshots: `pnpm testu src/commands/specific/cmd-file.test.mts` |
104 | | -- Update with flag: `pnpm --filter @socketsecurity/cli run test:unit src/commands/specific/cmd-file.test.mts --update` |
105 | | -- NEVER write source-code-scanning tests -- verify behavior, not string patterns |
| 112 | +- Update snapshots: `pnpm testu <path>` or `--update` flag |
| 113 | +- NEVER write source-code-scanning tests — verify behavior, not string patterns |
106 | 114 |
|
107 | 115 | ### Changelog |
108 | 116 |
|
109 | | -Follow [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). User-facing changes only: Added, Changed, Fixed, Removed. Marketing voice, stay concise. |
| 117 | +Follow [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). User-facing only: Added, Changed, Fixed, Removed. Concise. |
110 | 118 |
|
111 | | -## Code Style (MANDATORY) |
| 119 | +### Code Style (MANDATORY) |
112 | 120 |
|
113 | | -### File Organization |
114 | | - |
115 | | -- `.mts` extensions for TypeScript modules |
116 | | -- 🚨 ALWAYS use separate `import type` statements -- NEVER mix runtime and type imports |
117 | | -- Node.js fs: `import { existsSync, promises as fs } from 'node:fs'` (cherry-pick `existsSync`, alias promises as `fs`) |
| 121 | +- `.mts` extensions for TS modules |
| 122 | +- 🚨 Separate `import type` statements — NEVER mix runtime and type imports |
118 | 123 | - Process spawning: MUST use `spawn` from `@socketsecurity/registry/lib/spawn` (NEVER `child_process`) |
119 | | -- File existence: ALWAYS use `existsSync` from `node:fs`. NEVER `fs.access`, `fs.stat`-for-existence, or an async `fileExists` wrapper. |
120 | | - |
121 | | -### Code Patterns |
122 | | - |
123 | | -- Array destructuring: Use `{ 0: key, 1: data }` instead of `[key, data]` |
124 | | -- Dynamic imports: 🚨 FORBIDDEN -- always use static imports |
125 | | -- Sorting: 🚨 MANDATORY -- sort lists, exports, destructured properties, documentation headers alphabetically |
126 | | -- Comments: Default NO. Only when the WHY is non-obvious. Own line, not inline. |
127 | | -- Functions: Alphabetical order, private first, exported second |
128 | | -- Object mappings: Use `__proto__: null` for static lookup tables; `Map` for dynamic collections |
129 | | -- Array length: `!array.length` not `=== 0`; `array.length` or `!!array.length` for truthy |
| 124 | +- Array destructuring: `{ 0: key, 1: data }` instead of `[key, data]` |
| 125 | +- Dynamic imports: 🚨 FORBIDDEN — always static imports |
| 126 | +- Sorting: 🚨 MANDATORY — lists, exports, destructured properties, doc headers alphabetically |
| 127 | +- Comments: Default NO. Only when WHY is non-obvious. Own line, not inline. |
| 128 | +- Functions: alphabetical; private first, exported second |
| 129 | +- Object mappings: `__proto__: null` for static lookup; `Map` for dynamic |
| 130 | +- Array length: `!array.length` not `=== 0` |
130 | 131 | - Catch: `catch (e)` not `catch (error)` |
131 | | -- Numbers: Use underscore separators (`20_000`). Do NOT modify number values inside strings. |
132 | | -- Flags: MUST use `MeowFlags` type with descriptive help text |
133 | | -- Error handling: Use `InputError` and `AuthError` from `src/utils/errors.mts`; prefer `CResult<T>` for fallible functions; avoid `process.exit(1)` |
134 | | -- GitHub API: Use Octokit from `src/utils/github.mts`, not raw fetch |
| 132 | +- Numbers: underscore separators (`20_000`); don't modify values inside strings |
| 133 | +- Flags: MUST use `MeowFlags` type with descriptive help |
| 134 | +- Error handling: `InputError`/`AuthError` from `src/utils/errors.mts`; prefer `CResult<T>`; avoid `process.exit(1)` |
| 135 | +- GitHub API: Octokit from `src/utils/github.mts`, not raw fetch |
135 | 136 |
|
136 | 137 | ### Command Pattern |
137 | 138 |
|
138 | | -- Simple commands (<200 LOC, no subcommands): single `cmd-*.mts` file |
139 | | -- Complex commands: modular `cmd-*.mts` + `handle-*.mts` + `output-*.mts` + `fetch-*.mts` |
140 | | - |
141 | | -### Completion Protocol |
142 | | - |
143 | | -- NEVER claim done at 80% -- finish 100% before reporting |
144 | | -- Fix forward: if an approach fails, analyze why, adjust, rebuild -- not `git checkout` |
145 | | -- After EVERY code change: build, test, verify, commit as a single atomic unit |
146 | | -- Reverting requires explicit user approval |
147 | | - |
148 | | -### Context Awareness |
149 | | - |
150 | | -- Tool results over 50K characters are silently truncated -- narrow scope and re-run if results look incomplete |
151 | | -- For tasks touching >5 files: use sub-agents with worktree isolation |
| 139 | +- Simple (<200 LOC, no subcommands): single `cmd-*.mts` |
| 140 | +- Complex: `cmd-*.mts` + `handle-*.mts` + `output-*.mts` + `fetch-*.mts` |
152 | 141 |
|
153 | 142 | ## Codex Usage |
154 | 143 |
|
155 | | -- Codex is for advice and critical assessment ONLY -- never for making code changes |
156 | | -- Before complex optimizations (>30min), consult Codex for critical analysis first |
| 144 | +Advice and critical assessment ONLY — never for making code changes. Consult before complex optimizations (>30min). |
157 | 145 |
|
158 | 146 | ## Agents & Skills |
159 | 147 |
|
160 | | -- `/security-scan` -- AgentShield + zizmor security audit |
161 | | -- `/quality-scan` -- comprehensive code quality analysis |
162 | | -- `/quality-loop` -- scan and fix iteratively |
163 | | -- `/sync-checksums` -- sync external tool SHA-256 checksums |
| 148 | +- `/security-scan` — AgentShield + zizmor security audit |
| 149 | +- `/quality-scan` — comprehensive code quality analysis |
| 150 | +- `/quality-loop` — scan and fix iteratively |
| 151 | +- `/sync-checksums` — sync external tool SHA-256 checksums |
164 | 152 | - Agents: `code-reviewer`, `security-reviewer`, `refactor-cleaner` (in `.claude/agents/`) |
165 | 153 | - Shared subskills in `.claude/skills/_shared/` |
0 commit comments