Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changelog/legacy-fixer-comparison.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: changed
type: patch
---

Record resolved legacy fixer rules, options and loaded-source provenance without broadening the initial default policy.
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ for the exact local base/head before publication; do not claim remote CI evidenc
- [README.md](README.md): library/CLI adoption, explicit fix and tool scope.
- [Policy comparison](docs/policy.md): evidence, rule differences and extraction gates.
- [Resolved preset](docs/resolved-preset.md): compiled rules, golden contracts and dependency-update review.
- [Legacy fixer comparison](docs/legacy-fixer-comparison.md): fixed-source inventory, loaded dependencies and remaining profile decisions.
- [PHPDoc comparison](docs/phpdoc-comparison.md): actual custom-rule registration, source contracts and remaining golden decisions.
- [Static-analysis evaluation](docs/static-analysis-evaluation.md): candidate engines, whole-project analysis and unresolved domain ownership.
- [Architecture decision](docs/architecture.md): library/tool dependencies, CPX/autoload limits and bootstrap without circular prerequisites.
Expand Down
80 changes: 80 additions & 0 deletions docs/legacy-fixer-comparison.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Resolved legacy fixer comparison

This reference extends issue #5 with actual fixer instances at fixed source and
package references. It does not select a broader default profile or claim parity
with the DevTools Rector/PHPDoc pipeline. The initial non-risky preset stays the
default. No consumer migration follows from these results.

The [machine-readable inventory](reference/legacy-fixer-inventory.json) contains
every active fixer, fully resolved configuration including upstream defaults,
priority, reported risky flag, package reference and source-file SHA-256. Paths
are relative to source packages; no developer paths or credentials are included.
This is recorded evidence, not executable configuration or a consumer DSL.

## Reproduction boundaries

Three separate PHP 8.5.11 processes used one disposable Composer project declaring
PHP `^8.3`. No process loaded another tool's autoloader. Reflection verified each
loaded fixer against its own installation. Source commits are in the inventory.

CoiSA expanded `DefaultSet('')->getRules()` with native RuleSet/FixerFactory;
no header was supplied. DevTools loaded its actual ECS builder, booting the
ECS 13.0.4 LazyContainerFactory and compiler passes. Only cache location and
parallelism were redirected. Its additional Generic GitMergeConflictSniff is
outside the fixer counts. Code Standards booted its ECS 13.3.8 container/preset.
Configured fixer state was inspected after native normalization; null means
that fixer has no stored configuration property.

Both legacy checkouts have untracked local Composer locks. These local installs
are evidence, not published lockfiles or fresh-install reproducibility promises.
Reproduce the recorded package references in separate installations before
updating the inventory; do not combine dependency graphs. Verify source-file
hashes as well as package metadata.

The active DevTools fixer is **bundled PHP-CS-Fixer 3.92.4**, not its separately
installed root PHP-CS-Fixer 3.95.1. The active reference is
`9e7488b19403423e02e8403cc1eb596baf4673b0`. CoiSA and Code Standards load
PHP-CS-Fixer 3.95.27 (`1d0c68ee5f37446d8ad5970b82384cd1bb0a3317`). DevTools
also loads bundled Symplify Coding Standard 13.0.0
(`bd7c36af1e96eecd08cfcc0a772a19767aa02300`). Each rule records its real origin;
root metadata must not silently stand in for the loaded code.

## Observed deltas

| Profile | Active fixers | Reported risky |
| --- | ---: | ---: |
| CoiSA | 230 | 54 |
| DevTools ECS | 216 | 43 |
| Initial Code Standards | 48 | 0 |

The legacy profiles share 194 names; CoiSA has 36 additional rules and DevTools 22.
Seventeen shared names have different normalized configurations. All 48 initial
rules occur in DevTools; CoiSA lacks `visibility_required`. Membership does not
establish behavior equivalence across package versions.

Differences include PHPDoc alignment (CoiSA vertical, DevTools/Code Standards
left), typed-parameter annotation generation, strict types, empty loop layout,
PHPDoc ordering and trailing-comma elements. Both legacy profiles normalize
multiline arguments; Code Standards preserves blank lines between attributed
parameters with `on_multiline=ignore`, covered by its existing golden regression.

CoiSA enables author annotation removal, immutable DateTime conversion and
protected-to-private conversion. DevTools preserves author annotations and
mutable DateTime at this ECS stage, but still enables protected-to-private.
The initial preset preserves all three, as its goldens demonstrate. Upstream
`isRisky()` is metadata, not a guarantee of unchanged public API:
`protected_to_private` reports false despite changing visibility.

No header is active in the CoiSA snapshot because its header argument is empty.
A supplied header adds the PHPDoc `after_open` writer and year/range normalization.
DevTools' separate `.docheader`/PHPDoc pass has another placement contract.
Neither is part of the initial Code Standards default.

## Remaining decision

Keep #5 open for behavioral comparisons of the complete legacy pipeline,
header/year and Finder fixtures, actual override precedence and target-version
variations, plus a separately authorized choice of any opt-in profile. Rector
sets/custom rules are semantic work; optional Twig/magic-value and type-analysis
ownership remain independent. Do not broaden the default or regenerate this
inventory merely to silence a dependency-update failure.
7 changes: 6 additions & 1 deletion docs/policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ from blocked PR #376 or composer-installers #15 was executed or changed.
| Runtime | PHP 8.3+ contract | PHP ^8.3 | PHP ^8.3 |
| Consumer PHP target | Rector resolves Composer minimum | auto rules resolve minimum | No version-dependent migration sets |
| PHPDoc preservation | skips conversion, empty/redundant tags removal, global imports, general annotation removal | removes author; preserves empty return/package | Same six ECS skips as DevTools; left alignment |
| Extra risky policy | PHPUnit static calls self; missing typed params; refactoring sets | immutable date, private visibility, simplified null returns and migration | Deliberately absent pending separate profile/fixtures |
| Additional behavior | PHPUnit static calls self; missing typed params; refactoring sets | immutable date, private visibility, simplified null returns and migration | Deliberately absent pending separate profile/fixtures |
| Headers | `.docheader`, current year, after strict declaration | opening header extracted without executing config, updated year, after open | No automatic header rewrite |
| Scope | source resolver excludes generated/resources/public/vendor | consumer Finder, hidden files, VCS ignores, path exclusions | Tracked PHP/bin scope, same generated exclusions plus node_modules; symlinks rejected |
| Overrides | customize callback last | extraRules last | customize callback last; explicit config selection |
Expand All @@ -41,6 +41,11 @@ list and effective options for the locked version. Golden fixtures make style,
documentation/semantic preservation and second-pass stability reviewable. This
is a first bounded part of #5, not equivalence with the legacy engines.

The [resolved legacy fixer comparison](legacy-fixer-comparison.md) expands all
three actual fixer profiles with normalized options, reported risk, priority
and source hashes. It distinguishes bundled code from root Composer metadata
and keeps the remaining full-pipeline decisions explicit.

This is not a rule-by-rule equivalence proof for the complete
legacy ECS + Rector + PHPDoc stack. No consumers may be automatically migrated
on the strength of this comparison. Before migration, expand resolved rule lists,
Expand Down
Loading
Loading