# Consistent subcommand pattern

- **Pattern:** `ab-000641` (`cli-quality.command-structure.subcommand-pattern`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000641
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000641)

## Why it matters

Inconsistent subcommand naming destroys discoverability. When a user learns `user:create` exists, they expect `team:create` to follow the same pattern — if instead they find `createTeam` or `team_create`, they have to read the full help text for every resource. Mixed conventions (kebab-case for some commands, camelCase for others, snake_case for a third) signal an AI-assembled codebase where different sessions added commands without checking what already existed. Beyond user friction, ISO 25010:2011 maintainability.consistency flags this directly: inconsistent naming makes the surface area harder to test, document, and extend.

## Severity rationale

High because inconsistent naming breaks user mental models and makes every new command unpredictable, which directly degrades ISO 25010:2011 usability.learnability.

## Remediation

Pick one naming convention and apply it across every resource. Kebab-case with a `resource:verb` or `resource verb` pattern is the most common and shell-friendly:

```ts
// Good — consistent kebab-case CRUD across every resource
program.command('user:list')
program.command('user:get')
program.command('user:create')
program.command('user:delete')
program.command('team:list')
program.command('team:get')
program.command('team:create')
program.command('team:delete')
```

Audit all registered commands with `mytool --help` and `mytool <resource> --help`. If you find `listUsers`, `delete_token`, and `create-session` coexisting in the same binary, rename them in a single pass before the CLI is published. Aliases (`program.alias()`) can bridge old names during a migration period.

## Detection

- **ID:** `subcommand-pattern`
- **Severity:** `high`
- **What to look for:** Enumerate every subcommand registered in the CLI. For each subcommand, examine all registered commands for naming consistency. Check that subcommands follow a consistent naming convention (all kebab-case like `create-user` or all single-word like `create`). Check that the command hierarchy is consistent (e.g., if one resource has `list`/`get`/`create`/`delete`, others follow the same pattern). Look for orphaned commands that don't fit the pattern.
- **Pass criteria:** Subcommand names use a consistent casing convention (kebab-case preferred). Resource-oriented commands follow a consistent verb pattern. No commands are confusingly named or redundant (e.g., both `remove` and `delete` for the same concept) — 100% of subcommands must use consistent kebab-case or camelCase naming. Report: "X subcommands found, all Y follow consistent naming conventions."
- **Fail criteria:** Mixed naming conventions (some kebab-case, some camelCase, some snake_case), or inconsistent verb patterns across resources, or redundant commands with different names for the same action.
- **Skip (N/A) when:** The CLI has only a single command (no subcommands) — there is no pattern to evaluate. All checks skip when no CLI entry point is detected.
- **Cross-reference:** The `help-flag` check verifies each subcommand responds to --help.
- **Detail on fail:** `"Mixed naming: 'create-user' (kebab-case) but 'listUsers' (camelCase) and 'delete_token' (snake_case)"` or `"Users resource has list/get/create/delete but Teams resource only has 'teams' with no CRUD subcommands"`
- **Remediation:** Consistent naming helps users predict commands they haven't seen yet. Pick one convention and apply it everywhere:

  ```ts
  // Good — consistent kebab-case, consistent CRUD verbs
  program.command('user:list')    // or 'users list'
  program.command('user:get')
  program.command('user:create')
  program.command('user:delete')
  program.command('team:list')
  program.command('team:get')
  program.command('team:create')
  program.command('team:delete')
  ```

## External references

- iso-25010 usability.learnability
- iso-25010 maintainability.modularity

Taxons: user-experience, code-quality

HTML version: https://auditbuffet.com/patterns/ab-000641
