rskuipers/php-assumptions
PHP Assumptions is a static analysis tool that detects hidden assumptions in your code, like variables used without guarantees about their type or existence. It reports each assumption, helping you catch risky spots and improve type safety. Runs via Composer and CLI.
Architecture fit. rskuipers/php-assumptions is a dev-time static analysis CLI, not a Laravel package. It ships no service provider, no facade, no publishable config, and no runtime dependency on the framework. That is actually a point in its favor: it cannot leak into the request lifecycle, bootstrap order, or container graph. Architecturally it belongs in the same layer as PHPStan/Larastan, Pint, and Rector — a require-dev binary executed by Composer scripts or CI — and the correct mental model is "linter," not "library."
The tool's value proposition is narrow and specific: it parses docblocks and code to find places where the code assumes something about a value (it is an array, it is non-null, it is an instance of X) without a corresponding guard, and it lets you map assumption types to the guard functions your codebase actually uses (e.g. is_array, custom assertions). That configurability is the main reason to consider it over a generic linter — it can be taught your conventions.
Integration feasibility. Low effort: one composer require --dev, one config file at the project root (or passed via --config), one CI step. There is no migration, no data model, no middleware, no queue interaction. A single engineer can produce a working pilot in under a day. The real cost is not wiring — it is triaging output.
Technical risk.
composer.lock plus a hash-verified install. An unresolvable upstream is a hard blocker for anything beyond a throwaway audit.Model::__callStatic. Expect false positives concentrated exactly where Laravel code is densest, which is also where the signal would be most valuable. The guard-mapping config mitigates this only partially.Key questions.
nikic/php-parser major version)? Does that pin conflict with Larastan's parser requirement and block upgrades?Stack fit. Add as a require-dev entry, pinned to an exact version. Invoke through a Composer script (composer assumptions) and a dedicated CI job that is non-blocking during the pilot. Do not add it to the deploy pipeline, do not add it to the production image, and do not add it to the pre-commit hook until precision is measured.
Migration path. There is no migration in the data sense; the migration is organizational. Sequence it as an audit, not an adoption:
Validator usage — until the output is stable.Compatibility. Expect friction on the parser dependency; static analysis tools are the most version-sensitive part of a PHP dependency graph. Check the constraint against Larastan and Rector before adding, and verify the lock file resolves without downgrading the existing analyser stack. If it forces a downgrade of Larastan, the trade is not worth it.
Sequencing. Run this after Larastan is at a stable level and a baseline exists. Deploying a second analyser into a codebase with no existing baseline produces an uninterpretable wall of output and burns team goodwill on a tool we may drop.
Maintenance. Effectively zero operational maintenance — no runtime, no migrations, no config drift in production. The maintenance burden is version-lock upkeep: every PHP or php-parser major bump requires confirming the tool still installs and still parses. With a single maintainer upstream and a 2025 release cadence, budget for the possibility of forking or dropping it at the next PHP major.
Support. No commercial support, no vendor, no SLA. Internal support reduces to "the maintainer's issue tracker, or we fix it ourselves." Before formal adoption, identify one engineer who can read the tool's internals well enough to patch it or to declare it abandoned.
Scaling. Runtime scales linearly with codebase size in the same way as any AST walker — acceptable for CI, but it is another full parse of the tree. On a large monorepo this is a real minute-cost per pipeline run and should be scoped to changed paths. Organizational scaling is the bigger constraint: every developer must learn to distinguish a genuine unguarded assumption from a Laravel-magic false positive, and that learning cost recurs with each new hire.
Failure modes.
require-dev until someone audits the lock file.Ramp-up. Low for wiring (hours), moderate for interpretation (days per engineer to build intuition on false-positive patterns), and the payoff is contingent on the precision measurement. Realistic recommendation: fund a two-day spike, run it as a one-off assumption audit on the legacy surface, and treat the findings as input to better Larastan rules and explicit assertion helpers rather than as a permanent pipeline stage. If the spike finds a defect class Larastan genuinely misses, revisit adoption with real numbers; if not, extract the value once and do not carry the dependency.
How can I help you explore Laravel packages today?