Build1 distinct publisher2 min readPublished
Fifteen structured attributes take over from a tag that fired on methods nobody had to change. The vendor, not the plugin author's ignore list, absorbs the fix.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The concession in Shopware's post is about incentives rather than syntax. A tag that fires on every call site of a method that will keep working teaches extension developers exactly one habit, and Shopware says it considered blessing that habit by recommending more ignore patterns, then rejected it, because a blanket ignore also swallows the deprecations where migration genuinely is required [9]. Its own reading is that PHPStan was not too strict; it was being handed the wrong signal [9].
One boolean flag cannot say which kind of dependency a plugin has. Narrowing a parameter type breaks callers that pass values outside the future type, while widening that same parameter is harmless to callers and can make an overriding method incompatible [8]. Return types run the other way, because PHP return types are covariant: a narrower return type leaves callers alone but can force subclasses that redeclare the method to adjust [10]. Calling a method and overriding it are different forms of dependency, and the old annotation could express neither that distinction nor the future type, parameter name, default value, or affected audience in a form a tool could read [12].
The arithmetic of the replacement is worth stating plainly. The `reason:*` markers announced five categories of planned change [4]. The `BCChange` namespace ships 15 concrete attributes [6], roughly three times the granularity [14], with directional names such as `ReturnTypeNarrowing` and `ReturnTypeWidening` [13], so direction is part of the type instead of part of the prose.
Delivering this in 6.7.14.0 rather than in 6.8.0 is the part that has to be right for the rest to function: metadata describing a major release has to live in the branch you are leaving, not the one you are entering [15]. That also fixes where the remaining work sits. A plugin can only pre-migrate if its pipeline runs the older line with tooling that understands the attributes, and Shopware's claim is that the attributes carry enough structured information for PHPStan, Rector and IDEs to reason about them [5], which is a statement about what is now possible, not about what those tools do today. The near-term benefit Shopware claims for itself is narrower and more credible: less noise for extension developers [17].
Ranked by verification strength, evidence, and original report placement.
With Shopware 6.7.14.0, Shopware is changing how planned API changes are communicated: real deprecations remain deprecations, while other backward-compatibility changes are described with dedicated, structured PHP attributes.
Shopware now uses two signals: @deprecated means an API is obsolete and will be removed or replaced and developers must migrate away from it; BC-change attributes describe a future change to an API that remains available, such as a new parameter, a narrower return type, or a class becoming final.
Context::scope() had its planned 6.8 change announced as "@deprecated tag:v6.8.0 - reason:new-optional-parameter - parameter $states will be added"; static analysis reported every call to the method even though the method is not going away and existing calls will continue to work without changes.
Shopware also used @deprecated as an internal planning mechanism for the next major version, with a reason:* marker announcing that a return type will become narrower, a parameter type will change, a new optional parameter will be added, a class will become final or internal, or a method's visibility will change.
The new attributes live in the Shopware\Core\Framework\Deprecation\BCChange namespace, and there are currently 15 concrete attributes covering changes to types, parameters, visibility, inheritance and exception contracts.
Every attribute belongs to one or both of two audiences: CallSiteCompatibilityChange, for a change that may affect code calling a method, and ExtenderCompatibilityChange, for a change that may affect a subclass or method override.
Follow any of these and your For You feed starts watching them — no settings page required.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Detailed primary source, single publisher
The cluster rests on one self-published vendor engineering post, but it is unusually concrete: named namespace, attribute count, audience interfaces, directional naming, and before/after code for a specific method. Descriptive mechanics are well evidenced; nothing is independently corroborated and the benefit claims carry no measurement.
Shipped in Core, no ecosystem uptake shown
Adoption evidence is vendor-internal only: the attributes ship in 6.7.14.0, Core's existing planning annotations were migrated, PHPStan enforcement was added, and Context::scope() is converted. There is no evidence of third-party consumption — no plugin authors, no Rector rules, no IDE support, no counts of affected extensions.
Modestly overstated benefits, sober mechanics
The technical body is measured and self-critical — it concedes the vendor gave PHPStan the wrong signal rather than blaming the tool. The gap comes from unmeasured outcome language ('less noise', warnings 'trustworthy and actionable again', tools can now reason about the changes) presented as accomplished fact when only Shopware's own PHPStan enforcement is shown, and from the release itself being a metadata convention rather than a resolved 6.8 upgrade path.
Vendor self-report on its own framework
The single source is Shopware writing about Shopware on a developer-relations channel, with a direct interest in framing a self-inflicted tooling-noise problem as solved and in reassuring plugin authors ahead of the 6.8 major. That incentive is partly offset by the post's explicit admission of fault and by concrete, checkable code details.
Mechanics reliable, effects unproven
High confidence in what shipped and how it is structured, because the source is primary, specific and falsifiable against the codebase. Low confidence in the claimed developer-experience and tooling-ecosystem effects, since the cluster has one self-interested publisher, no independent corroboration and no adoption or measurement data.
build
Six MariaDB versions, one real difference: the only reason to leave 10.6 is the July 2026 clock1 distinct publisher
build
Once the question needs a cube, you own the parser1 distinct publisher
build
Thirty lines of Doctrine filter, and the query paths where it is simply not there1 distinct publisher
build
array_search_range meets the freeze: PHP internals wants a lazy slice, not another array function1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 24, 2026