FlagArgumentDetector: a method whose ENTIRE body is `if ($flag) {…} else {…}` (or a
two-armed `match`) on one of its own bool parameters. Two methods sharing a name, and a
call site that reads `render($order, true)` — true what?
New skill backend/behaviour-per-method teaches the split. None of the existing skills
fit: the fix names two methods, it does not flatten flow, so filing it under
guard-clauses would have pointed readers at the wrong lesson.
Three restrictions, each one a false positive that calibration or the fixture caught:
- The branch must be the WHOLE body. A method with a job and a conditional in it is not
itself the conditional.
- The condition must be the flag alone. `if ($compact && $rows !== '')` is the method
reasoning, not obeying.
- Both arms must DO something. Two arms returning different constants are a mapping
from a bool to a value, and an arm exiting with a bare constant is a guard answering
a precondition — the fixture's AccessLevel, where the redundant `else` is the sin.
The ternary form is deliberately excluded, and that is load-bearing: including it would
have flagged `Option::when(bool, callable) => $condition ? $factory() : none()` and
`BoolEnum::fromBool() => $value ? self::True : self::False` — a combinator whose flag is
the whole API, and a pure conversion. Both would be plainly wrong.
Calibrated over 7 trees: no false positives. Worth recording that this pattern, like
computed-boolean-argument, did not occur in any of them — 47 and 30 bool-param methods,
20 and 10 branching on the flag, none where the body IS the branch. Guard-clause style
(which this codebase teaches) makes the explicit-else form rare.