pedantic-coder/skills/abbreviation-policy/SKILL.md
This skill should be used when the user is abbreviating identifiers, using acronyms, or when a codebase has inconsistent short forms like btn/button, msg/message, req/request. Covers the abbreviation decision framework, approved short forms, and the rule that consistency beats brevity.
npx skillsauth add oborchers/fractional-cto abbreviation-policyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Every abbreviation is a tax on the reader. The writer saves a few keystrokes; every future reader pays the cost of decoding. Modern editors autocomplete. Modern screens are wide. Modern codebases are searched, not memorized. There is no defensible reason to abbreviate an identifier unless the abbreviation is more widely recognized than the full word. url is clearer than uniformResourceLocator. btn is not clearer than button. This is the line, and it is not negotiable.
Before using any abbreviation, apply this test in order:
id, url, http -- everyone knows these.txMgr for "transaction manager" fails this test.The burden of proof is on the abbreviation. Full words are correct by default.
These abbreviations are approved for use in any codebase without documentation. They are more recognizable than their expanded forms.
| Abbreviation | Meaning | Context |
|-------------|---------|---------|
| id | Identifier | Any |
| url | Uniform Resource Locator | Any |
| http / https | Hypertext Transfer Protocol | Any |
| api | Application Programming Interface | Any |
| db | Database | Any |
| sql | Structured Query Language | Any |
| html | HyperText Markup Language | Any |
| css | Cascading Style Sheets | Any |
| json | JavaScript Object Notation | Any |
| xml | Extensible Markup Language | Any |
| config | Configuration | Any |
| auth | Authentication / Authorization | Any |
| admin | Administrator | Any |
| err | Error | Go (idiomatic), acceptable elsewhere |
| ctx | Context | Go (idiomatic), acceptable elsewhere |
| req | Request | Handler functions, middleware |
| res / resp | Response | Handler functions, middleware |
| fn | Function | Callbacks, higher-order functions |
| args | Arguments | Any |
| params | Parameters | Any |
| env | Environment | Configuration, deployment |
| src | Source | Build systems, file operations |
| dst | Destination | File operations, network |
| tmp | Temporary | Only for genuinely temporary values with a lifespan of a few lines |
| max | Maximum | Any |
| min | Minimum | Any |
| len | Length | Any |
| num | Number (count of) | Prefixing a noun: numRetries, num_users |
| prev | Previous | Iteration, state management |
| next | Next | Iteration, state management |
| init | Initialize | Startup, constructors |
| msg | Message | Messaging systems, logs, chat |
| doc | Document | Document management, databases |
| img | Image | Media handling, UI |
| btn | Button | UI contexts only -- never in backend code |
| info | Information | Only as part of a compound: userInfo, errorInfo -- never standalone |
info as a standalone name is banned. See the naming-precision skill. info is only acceptable as a suffix in a compound where the first word provides the specificity: errorInfo, connectionInfo.
This is the definitive test for any abbreviation not on the universally understood list.
If a competent developer joining your team today would need to ask "what does this mean?" when reading the code, the abbreviation is unacceptable.
| Abbreviation | Passes? | Why |
|-------------|---------|-----|
| url | Yes | Every developer knows this |
| config | Yes | Universal in software |
| btn | Yes (UI) / No (backend) | UI developers know it; backend developers may not |
| txn | Borderline | Common in financial codebases, obscure elsewhere. Document it. |
| svc | No | Write service |
| mgr | No | Write manager (then rename to something precise -- see naming-precision) |
| impl | No | Write implementation or, better, name what it implements |
| repo | Borderline | Common in DDD codebases. Document it or write repository. |
| util | No | Write nothing -- split the utility into specific modules |
| acct | No | Write account |
| addr | No | Write address |
| amt | No | Write amount |
| attr | No | Write attribute |
| calc | No | Write calculate or calculation |
| cb | No | Write callback |
| cmd | Borderline | Common in CLI contexts. Write command elsewhere. |
| coll | No | Write collection |
| desc | No | Write description |
| dest | No | Write destination -- or use the approved dst |
| dict | Borderline | Python: dict is the type name, fine. Elsewhere: write dictionary or map. |
| fmt | Go only | Go's fmt package makes this idiomatic in Go. Write format elsewhere. |
| idx | Borderline | Write index. i is fine for loop counters. |
| lbl | No | Write label |
| lib | Borderline | Common in build systems. Write library in application code. |
| obj | No | Name the actual thing. See naming-precision. |
| pkg | Go only | Go convention. Write package elsewhere. |
| ptr | Go/C only | Idiomatic in systems languages. Write pointer in high-level code. |
| ref | No | Write reference |
| str | Borderline | Python: str is the type name. Elsewhere: write string. |
| tbl | No | Write table |
| val | No | Write value -- then rename to something specific. See naming-precision. |
This rule supersedes all others. If you use an abbreviation once, you use it everywhere. If you spell it out once, you spell it out everywhere.
# UNACCEPTABLE: message in one place, msg in another
def send_message(message: str) -> None:
log.info(f"Sending msg: {message}") # msg vs message
queue.publish(msg=message) # msg parameter
track_event("message_sent") # message in event name
# CORRECT: pick one form and use it everywhere
def send_message(message: str) -> None:
log.info(f"Sending message: {message}")
queue.publish(message=message)
track_event("message_sent")
// UNACCEPTABLE: button in component names, btn in props and handlers
function SubmitButton({ btnText, onBtnClick }: SubmitButtonProps) {
return <button onClick={onBtnClick}>{btnText}</button>;
}
// CORRECT: one form throughout
function SubmitButton({ buttonText, onButtonClick }: SubmitButtonProps) {
return <button onClick={onButtonClick}>{buttonText}</button>;
}
// UNACCEPTABLE: request in one function, req in another
func HandleRequest(request *http.Request) { ... }
func validateReq(req *http.Request) error { ... }
func logRequest(request *http.Request) { ... }
// CORRECT: pick one -- in Go handler code, req is idiomatic
func HandleRequest(req *http.Request) { ... }
func validateRequest(req *http.Request) error { ... }
func logRequest(req *http.Request) { ... }
Cross-file consistency is mandatory. If user_service.py uses message and notification_service.py uses msg, the codebase is inconsistent. Grep the codebase. Pick one. Change all occurrences.
For any abbreviation that is not universally understood but is widely used in your domain, maintain an explicit registry. This is a file in your repository -- not a wiki, not a Confluence page, not tribal knowledge.
# Abbreviation Registry
These abbreviations are approved for use throughout this codebase.
Using the full form is also acceptable. Mixing forms is not.
| Abbreviation | Full Form | Context |
|-------------|-----------------|--------------------------------|
| `txn` | transaction | Payment processing, ledger |
| `repo` | repository | Data access layer |
| `sku` | stock keeping unit | Inventory, catalog |
| `qty` | quantity | Orders, inventory |
| `amt` | amount | Financial calculations |
| `org` | organization | Multi-tenancy |
Rules for the registry:
ABBREVIATIONS.md or a section in CONTRIBUTING.md)Multi-letter acronyms follow language-specific casing rules. These are covered in detail in the casing-law skill, but the abbreviation-relevant summary is:
| Language | Rule | Example |
|----------|------|---------|
| Python | Treat as a word in PascalCase | HttpClient, JsonParser, UrlValidator |
| TypeScript | Treat as a word in PascalCase/camelCase | HttpClient, jsonParser, urlValidator |
| Go | Keep well-known acronyms uppercase | HTTPClient, JSONParser, URLValidator |
Two-letter acronyms are a special case:
Id, Ip, Io in PascalCaseID, IP, IORefer to the casing-law skill for the complete acronym list and handling rules.
# BAD: Inconsistent abbreviations, unapproved short forms
def calc_ttl_amt(txn_lst, disc_pct):
ttl = 0
for txn in txn_lst:
ttl += txn.amt - (txn.amt * disc_pct / 100)
return ttl
usr_acct = get_usr_acct(acct_id)
btn_clr = get_btn_clr(theme)
addr_str = fmt_addr(usr_acct.addr)
# GOOD: Full words, clear meaning
def calculate_total_amount(
transactions: list[Transaction],
discount_percent: float,
) -> float:
total = 0.0
for transaction in transactions:
total += transaction.amount - (transaction.amount * discount_percent / 100)
return total
user_account = get_user_account(account_id)
button_color = get_button_color(theme)
formatted_address = format_address(user_account.address)
// BAD: Abbreviated everything, impossible to read without a decoder ring
interface UsrAcct {
acctId: string;
dispNm: string;
regDt: Date;
lstLoginTs: number;
emailAddr: string;
numOrds: number;
}
function updUsrAcctInfo(acctId: string, updData: Partial<UsrAcct>): void { ... }
function getAcctOrds(acctId: string, pgNum: number, pgSz: number): OrdLst { ... }
// GOOD: Full words, instantly readable
interface UserAccount {
accountId: string;
displayName: string;
registrationDate: Date;
lastLoginTimestamp: number;
emailAddress: string;
orderCount: number;
}
function updateUserAccountInfo(accountId: string, updates: Partial<UserAccount>): void { ... }
function getAccountOrders(accountId: string, pageNumber: number, pageSize: number): OrderList { ... }
// BAD: Over-abbreviated, unclear
func ProcMsg(ctx context.Context, msg *Msg) (*Resp, error) {
v := validateMsg(msg)
if v != nil {
return nil, v
}
r, err := svc.SendMsg(ctx, msg)
if err != nil {
return nil, fmt.Errorf("snd msg: %w", err)
}
return r, nil
}
// GOOD: Approved abbreviations only (ctx, msg, err), rest spelled out
func ProcessMessage(ctx context.Context, message *Message) (*MessageResponse, error) {
validationErr := validateMessage(message)
if validationErr != nil {
return nil, validationErr
}
response, err := messageService.SendMessage(ctx, message)
if err != nil {
return nil, fmt.Errorf("send message: %w", err)
}
return response, nil
}
Working implementations in examples/:
examples/abbreviation-rules.md -- Multi-language examples showing consistent vs inconsistent abbreviation usage in Python, TypeScript, and Go, with a sample abbreviation registryWhen reviewing code for abbreviation policy compliance:
message is used anywhere, msg is not used in any other file (or vice versa)casing-law skill)info is never used as a standalone name -- only as part of a compound (errorInfo, connectionInfo)btn is only used in UI-layer code, never in backend or business logictmp is only used for genuinely temporary values with a lifespan of a few linestxn, sku, qty) are documented in the project's abbreviation registryacct, addr, calc, desc, lbl, tbl, val) unless explicitly approved and registeredtools
This skill should be used when the user invokes any /plan-* command from the planning-tools plugin (/plan-context, /plan-master, /plan-open-questions, /plan-verify, /plan-tick, /plan-progress, /plan-delete), asks how Claude Code's plan files work, asks where plans are stored, asks to author or audit a multi-phase master planning document, asks how to walk through a plan's Open Questions interactively, asks how to write progress entries, or mentions ~/.claude/plans/ or .claude/planning-tools.local.md. Provides the index of planning-tools commands, the master-plan workflow lifecycle, the v0.3.0+ list-shape mandate (phases and questions as headings + bulleted scope items, never tables), the v0.3.2+ plain-bullet shape (no `- [ ]` checkboxes — heading emoji is the sole tick signal), the progress-entry methodology, and the mechanics of Claude Code's plan-mode file storage.
testing
This skill should be used by the plan-verifier agent and the /plan-verify command to audit a drafted master plan against a fixed checklist. Covers universal-core completeness, the v0.3.0+ no-tables-for-phases-or-questions rule, trigger-based section-coverage gaps, phase actionability (heading + per-phase TL;DR + bulleted scope + exit criteria), the v0.3.1+ per-phase TL;DR requirement, the v0.3.2+ plain-bullet scope shape (legacy `- [ ]`/`- [x]` accepted silently), the v0.3.3+ context-block shape (plan-level `**TL;DR:**` + bulleted metadata, legacy `>` blockquote accepted silently), integer phase numbering enforcement, dependency traceability, citation resolution, callout/evidence convention compliance, Open Questions placement, and the one-PR-per-master-plan rule. Single-owner of the audit checklist.
tools
This skill should be used when authoring, reviewing, or modifying a multi-phase master planning document via the planning-tools plugin (especially the /plan-master and /plan-verify commands). Codifies the universal core sections, trigger-based optional sections, integer-only phase numbering, Open Questions placement, one-PR-per-plan rule, status conventions, evidence attribution, callouts, cross-reference formats, the v0.3.0 list-shape mandate (phases and questions are heading + bulleted list, never markdown tables), the v0.3.1 per-phase TL;DR requirement (1–3 sentence what/why summary under each phase heading for glance-ability), the v0.3.2 plain-bullet scope shape (`- <action>` items, no `- [ ]` checkboxes — the phase status emoji is the sole tick signal), and the v0.3.3 context-block shape (a plan-level `**TL;DR:**` + a bulleted metadata list instead of a `>` blockquote; legacy blockquote blocks accepted silently). Project-agnostic — no ticket-prefix or plan-type taxonomy.
testing
This skill should be used when the user is adjusting spacing, padding, margins, content density, section gaps, vertical rhythm, or separation between elements. Also applies when reviewing whether a design feels cramped or too sparse, choosing between borders and whitespace for separation, or defining a spacing system. Covers the 4px/8px spacing system, macro vs micro whitespace, content density spectrum, separation techniques (whitespace > background shifts > borders), and vertical rhythm.