# 0031. No static analysis or formatter, for now

- **Status:** Accepted
- **Date:** 2026-08-08

## Context

The automated quality surface here is PHPUnit over a fourteen-file allowlist. There is no PHPStan, no
formatter, no mutation testing; [CODE_STYLE.md](../CODE_STYLE.md) is enforced by review alone.

The question came up as part of the documentation upgrade, backed by a worked-through php-cs-fixer
configuration for a nearly identical style. Both tools were considered and both were deferred.

## Decision

**Neither PHPStan nor a formatter is introduced now.** The findings are recorded here so they do not have to
be re-derived when the question returns.

**PHPStan** is the more valuable of the two — it finds defects, not formatting. Introducing it to an existing
codebase of this size is a task with its own plan: start at a low level with a baseline and raise it, never
at max. It is a code task, not part of the documentation set, and it is not started unasked.

**A formatter**, if it ever happens, has these constraints:

- **No preset.** `@Symfony` and `@PER-CS` encode the opposite of this style on several points; inheriting one
  means fighting it rule by rule, forever, across upgrades.
- **Mechanizable with stock rules:** `spaces_inside_parentheses` (`space: single`), `cast_spaces`
  (`space: none`), `unary_operator_spaces`, `no_spaces_after_function_name`, `function_declaration`
  (`closure_function_spacing: none`, `closure_fn_spacing: none`), `echo_tag_syntax` (`format: short`).
- **Not mechanizable — no stock rule exists:** spaces inside array offsets (`$row[ 'name' ]`), the missing
  space before a control structure's parenthesis (`if( $x )`), brace-less single-statement blocks, tight
  `<?=$value?>` echo tags. Several stock rules produce the *opposite* and must be explicitly disabled.
- **`ordered_imports` does not implement the `use` convention**, with any `sort_algorithm`. It sorts by the
  namespace string rather than the rendered line, alphabetizes group imports and regroups `use function`
  blocks; on a comparable codebase it wanted to rewrite six files. It is also deprecated, scheduled for
  removal in php-cs-fixer 4.0. This repository additionally requires `use Yii;` **first**, which no stock
  algorithm produces.
- **Exclude `views/`** — markup plus tight echo tags is what no stock fixer understands.
- **Acceptance test:** the config is correct when `php-cs-fixer check --diff` produces an **empty diff** on
  the current codebase. If it wants to change anything, the config is wrong, not the code.

## Alternatives

- **Adopting php-cs-fixer now, for the mechanizable subset.** It would cover perhaps half the style rules
  while the half that actually gets violated in review stays manual — and it adds a gate, a config file and
  an upgrade surface for that half.
- **PHPStan at max level with a large baseline.** A baseline that big is a list nobody reads, and the level
  can never be raised because every raise re-opens all of it.

## Consequences

- Style stays a review concern. That is a real cost and it is accepted knowingly.
- The findings above are captured here, so the next attempt starts from a working config sketch instead of
  from scratch.
- Superseding this ADR is the way to introduce either tool; each will need its own plan.
