Get the FREE Ultimate OpenClaw Setup Guide →

naming

npx machina-cli add skill tslateman/duet/naming --openclaw
Files (1)
SKILL.md
7.9 KB

Naming as Design

Overview

Naming difficulty is a design smell. When you struggle to name something, the abstraction is wrong. Use naming as a lens to surface confused boundaries, mixed responsibilities, and domain misunderstanding.

Benner's Four Principles

Every name balances four properties. When they conflict, make the tradeoff deliberate.

  1. Understandability — Describe the context it represents. A reader should know what it does without reading the implementation
  2. Conciseness — Use only the words necessary. Longer is not clearer if the extra words add no meaning
  3. Consistency — Same word means the same thing everywhere. Different things get different names
  4. Distinguishability — A name must be distinct from its neighbors. Similar names for different things cause bugs

See references/principles.md for detailed rules and naming smells.

Two Modes

Review Mode

Examine names in recently changed code:

  1. Read the changed code
  2. For each name, ask:
    • Does it pass all four principles?
    • Could a reader understand this without context?
    • Is the verb specific? ("process", "handle", "manage" almost never are)
    • Does it match the domain language?
  3. Surface violations with specific alternatives

Design Mode

When naming is hard, use the struggle as a diagnostic:

  1. What does this thing actually do? List its responsibilities
  2. If the list has more than one item, the naming problem is a design problem — split it
  3. Who calls it? What do they expect?
  4. If it disappeared, what would break? That's what it is
  5. What would the domain expert call it?

Naming Smells

Names that signal design confusion:

SmellExampleWhat it reveals
Generic verbhandleData, processRequestUnclear responsibility
Suffix -Manager, -Helper, -UtilsUserManager, StringHelperGod object or junk drawer
And/Or in namevalidateAndSaveTwo responsibilities
Type in nameuserList, nameStringRedundant or wrong abstraction level
Negated booleanisNotReady, disableFeatureDouble negatives in conditions
Abbreviated beyond recognitionusrSvcRspConciseness without understandability

Bloch's API Design Maxims

For public interfaces — APIs, library boundaries, module exports:

  • Names should be self-documenting. If you need a comment to explain what a function does, rename it
  • Same word, same meaning. Don't use "remove" in one place and "delete" in another for the same operation
  • Principle of Least Astonishment. A method named check should not modify state
  • If it's hard to name, the design is wrong. Rename the design, not just the symbol

Evans' Ubiquitous Language

Code names should match how domain experts talk:

  • If the business says "order" and code says "purchase", one of them is wrong
  • Naming mismatches between code and conversation reveal domain misunderstanding
  • When renaming, update tests, docs, and conversations — not just code

Naming Checklist

For any name under review:

[ ] Specific verb (not handle/process/manage/do)
[ ] No unnecessary words
[ ] Consistent with similar names nearby
[ ] Distinguishable from neighbors
[ ] Matches domain language
[ ] Readable without implementation context
[ ] No embedded type information
[ ] Boolean reads as a question (isReady, hasPermission, canEdit)

Output Format

When reviewing names:

## Naming Review

### Must Rename

- `processData` → `validateInvoiceLineItems` — "process" hides
  the actual responsibility; this only validates
- `handleClick` → `submitPayment` — name the action, not
  the event

### Consider Renaming

- `userInfo` → `billingProfile` — more specific to its
  actual contents

### Design Concern

- `OrderManager` has 12 methods spanning validation,
  persistence, and notification. The naming struggle
  reflects three responsibilities that should be separate
  types.

Before/After Examples

Functions

BeforeAfterWhy
processData(input)validateInvoiceLineItems(invoice)"Process" hides responsibility; name the action and the domain
handleClick()submitPayment()Name the business action, not the DOM event
doStuff(items)deduplicateContacts(contacts)Eliminate weasel verbs; name what it actually does
run()pollForStatusUpdates()Ambiguous in any class with more than one operation

Variables

BeforeAfterWhy
dataunpaidInvoicesGeneric noun → specific domain concept
tempunsavedDraftReveals intent; "temp" says nothing about lifecycle
flagrequiresApprovalReads as a question; boolean purpose is clear
resultvalidationErrorsNames the content, not the role in the function
listactiveSubscriptionsType-in-name smell; name the contents instead

Types and Modules

BeforeAfterWhy
UserManagerUserRepository + UserNotifier-Manager reveals multiple responsibilities; split them
StringHelperSlugFormatter-Helper is a junk drawer; name the actual capability
DataServiceInventoryClientTwo generic words; name the domain and the role
utils/misc.tspricing/discount-rules.tsFile path is a name too; make it navigable

Booleans

BeforeAfterWhy
isNotReadyisReady (invert usage)Avoid double negatives in conditionals
disableFeaturefeatureEnabled (invert usage)Positive form reads naturally in if statements
checkhasPermission"Check" doesn't say what the answer means

Strunk's Rule 12

"Use definite, specific, concrete language." The prose skill teaches this for English. Apply it identically to code:

VagueSpecific
getDatafetchUserProfile
itemcartLineItem
resultvalidationErrors
infoshippingAddress
tempunsavedDraft

See Also

  • /design — Hard-to-name things signal design problems
  • /review — Code review surfaces naming issues; naming review deepens code review
  • /prose — Strunk's rules apply to code names identically to English prose
  • skills/FRAMEWORKS.md — Full framework index

Source

git clone https://github.com/tslateman/duet/blob/main/skills/naming/SKILL.mdView on GitHub

Overview

Naming difficulty is a design smell. When naming is hard, boundaries become unclear and responsibilities blur, signaling domain misunderstandings. Naming as a design lens surfaces these issues using Benner's Four Principles to guide targeted renames that improve clarity and maintainability.

How This Skill Works

In Review Mode, scan recently changed code and evaluate each name against Understandability, Conciseness, Consistency, and Distinguishability, checking if a reader can grasp intent without implementation context, whether words are necessary, and if the naming matches domain language. In Design Mode, treat naming struggles as a diagnostic: list actual responsibilities, split if there are multiple, identify who calls it and what would fail if it disappeared, and align with domain expert terminology. This approach helps surface design problems rather than merely polishing labels.

When to Use It

  • When asked to name or rename something (name this, rename, what should I call it)
  • When a code review surfaces vague or misleading names
  • When a symbol's name implies more than one responsibility (design smell)
  • When you want to align names with domain language
  • When you want to surface design problems through naming and boundaries

Quick Start

  1. Step 1: Read recently changed code and list names that fail Benner's Four Principles
  2. Step 2: For each offender, propose alternatives that reflect domain language and single responsibility
  3. Step 3: Implement targeted renames and update tests, docs, and conversations accordingly

Best Practices

  • Use a specific verb (not handle/process/manage/do)
  • Keep words concise and avoid unnecessary terms
  • Maintain consistency with similar names nearby
  • Ensure names are distinguishable from neighbors
  • Match domain language and ensure readability without implementation context

Example Use Cases

  • Before: handleData -> After: loadData (clarifies action and intent)
  • Before: UserManager -> After: UserService (better boundary and responsibilities)
  • Before: validateAndSave -> After: validateData and saveData (split responsibilities)
  • Before: userList -> After: users (aligns with domain language and reduces type hinting)
  • Before: isNotReady / disableFeature -> After: isReady / featureEnabled (remove negation and clarify state)

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers