# Coding Standards

## Purpose

This document defines implementation conventions for production code and tests. It complements the architectural rules without redefining layer ownership.

## Naming Conventions

- Use names that describe responsibility and domain meaning.
- Name interfaces as capabilities or contracts, not implementation details.
- Name immutable outcomes and states with precise nouns or past-tense results.
- Use established protocol terminology for protocol fields and commands.
- Avoid generic names such as `Manager`, `Helper`, or `Utils` unless the responsibility is genuinely precise.

## Class Organization

- Declare strict types in every PHP file.
- Keep one primary class, interface, or enum per file.
- Keep namespaces aligned with directory and architectural ownership.
- Prefer final classes unless extension is an explicit design requirement.
- Keep public surface areas minimal.
- Order imports and declarations consistently with Pint.

## Method Organization

- Methods must perform one coherent operation.
- Prefer short, explicit control flow over hidden mutation.
- Keep public methods near the top and private implementation details below them.
- Avoid boolean parameters when a typed state or separate operation expresses intent better.
- Never hide retries, loops, I/O, or state changes inside innocuous methods.

## Constructor Rules

- Constructors must establish complete invariants.
- Do not expose partially initialized objects.
- Validate related values together.
- Use named factories when distinct valid construction modes require different rules.
- Constructor defaults must be deterministic and safe.

## Readonly and Immutable Objects

- Use `readonly` for immutable models, results, snapshots, routes, and handlers where appropriate.
- Store immutable collaborators in readonly services where practical.
- Do not expose mutable collections from immutable objects.
- An immutable object must be valid at construction; readonly syntax is not sufficient by itself.

## Exception Policy

- Throw the exception type owned by the current boundary.
- Use stable, sanitized categories for expected validation and operational failures.
- Do not expose secrets, credentials, sensitive payloads, absolute paths, stack traces, or uncontrolled provider details.
- Catch exceptions only when translating, cleaning up, or applying an explicit policy.
- Never swallow a failure unless deterministic best-effort cleanup explicitly requires it.

## Validation Reuse

- Reuse existing validators, field limits, registries, command-length authorities, encoders, and state rules.
- Never duplicate protocol rules.
- Centralize shared validation at the boundary that owns the rule.
- Add new validation authority only when no existing authority correctly owns the rule.

## Dependency Injection

- Inject external behavior and replaceable policies through narrow contracts.
- Prefer constructor injection.
- Avoid service location and ambient global state.
- Provide defaults only when they preserve deterministic production composition.
- Prefer composition over duplication.

## Type Safety

- Use precise parameter, property, and return types.
- Use enums, value objects, and typed result interfaces for closed concepts.
- Avoid mixed values and unstructured arrays at public boundaries.
- Use union types only when each alternative has clear caller semantics.
- Preserve strict object identity when required by the architecture.

## Documentation Expectations

- Document non-obvious invariants, ownership, and protocol constraints.
- Use PHPDoc for collection shapes, templates, and information not expressible in PHP types.
- Do not add comments that merely repeat code.
- Keep project documentation synchronized with approved behavior.

## Testing Expectations

- Add focused, invariant, boundary, production-path, failure-path, and regression tests as applicable.
- Use real production composition with test doubles only at explicit boundaries.
- Assert meaningful outputs, identity, invocation counts, I/O counts, state, and cleanup.
- Use data providers for systematic cases.
- Ensure tests are deterministic and independent of external services unless explicitly designated as integration tests.

## Refactoring Rules

- Refactor only within approved scope.
- Do not combine unrelated cleanup with feature work.
- Preserve behavior with regression tests before structural change.
- Do not rename, relocate, or generalize stable components speculatively.
- Prefer the smallest change that satisfies the approved architecture.
- Never edit vendor files.
