andrexibiza's F12 (changed form, review 5407834086): canonical_tree() pooled
every parameter, assignment and def in the module into one "rebound" set, so
`from subprocess import run as execute` stopped resolving everywhere as soon
as an unrelated function had a parameter or local named `execute`, and
`launch(cmd): return execute(cmd)` lost its HX006.
Bindings are now recorded per scope (module, class, function/lambda,
comprehension) and each read resolves through the scope chain the way Python
does: the innermost scope that binds the name decides, a scope that binds it
other than by one import makes it a plain local there, class bodies are not
visible to nested functions. Genuine shadowing in the consuming function (or
at module level) still stops resolution.