PHP 8.2+ · VERSION-AWARE · READ-ONLY · VERIFY: PHPCOMPATIBILITY

Modern PHP guidance that respects the whole version range.

A policy and rule-query foundation for coding agents: understand the project's declared PHP compatibility before choosing newer syntax, APIs, deprecations, or replacements.

  • 81 source-backed rules in source
  • PHP 8.2–8.5 coverage
  • Real PHPCompatibility verify adapter

Why it exists

One Composer range needs two policy axes.

01

Feature ceiling

The lowest PHP minor that must remain supported. New syntax or APIs cannot silently raise the project's minimum requirement.

02

Lifecycle ceiling

The highest known PHP minor still inside the supported range. Newer deprecations and removals must not be ignored.

The resolver keeps these values separate instead of treating the developer's local runtime as the project's compatibility policy.

Shipped in v0.3.0 · hardened in v0.3.1 · expanded in v0.3.2 · expanded again in v0.3.3 · deepened in v0.3.4 · widened in v0.3.5 · re-measured in v0.3.6 · extended to behavior changes in v0.3.7 · confirmed again in v0.3.8 · new functions in v0.3.9

A real PHPCompatibility adapter reports advisory evidence.

Released: M2

  • resolve / list-rules / explain / doctor
  • 16 source-backed PHP 8.2–8.5 rules
  • Agent Skill + AGENTS.md wrapper
  • PHAR release asset + SHA-256

Released: M3

  • Real PHPCompatibility verify adapter
  • Canonical verification.schema.json
  • Exact policy projection, incl. single-target
  • Mapped and unmapped evidence model
  • Rule-local ordered mapping lists in schema 1.1.0
  • Deterministic top-level scan operands with exact root vendor/ exclusion
  • 80 source-backed rules, up from 72
  • 45 of 80 rules carry a proven sniff mapping, up from 37 of 72

Still not included

  • PHPStan deprecation adapter (deferred)
  • Rector dry-run advisory adapter (dropped)
  • Auto-fixing or target-project writes

v0.3.1 keeps verification narrow and truthful: the production phpcompatibility adapter uses exact rule mappings and explicit scan operands, excludes only the project root's own vendor/ directory, and never falls back to an unanchored ignore pattern that could produce a false clean.

Agent contract

Policy first, guidance second.

1 · Resolve

  • Read Composer compatibility declarations
  • Respect explicit platform constraints
  • Produce deterministic policy output

2 · Query

  • Filter rules by applicable PHP versions
  • Keep rule IDs and JSON output stable
  • Use authoritative PHP provenance

3 · Advise

  • Return small agent-readable guidance
  • Do not execute the target project
  • Do not modify target code by default

This resolve / query / advise flow is implemented and read-only: it reads composer.json and composer.lock only, and never executes or writes to the analyzed project.

Roadmap

