You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
chore(claude): add sorting + open-PR rules to CLAUDE.md
Fleet-wide propagation from meander (b0f0cb2 + db95184). Adds:
- "Sorting" subsection in SHARED STANDARDS: codifies the rule
that config lists, object keys, import specifiers, top-level
function placement, and set-like array literals all sort
alphanumerically (literal byte order). Position-bearing arrays
opt out.
- "Open PRs" bullet in SHARED STANDARDS: when commits are added
to an open PR, the title + description must be rewritten to match.
Patch C (sort .claude/settings.json deny/allow) is N/A here —
this repo's settings.json has no permissions block.
Copy file name to clipboardExpand all lines: CLAUDE.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,6 +35,7 @@ The umbrella rule: never run a git command that mutates state belonging to a pat
35
35
## 📚 SHARED STANDARDS
36
36
37
37
- Commits: [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)`<type>(<scope>): <description>` — NO AI attribution
38
+
-**Open PRs:** when adding commits to an OPEN PR, ALWAYS update the PR title and description to match the new scope. A title like `chore: foo` after you've added security-fix and docs commits to it is now a lie. Use `gh pr edit <num> --title "..." --body "..."` (or `--body-file`) and rewrite the body so it reflects every commit on the branch, grouped by theme. The reviewer should be able to read the PR description and know what's in it without scrolling commits.
38
39
- Scripts: Prefer `pnpm run foo --flag` over `foo:bar` scripts
39
40
- Dependencies: After `package.json` edits, run `pnpm install`
40
41
- Backward Compatibility: 🚨 FORBIDDEN to maintain — actively remove when encountered
@@ -44,6 +45,18 @@ The umbrella rule: never run a git command that mutates state belonging to a pat
44
45
- Null-prototype objects: ALWAYS use `{ __proto__: null, ...rest }` for config, return, and internal-state objects. Prevents prototype pollution and accidental inheritance. See `src/socket-sdk-class.ts` and `src/file-upload.ts` for examples.
45
46
- Linear references: NEVER reference Linear issues (e.g. `SOC-123`, `ENG-456`, Linear URLs) in code, code comments, or PR titles/descriptions/review comments. Keep the codebase and PR history tool-agnostic — tracking lives in Linear.
46
47
48
+
### Sorting
49
+
50
+
Sort lists alphanumerically (literal byte order, ASCII before letters). Apply this to:
51
+
52
+
-**Config lists** — `permissions.allow` / `permissions.deny` in `.claude/settings.json`, `external-tools.json` checksum keys, allowlists in workflow YAML.
53
+
-**Object key entries** — sort keys in plain JSON config + return-shape literals + internal-state objects. (Exception: `__proto__: null` always comes first, ahead of any data keys.)
54
+
-**Import specifiers** — sort named imports inside a single statement: `import { encrypt, randomDataKey, wrapKey } from './crypto.mts'`. Imports that say `import type` follow the same rule. Statement *order* is the project's existing convention (`node:` → external → local → types) — that's separate from specifier order *within* a statement.
55
+
-**Method / function source placement** — within a module, sort top-level functions alphabetically. Convention: private functions (lowercase / un-exported) sort first, exported functions second. The first-line `export` keyword is the divider.
56
+
-**Array literals** — when the array is a config list, allowlist, or set-like collection. Position-bearing arrays (e.g. argv, anything where index matters semantically) keep their meaningful order.
57
+
58
+
When in doubt, sort. The cost of a sorted list that didn't need to be is approximately zero; the cost of an unsorted list that did need to be is a merge conflict.
59
+
47
60
### Promise.race in loops
48
61
49
62
**NEVER re-race the same pool of promises across loop iterations.** Each call to `Promise.race([A, B, ...])` attaches fresh `.then` handlers to every arm; a promise that survives N iterations accumulates N handler sets. See [nodejs/node#17469](https://github.com/nodejs/node/issues/17469) and `@watchable/unpromise`.
0 commit comments