Sort lists alphanumerically (literal byte order, ASCII before letters). This is a universal rule: any block of sibling items, in any file type, gets sorted unless there's a documented ordering reason. When you touch an unsorted block, fully re-sort it. Don't append the new entry and leave the rest unsorted.
- ASCII byte order, not natural/numeric order.
'name-10'sorts before'name-2'. Stable across Node versions and machines. - Case-sensitive.
'Z' < 'a'(uppercase first). Raw<comparison, notlocaleCompare. - No locale-aware collation. No
Intl.Collator, nonumeric: true. - Whole-token comparison, not character-class buckets.
These are the exact semantics every socket/sort-* lint rule uses.
- Import specifiers: named imports inside a single statement, e.g.
import { encrypt, randomDataKey, wrapKey } from './crypto.mts'.import typefollows the same rule. Statement order (node:→ external → local → types) is separate from specifier order within a statement. Enforced bysocket/sort-named-imports. - Object literal properties: sibling properties of an object literal at
module scope (and inside
export const/export default) sort alphanumerically. Exception:__proto__: nullalways comes first, ahead of any data key. Object literals that are position-bearing (HTTP header order, protocol field order) opt out with// socket-hook: allow object-property-order. Enforced bysocket/sort-object-literal-properties. - Method / function placement: within a module, sort top-level functions
alphabetically. Private functions (lowercase / un-exported) sort first,
exported functions second; the
exportkeyword is the divider.main, if present, stays last. Enforced bysocket/sort-source-methods. - Array literals: when the array is a config list, allowlist, or set-like
collection. Position-bearing arrays (
argv, anything where index matters semantically) keep their meaningful order. Setconstructor arguments:new Set([...])andnew SafeSet([...])literals. The runtime is order-insensitive, so source order is alphanumeric. Enforced bysocket/sort-set-args.- Regex alternation groups:
(foo|bar|baz)reads as(bar|baz|foo). Capturing, non-capturing, and named-capture groups all follow the rule. Auto-fixable when every alternative is a simple literal. Order-bearing alternations (rare; markup parsers where<!--|-->would silently mismatch if reordered) append// socket-hook: allow regex-alternation-order. Enforced bysocket/sort-regex-alternations. - String-equality disjunctions:
x === 'a' || x === 'b' || x === 'c'reads with the comparand strings in alpha order. The De Morgan dualx !== 'a' && x !== 'b'follows the same rule. Auto-fixable when every clause has the same left operand and uses string-literal comparands; mixed shapes are skipped. Enforced bysocket/sort-equality-disjunctions. - Boolean identifier chains:
agentshieldOk && zizmorOk && sfwOkreads in alpha order. Fires only when every leaf is a bareIdentifierAND the chain has 3+ operands (two-operand chains are guard patterns whose order carries narrative). Duplicate identifiers and interior comments are skipped. Enforced bysocket/sort-boolean-chains. - TypeScript union of string literals:
type Source = 'download' | 'path' | 'vfs'. Members are interchangeable at the type level; alpha order makes "which values can this take?" answerable without scanning. Position-bearing unions (a discriminator where order encodes priority) append// socket-hook: allow union-order. (Rule planned; see Roadmap.)
oxlint only sees JS/TS, so these are caught by the alpha-sort-reminder hook on
edit and by review, not by a lint rule.
- JSON / JSONC (
tsconfig.json,package.json,.oxlintrc.json,.config/*.json): sort every object's keys alphanumerically.- Exception:
tsconfig.jsontop-level has a canonical order (extends→compilerOptions→include→exclude→files); keys insidecompilerOptionsalphabetize. - Exception:
package.jsontop-level keeps npm convention (name→version→description→ … →scripts→dependencies); keys insidescripts/dependencies/devDependenciesalphabetize.
- Exception:
- YAML (
.github/workflows/*.yml,pnpm-workspace.yaml):env:blocks,with:blocks,catalog:entries,minimumReleaseAgeExcludearrays, and allowlist arrays alphabetize.matrix.include[]entries alphabetize by a compoundplatform → archkey. Even commented-out matrix entries sort into position; don't drop them at the bottom.- Exception: step lists are ordered by pipeline phase, not alpha.
- Exception: active matrix entries today are
x64-before-arm64fleet-wide for historical reasons; new entries follow alpha (arm64<x64), and a fleet-wide cascade re-sort of the active entries is a future PR. (Origin: socket-btmboringssl.yml, commit c8dd1f1b.)
- Bash / shell variables in workflow scripts: cache-key hash assignments
(
BIN_INFRA_LIB=$(...),BORINGSSL_PACKAGE_JSON=$(...)) alphabetize. Hash order doesn't affect correctness, but stable diffs do. - Markdown lists (README consumer lists, doc bullet lists, fleet-canonical
tables): alphabetize sibling bullets.
- Exception: narrative ordering (numbered setup steps, "first X then Y"). State the reason in surrounding prose.
- NO ELLIPSIS. Drop
"..."/"…"from list endings. List every item alphabetically, or write "N items, see<source>". Never trail off.
- Fully re-sort, don't append. Editing an already-sorted block → insert in sorted position. Editing an unsorted block → fully re-sort it in the same commit.
- Cascade-scoped re-sorts (e.g. all 8 builder workflows' matrix entries) get
a dedicated
chore(wheelhouse): cascade alpha-sort <pattern>PR. Don't slip the re-sort into unrelated work. - State the reason for any non-alpha order inline. Boot/init sequences, dependency chains, parser tokens in lex order, and discriminator priority all qualify.
When in doubt, sort. Sorting a list that didn't need it costs nothing. Leaving one unsorted that did costs a merge conflict later.
| Surface | Plan |
|---|---|
export { … } lists |
socket/sort-named-exports — mirror sort-named-imports. |
| TS string-literal unions | socket/sort-union-members — with // socket-hook: allow union-order escape. |
| Module-scope const arrays | socket/sort-array-literals — skip position-bearing arrays. |
| Independent switch-case branches | future rule; skip fall-through / early-return chains. |
.claude/settings.json permission lists, external-tools.json keys |
sync-scaffolding sort check. |
User-confirmed across 2026-04-17 → 2026-05-29 in socket-lib, socket-cli,
socket-btm, ultrathink, socket-sdk-js, socket-wheelhouse. Representative asks:
"properties and configs should be sorted alphanumerically" (JSON keys,
2026-04-17); "lets alphanumeric sort" (object-literal props); repeated
sort-source-methods reorders; "make sort-source-methods autofixable"; "add a
sort-boolean-chains rule"; "alphanumeric, no ellipsis" (README lists,
2026-05-29); "alphanumeric sort" on commented matrix entries
(boringssl.yml, 2026-05-29); "how can we do more alphanumeric sorting"
(2026-05-29, the meta-ask that produced this consolidation). John-David treats
an unsorted list as a defect: "when in doubt, sort."