Small, reviewable milestones with explicit boundaries.

  1. M0 · v0.0.1 (complete)Repository contracts, CLI skeleton, schemas, CI, ADRs, and static Pages source.
  2. M1 · v0.1.0 (complete)Implemented: Composer Semver resolver, two-axis policy, rule registry, the resolve / list-rules / explain commands, and 16 verified PHP seed rules.
  3. M2 · v0.2.0 (complete)Implemented: a Claude Agent Skill, a Codex-compatible AGENTS.md snippet, a CI-built PHAR attached to each release, and a bounded, read-only doctor diagnostic.
  4. M3 · v0.3.0 (complete)Implemented: the explicit verify surface and a real, policy-aware PHPCompatibility adapter reporting zero-mutation advisory evidence. A PHPStan deprecation adapter was deferred and a Rector dry-run adapter was dropped rather than broadening the product boundary.
  5. M3 patch · v0.3.1 (complete)Ordered rule-local PHPCompatibility mappings and deterministic vendor-safe scan scoping, closing issues #11, #12, and #14 without adding analyzer infrastructure.
  6. Rule-catalogue expansion · v0.3.2 (complete)Acted on the M3-B value gate finding directly: added 8 source-backed rules (16 → 24) and 12 proven PHPCompatibility sniff mappings (9 of 16 → 16 of 24 rules mapped), with no new adapter infrastructure.
  7. Further catalogue and mapping growth · v0.3.3 (complete)Added 8 more source-backed rules (24 → 32) and 25 proven PHPCompatibility sniff mappings (16 of 24 → 24 of 32 rules mapped), every one of the eight new rules shipping mapped, with no new adapter infrastructure.
  8. Catalogue depth over mapping breadth · v0.3.4 (complete)Added 8 more source-backed rules (32 → 40), all from issue #18's Tier B — candidates the analyzer produces no finding for at all — so every one ships unmapped and mapping coverage falls from 24 of 32 rules to 24 of 40, a deliberate, measured trade for catalogue depth rather than a regression.
  9. Emptying issue #18's Tier A · v0.3.5 (complete)Added the 8 remaining source-backed rules from issue #18's Tier A (40 → 48), every one shipping mapped, so mapping coverage rises from 24 of 40 rules (60%) to 32 of 48 (67%) — reversing the previous round's deliberate trade. Tier A, as bounded by analyzer-probed candidates, was believed exhausted; v0.3.6 found that incomplete.
  10. Re-measuring issue #18 from php-src · v0.3.6 (complete)Enumerating candidates from php-src UPGRADING first, rather than by probing the analyzer, found 13 uncovered Core/Standard deprecations (3 mappable) and disproved the "Tier A exhausted" claim. Ships 8 rules covering 9 of the 13 entries (48 → 56 rules), so mapping coverage falls from 32 of 48 rules (67%) to 35 of 56 (62%); 4 of the 13 gaps, all unmappable, remain open.
  11. Backward Incompatible Changes from php-src · v0.3.7 (complete)The first round drawn from UPGRADING's Backward Incompatible Changes section instead of Deprecated Functionality — behavior that silently changed rather than an API marked deprecated. Probing 18 candidates against the analyzer produced exactly 1 finding, so 7 of the 8 new rules (56 → 64 rules) ship unmapped and mapping coverage falls from 35 of 56 rules (62.5%) to 36 of 64 (56%), the steepest of three deliberate breadth-for-depth trades. Measured directly against php-src, catalogue coverage of the 36 Core/Standard Backward Incompatible Changes entries in 8.2–8.5 rises from 2 to 11, because the eight rules cover 9 of those entries (one rule counts twice); 25 remain uncovered.
  12. Second Backward Incompatible Changes round · v0.3.8 (complete)The second round drawn from UPGRADING's Backward Incompatible Changes section. Probing 16 more candidates against the analyzer again produced exactly 1 finding, confirming the pattern v0.3.7 first observed rather than sampling noise, so 7 of the 8 new rules (64 → 72 rules) ship unmapped and mapping coverage falls from 36 of 64 rules (56%) to 37 of 72 (51%), the fourth deliberate breadth-for-depth trade and the deepest yet. Measured directly against php-src, catalogue coverage of the 36 Core/Standard Backward Incompatible Changes entries in 8.2–8.5 rises from 11 to 19, because the eight rules cover 8 of those entries, one each; 17 remain uncovered.
  13. New Functions from php-src · v0.3.9 (complete)The first round drawn from UPGRADING's New Functions sections rather than Deprecated Functionality or Backward Incompatible Changes — a section PHPCompatibility was built to answer rather than one it is structurally blind to. All 8 new rules (72 → 80 rules) ship mapped, so mapping coverage rises for the first time since v0.3.5, from 37 of 72 rules (51.4%) to 45 of 80 (56.25%), ending three consecutive falls and landing back at the v0.3.7 level. SNIFF_RULE_MAP gains 15 sniff ids. The seam is overwhelmingly extension-scoped — of 54 open entries only 3 are Core/Standard — so category: extension nearly doubles, 7 to 13; this round also records three measured defects in the pinned analyzer's own data, the first findings calling it wrong rather than merely blind.
  14. Next · further catalogue and mapping growthMapping coverage in the current source checkout covers 46 of 81 rules, so growing further source-backed PHP rules and their proven mappings — including the 4 still-uncovered Deprecated Functionality gaps, the 17 still-uncovered Backward Incompatible Changes Core/Standard entries, and the 51 still-open, extension-scoped New Functions entries this round found — stays ahead of the deferred M3-C PHPStan adapter and the dropped M3-D Rector adapter.
  15. M4 · v0.4.xIsolated framework rule packs without mixing framework conventions into PHP Core policy.

Trust boundary

Designed to advise, not to act on your project.

Core commands are deterministic and read-only: no target PHP execution, no analyzed-project vendor/autoload.php, no Composer scripts or plugins, no network requirement for core resolution, and no writes to the analyzed repository.

The verify surface keeps verification explicit and zero-mutation. It never installs an analyzer, never accepts arbitrary analyzer arguments, preserves unsupported policies and unmapped findings, and its production PHPCompatibility adapter runs only as an isolated child process, tested to leave the target tree byte-identical on every path.

PHP language, Core, and bundled-extension facts must be backed by authoritative PHP sources and a review date. If a fact cannot be established, the project should leave the rule absent or explicitly uncertain rather than guess.

Primary inspiration: JetBrains/go-modern-guidelines. Modern PHP Guidelines is an independent implementation and is not affiliated with or endorsed by JetBrains. Its narrow version-policy focus is also distinct from netresearch/php-modernization-skill.