The framework extension is what makes level 8 possible

A service container returning mixed and a model with magic properties defeat static analysis entirely without a framework-aware extension.

$ composer require --dev nunomaduro/larastan

# what it teaches the analyser:
#   app(Foo::class) returns Foo, not mixed
#   $model->column, from the migration or a docblock
#   Model::where() returns a Builder, and ->first() may
#     return null
#   the facade signatures

# without it, level 5 is already unreachable.

The extension is not optional on a framework-heavy codebase — it is the difference between an analyser that works and one that reports thousands of false positives about magic. Model properties are the remaining gap: they come from the database and the analyser cannot see the schema, so a generated docblock per model is the usual answer and it goes stale. Generating those docblocks in CI and failing on a diff is what keeps them true.