SKILL.md 4.7 KB


name: coding-standard-rules

description: "Mandatory coding standards (function size, naming, no magic values, guard clauses, error handling, secrets, code reuse, comments). Use whenever writing, editing, refactoring, or reviewing source code in any language, even one-line changes; load it before writing the first line of code."

Code Writing Rules

[!IMPORTANT] Apply these rules by default. Do not violate them silently: if one conflicts with the task or the existing codebase, explain the conflict before proceeding.

Basics

The principle is to write simple code, human-readable, yet functional and modern.

  • Every function does one thing only (Single Responsibility Principle)
  • Ideally few lines (roughly under 20-30); if it grows too much, split it
  • Few parameters (ideally ≤ 3-4); beyond that, use an object/struct
  • Files and folders organized by domain/feature, not arbitrarily
  • Separation of concerns (e.g. business logic separated from presentation and data access)
  • Avoid duplication (DRY principle - Don't Repeat Yourself)
  • KISS (Keep It Simple, Stupid): no over-engineering or complex patterns unless truly needed
  • YAGNI (You Aren't Gonna Need It): don't add "future-proof" features unless requested

Syntax

  • Prefer concise syntax where it improves readability: elvis ?:, ternary, null coalescing ??, optional chaining
  • Do not create classes, interfaces or traits that contain a single function: use a standalone function, a static method on an existing class, or write the method in the current class
  • Prefer pure functions and direct composition over structural patterns (Factory, Strategy, etc.) — use them only if the complexity truly justifies it
  • Descriptive names without abbreviations; avoid redundant prefixes (e.g. $userManager->getUserData() → $users->get())
  • No magic values: any literal number or string with a specific meaning (thresholds, status codes, fixed strings used in comparisons, timeouts, etc.) must be extracted into a named constant declared at the top of the file/class. Trivial values with no ambiguity (0, 1, -1 used as neutral/increment, empty string checks) are exempt. Example:

    // Instead of:
    if ($user->status === 3) { ... }
    sleep(30);
    
    // Do:
    const STATUS_SUSPENDED = 3;
    const RETRY_DELAY_SECONDS = 30;
    
    if ($user->status === STATUS_SUSPENDED) { ... }
    sleep(RETRY_DELAY_SECONDS);
    
  • Merge guard clauses that lead to the same outcome into a single condition instead of multiple identical exit points. This applies to any repeated body, not just return — including identical throw, error logging, or early-exit blocks. Example:

    // Instead of:
    if ($a) return null;
    if ($b) return null;
    
    if ($x === null) throw new InvalidArgumentException('x missing');
    if ($y === null) throw new InvalidArgumentException('x missing');
    
    // Do:
    if ($a || $b) return null;
    
    if ($x === null || $y === null) throw new InvalidArgumentException('x missing');
    

If the guards throw/log different messages depending on which condition failed, keep them separate — do not merge conditions that would lose information.

Naming conventions

  • Use consistent case style per language convention (e.g. camelCase for variables/methods in PHP/JS, snake_case for variables in Python, PascalCase for classes)
  • Do not mix styles within the same file or codebase

Error handling

  • Never silently swallow an exception/error (empty catch block, ignored return code)
  • Catch only the specific exception types you can meaningfully handle; let unexpected ones propagate
  • Log errors with enough context (input, operation, expected vs actual) to debug without reproducing

Configuration and secrets

  • No credentials, API keys, hostnames, or environment-specific paths hardcoded in source
  • Use environment variables or a config/secret manager; source code must be identical across environments

Code reuse

  • Before creating a new function, check if an existing one covers the same core logic with overlapping parameters and no additional side effects — if so, refactor it instead of duplicating
  • The refactor must not introduce breaking changes: the original public signature must remain unchanged and all previous consumers must continue to work without modifications
  • After any refactor, explicitly verify that the original public method signature is unchanged by showing the before/after diff of the signature

Code Comments

  • Comment every function with its purpose, inputs, output, and side effects.
  • No comments that just restate the obvious
  • Add a comment before a logical block only when its intent isn't clear from the code itself (e.g. non-obvious business rules, workarounds, non-trivial algorithmic steps)
  • Place one blank line before every comment to keep code readable and maintainable