A baseline that can grow is a suppression file, and a baseline that can only shrink is a debt that gets paid — the difference is one CI step.
#!/usr/bin/env bash
set -euo pipefail
vendor/bin/phpstan analyse --no-progress # fails on anything NEW
# and the check that stops the baseline being regenerated larger
before=$(git show origin/master:phpstan-baseline.neon | grep -c 'message:')
after=$(grep -c 'message:' phpstan-baseline.neon)
[ "$after" -le "$before" ] || {
echo "baseline grew: $before → $after"; exit 1;
}
The first command alone is most of the value: new code is analysed at the chosen level and old code is ignored, so the analyser is useful from the first day. The second is what stops somebody regenerating the baseline to make a build pass, which is the obvious workaround and is always available. Reporting the two numbers in the build output makes the trend visible without anybody having to look for it.