diff --git a/.changelog/source-analysis-boundaries.md b/.changelog/source-analysis-boundaries.md new file mode 100644 index 0000000..1740aab --- /dev/null +++ b/.changelog/source-analysis-boundaries.md @@ -0,0 +1,7 @@ +--- +category: changed +type: patch +--- + +Documents the legacy PHPDoc rule activation and future analyzer boundaries, +including native whole-project PHPStan scope, without enabling new policies. diff --git a/AGENTS.md b/AGENTS.md index 88037c4..2fd31bc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -61,6 +61,8 @@ 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. +- [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. - [Automation](docs/automation.md): trust, ref/bootstrap contracts and consumer adoption. - [Instruction map](docs/instruction-map.md): single root scope and skill ownership. diff --git a/docs/phpdoc-comparison.md b/docs/phpdoc-comparison.md new file mode 100644 index 0000000..5a9b0e9 --- /dev/null +++ b/docs/phpdoc-comparison.md @@ -0,0 +1,55 @@ +# Source PHPDoc: legacy rules and extraction boundary + +Fixed DevTools source `35b5f78ac63813ec07aa3fb3eda08751541e28e1`; source inventory +for extraction planning. These observations do not establish runtime parity. +Potential edge cases below are future fixture requirements, not reproduced bugs +or an adopted rule profile. + +## Registration matters + +There are three custom classes, but they are not all enabled by the inspected +default. `Config/RectorConfig::DEFAULT_RULES` registers +AddMissingMethodPhpDocRector and RemoveEmptyDocBlockRector, plus external Faker +GeneratorPropertyFetchToMethodCallRector. AddMissingClassPhpDocRector exists but +is absent from that default list. Do not equate class presence with activation. + +The config also enables broad DEAD_CODE/CODE_QUALITY/CODING_STYLE/ +TYPE_DECLARATION/PRIVATIZATION/INSTANCEOF/EARLY_RETURN sets, derives PHP migration +sets from consumer Composer, enables name import/removal, and conditionally loads +Safe migrations. These effects must not come along implicitly with a PHPDoc +extraction. Customization runs last in the native Rector callback. + +## Observed class contracts + +| Class | Inspected behavior | Required future goldens before selecting policy | +| --- | --- | --- | +| AddMissingClassPhpDocRector | Targets Class_ only, skips any existing Doc; generates class-name summary and namespace @package when available | Named/anonymous/namespaced classes; preserve useful existing prose/tags; choose whether generated boilerplate adds useful human information | +| AddMissingMethodPhpDocRector | Targets ClassMethod; skips the entire method when any Doc exists; creates @param from native types or mixed, @return except constructors, and @throws from literal new named exceptions found recursively | Existing partial docs vs absent docs, typed/untyped/nullable/union/intersection/DNF, variadic/reference parameters, constructors, abstract methods, nested closures and exception-name imports | +| RemoveEmptyDocBlockRector | Targets Class_/ClassMethod only; removes whitespace/star-only Doc; preserves other comment objects and clears Rector/AST doc attributes | Empty vs meaningful prose/tags, other comments, declaration docs on interfaces/traits/enums and docs on properties/functions outside this target set, methods inside interfaces/traits/enums still targeted as ClassMethod, repeated passes and native Rector cache/API compatibility | + +These observations derive from the exact source, not generated example output. +In particular, the method rule does not fill missing tags in an existing partial +docblock, despite a broad reading of its description. Recursive throw traversal +and type rendering require dedicated fixture decisions; no unsupported claim of +precise escaping-exception inference or all-syntax correctness is made here. + +## Extraction boundary + +The initial Code Standards preset preserves existing PHPDoc and does not promise +useful documentation generation by restating syntax. Select human-useful policy +before copying any algorithm. Keep any later semantic operation explicit, +opt-in and target-PHP aware, separate from default check/fix. Reuse native APIs +and focused services rather than importing legacy broad configuration or a DSL. + +Future comparative goldens must isolate each selected rule first, then test the +selected combined ordering against ECS. Assert source-readonly check, explicit +write/second-pass idempotence, exact exits, comments/attribute spacing and config +override precedence. Do not execute automatic Safe/Faker/PHP migrations as part +of that PHPDoc comparison. Detailed engine compatibility and behavior remain +unverified; this inventory does not close issue5 or issue4. + +Immutable source links: +- https://github.com/php-fast-forward/dev-tools/blob/35b5f78ac63813ec07aa3fb3eda08751541e28e1/src/Config/RectorConfig.php +- https://github.com/php-fast-forward/dev-tools/blob/35b5f78ac63813ec07aa3fb3eda08751541e28e1/src/Rector/AddMissingClassPhpDocRector.php +- https://github.com/php-fast-forward/dev-tools/blob/35b5f78ac63813ec07aa3fb3eda08751541e28e1/src/Rector/AddMissingMethodPhpDocRector.php +- https://github.com/php-fast-forward/dev-tools/blob/35b5f78ac63813ec07aa3fb3eda08751541e28e1/src/Rector/RemoveEmptyDocBlockRector.php diff --git a/docs/policy.md b/docs/policy.md index e7aa4b7..846fbc3 100644 --- a/docs/policy.md +++ b/docs/policy.md @@ -46,3 +46,8 @@ Composer metadata normalization and existing public DevTools APIs stay untouched Static quality in this first increment means parseable PHP and formatting conformance. Type analysis, dead-code analysis and semantic refactors are not claimed. Application tests, coverage and complete reports remain outside this domain. + +The [PHPDoc comparison](phpdoc-comparison.md) records actual custom Rector +activation and the fixtures required before adopting a documentation policy. +The [static-analysis evaluation](static-analysis-evaluation.md) distinguishes +candidate engines and their analysis scopes without deciding domain ownership. diff --git a/docs/static-analysis-evaluation.md b/docs/static-analysis-evaluation.md new file mode 100644 index 0000000..1d924d6 --- /dev/null +++ b/docs/static-analysis-evaluation.md @@ -0,0 +1,80 @@ +# Static analysis: candidates and ownership boundary + +This source comparison records candidates without deciding ownership or +implementing an analyzer. DevTools issues +[#14](https://github.com/php-fast-forward/dev-tools/issues/14), +[#265](https://github.com/php-fast-forward/dev-tools/issues/265), +[#266](https://github.com/php-fast-forward/dev-tools/issues/266) and +[#267](https://github.com/php-fast-forward/dev-tools/issues/267) remain open. +These decisions are not prerequisites for the initial 0.1.0 style/syntax profile. + +## Existing source + +Inspected DevTools `35b5f78ac63813ec07aa3fb3eda08751541e28e1`. Bounded searches of +composer.json, src/, resources/, .github/ and README found no declarations of +PHPStan/Psalm/PHPat/php-assumptions/TypePerfect/security-audit engines or a +dedicated command for these candidate source analyzers. Existing Dependencies +and Metrics commands serve other contracts. PHPStan/Psalm filenames occur in +GitAttributes CandidateProvider only. +This is evidence of the searched surfaces, not a proof about every historical +branch or generated dependency. No source file was changed or scan executed. + +## Actual candidate engines + +Moving upstream default-branch manifests read via the authorized GitHub connector +on 2026-10-21 at 21:12 UTC, with exact file blob hashes below. These are not selected published +package versions or verified runtime compatibility claims. + +| Source issue | Candidate and real upstream | Observed contract | Consequence | +| --- | --- | --- | --- | +| DevTools14 | phpstan/phpstan | Dedicated analyzer/PHAR; native analyse/configuration/level/error-format/memory-limit | Prefer native settings and exits; no generic multi-engine abstraction before a second real requirement | +| DevTools265 | rskuipers/php-assumptions | Standalone bin/phpa; php-parser4/5 + league/climate; README calls it a proof of concept | Not a PHPStan extension or runtime assertion framework on this evidence; identify intended package/version and test actual exits/target syntax before integration | +| DevTools266 | carlosas/phpat, package phpat/phpat | type phpstan-extension; PHP^8.1, PHPStan^2.1; extension.neon registered in extra | Real PHPStan extension; its development Psalm dependency is not a consumer runtime engine | +| DevTools267 | FloeDesignTechnologies/phpcs-security-audit, package pheromone/phpcs-security-audit | type phpcodesniffer-standard; PHP_CodeSniffer^3.1.0 + DealerDirect installer plugin; manifest declares GPL-3.0-or-later | Premise that this is a PHPStan security extension is incorrect; assess separately, without automatic plugin activation, mandatory adoption or inferred compatibility with modern PHPCS | + +Manifest blob hashes: PHPStan `a267d4c50d8cd59cd63866d4c8b04a25f0a24627`; +assumptions `6037a1c9b39737581f74577f513d18333295354f`; +PHPat `055245974b55aa70c3a59954d373dc95c938b8e9`; +security-audit `a2a72a7b98d94d0e65e151f470dcc5715d9306a0`. +Security-audit README blob `63be29bacf78614110c556dfad68eafda4b140c4` +explicitly describes PHPCS invocation and significant noise; no scanner was run. + +Primary manifests: +[PHPStan](https://github.com/phpstan/phpstan/blob/2.3.x/composer.json), +[assumptions](https://github.com/rskuipers/php-assumptions/blob/master/composer.json), +[PHPat](https://github.com/carlosas/phpat/blob/main/composer.json), +[security-audit](https://github.com/FloeDesignTechnologies/phpcs-security-audit/blob/master/composer.json). + +## Changed-file semantics need a distinct decision + +PHPStan explicitly recommends a stable whole-project analysed path set and uses +its native result cache/dependency tree to revisit dependents of changed symbols. +Therefore the ECS changed-file list must not be presented as equivalent type +analysis. A changed method signature can invalidate unchanged callers; checking +only the changed source would not establish those callers' validity. This last +example is an architectural inference, not an executed regression result. +If a restricted mode is retained later, name its limits explicitly and require +cross-file dependency regressions; native whole-project analysis is the proposed +default for an eventual PHPStan slice. No new CLI option was implemented. +[Official result-cache contract](https://phpstan.org/user-guide/result-cache). + +PHPStan resolves symbols from analysed paths and the consumer Composer graph; +custom bootstrap/autoload PHP actually executes. A separately installed tool +does not remove that execution or namespace boundary. Preserve consumer NEON, +imports and baselines; use explicit target-PHP/config selection, unprivileged +processes, isolated tool cache and no incidental Composer scripts/plugins or +baseline writes. Test that checkout symbols win over an installed library with +the same namespace before adoption. +[Symbol discovery](https://phpstan.org/user-guide/discovering-symbols), +[native CLI](https://phpstan.org/user-guide/command-line-usage). + +## Remaining gates + +- Decide Code Standards ownership versus another tool before closing or moving + the four DevTools candidates. Do not implement every optional engine at once. +- Select actual published versions, inspect licenses/compatibility and prove + execution/format/exit/read-only behavior with synthetic cross-file fixtures. +- Keep TypePerfect semantic changes opt-in and independently scoped; its actual + package/groups remain to verify rather than copying an issue's assumption. +- Preserve current first-release boundary: syntax + non-risky ECS style only; + tests/coverage/full reporting remain other domains. No consumer migration.