agentleFS
AnyOrgNameAnyOrgName/php-skills/skills/phpstan/baseline/SKILL.md

baseline

Skill4 starsChanged 4 months agoMITView on GitHub

Adopt PHPStan on a legacy codebase without fixing everything at once — generate a baseline, include phpstan-baseline.neon, keep new code error-free, and shrink the baseline over time while enforcing it in CI. Use when the user wants to adopt PHPStan on an existing legacy codebase that already has many type errors, without blocking on a full cleanup; the user wants to generate a PHPStan baseline to snapshot existing errors so a new level can pass without fixing everything first; the user wants to shrink the PHPStan baseline over time, or keep it from growing, as they pay down type debt. Keywords: phpstan, baseline, legacy, static-analysis, ci.

3 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

8 rules. 0 are common, 4 are distinctive, and 4 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 4

    Distinctive

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Do not generate a baseline for a new or already-green codebase.

    line 66
  2. Very specific:

    Do not use a baseline to permanently silence a rule you never intend to fix.

    line 68
  3. Very specific:

    Add includes: [phpstan-baseline.neon] to phpstan.neon, then commit both files so the frozen errors apply everywhere.

    line 84
  4. Very specific:

    Run plain phpstan analyse in CI so new errors fail.

    line 86
  5. Distinctive:

    When raising the analysis level, regenerate the baseline once to absorb the new level's pre-existing errors, then hold it steady until the …

    line 91
  6. Very specific:

    Keep parameters.reportUnmatchedIgnoredErrors: true (the default) so PHPStan flags baseline entries that no longer match, prompting you to …

    line 93
  7. Distinctive:

    Treat the baseline as debt to pay down: fix baselined errors in files you already touch, then regenerate so removed errors drop out and the …

    line 95
  8. Distinctive:

    Not applicable — no I/O, auth, or untrusted input.

    line 130

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md
<!-- generated: do not edit — source: knowledge/atoms/phpstan/baseline/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->

PHPStan Baseline

When to use

  • The user wants to adopt PHPStan on an existing legacy codebase that already has many type errors, without blocking on a full cleanup.
  • The user wants to generate a PHPStan baseline to snapshot existing errors so a new level can pass without fixing everything first.
  • The user wants to shrink the PHPStan baseline over time, or keep it from growing, as they pay down type debt.

When NOT to use

  • Do not generate a baseline for a new or already-green codebase; fix the handful of errors directly instead of freezing them.
  • Do not use a baseline to permanently silence a rule you never intend to fix; use a scoped ignoreErrors entry for a deliberate, documented exception.

Core guidance

  • Generate the baseline with generate-baseline — Create the baseline with vendor/bin/phpstan analyse --generate-baseline, which writes a phpstan-baseline.neon listing every current error.
  • Include the baseline from phpstan.neon — Add includes: [phpstan-baseline.neon] to your phpstan.neon so the baselined errors are ignored on every run and commit both files.
  • Enforce zero new errors in CI, never regenerate to hide them — In CI run phpstan analyse (no --generate-baseline) so new errors fail the build; only regenerate the baseline in a deliberate, reviewed commit.

Quick recipe

  1. Set the target level in phpstan.neon, then run vendor/bin/phpstan analyse --generate-baseline to snapshot current errors. (verify: A phpstan-baseline.neon file is written listing the existing errors.)
  2. Add includes: [phpstan-baseline.neon] to phpstan.neon, then commit both files so the frozen errors apply everywhere. (verify: A fresh vendor/bin/phpstan analyse now exits 0.)
  3. Run plain phpstan analyse in CI so new errors fail; as you touch legacy files, fix their baselined errors and regenerate so the baseline only shrinks. (verify: CI fails on a newly introduced error and the baseline count trends downward.)

Best practices

  • When raising the analysis level, regenerate the baseline once to absorb the new level's pre-existing errors, then hold it steady until the next planned bump
  • Keep parameters.reportUnmatchedIgnoredErrors: true (the default) so PHPStan flags baseline entries that no longer match, prompting you to regenerate and drop them
  • Treat the baseline as debt to pay down: fix baselined errors in files you already touch, then regenerate so removed errors drop out and the file only shrinks

Anti-patterns

Anti-patternWhy it failsDo instead
Baselining everything to claim a high levelA huge baseline at max level means almost no real code is actually analysed at that<br>level; the badge is misleading and new code still slips through.Raise the level in steps, fixing errors at each step, and keep the baseline small<br>so the reported level reflects real coverage.
Gitignoring the baseline fileIf the baseline is untracked, CI has nothing to include, so either analysis fails<br>everywhere or each machine regenerates a different baseline and results diverge.Commit phpstan-baseline.neon alongside phpstan.neon so every environment<br>freezes the same set of errors.
Regenerating the baseline to make CI greenRegenerating absorbs the new error into the baseline, so the very bug analysis<br>caught ships silently and the baseline grows instead of shrinking.Fix the new error in the PR; reserve baseline regeneration for deliberate,<br>reviewed events like a level bump.

See references/anti-patterns.md.

Common mistakes

  1. Baseline generated but never included — You run --generate-baseline, commit phpstan-baseline.neon, but analysis still reports all the old errors. Fix: Add includes: [phpstan-baseline.neon] to phpstan.neon and rerun the analysis.
  2. Baseline entries drift when lines shift — Editing a baselined file shifts line numbers so a frozen error resurfaces or an unrelated one gets swallowed, producing confusing CI diffs. Fix: Regenerate the baseline after substantial edits to a legacy file, or fix that file's baselined errors while you are in it so the entries disappear cleanly.
  3. Baseline file causes constant merge conflicts — A single large phpstan-baseline.neon conflicts on almost every branch because many PRs regenerate overlapping regions of it. Fix: Discourage per-PR regeneration (only regenerate on level bumps), or split the baseline per top-level directory via multiple included files to localize churn.

Version notes

  • Baseline format and PHP 7.4 through 8.4 support (PHP >=7.4) — --generate-baseline writes a neon file by default; PHPStan can also emit PHP or JSON baselines via --generate-baseline=phpstan-baseline.php, and the feature works identically across PHP 7.4 through 8.4.
  • reportUnmatchedIgnoredErrors defaults on in PHPStan 2.x (PHP >=7.4) — In PHPStan 2.x reportUnmatchedIgnoredErrors defaults to true, so baseline entries that no longer match cause a failure until you regenerate; older versions were more lenient about stale entries.

Security

  • Not applicable — no I/O, auth, or untrusted input.

Testing

  • Activation and decision behavior are verified in eval/scenarios/phpstan/baseline.yaml.

Additional resources

  • references/anti-patterns.md
  • references/core.md
  • references/examples.md
  • references/pitfalls.md
  • references/recipes.md
  • references/version-differences.md

Knowledge graph

Prerequisites: phpstan/getting-started

<!-- graph-fragment: graph/fragments/phpstan/baseline.yaml -->

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.