Reuse the compiler's lowering pass instead of re-implementing its checks
in sema. A module can't be lowered standalone — lowering only type-checks
functions reachable from a root — so the open file alone misses errors
like a *Move passed into a by-value method parameter. Drive the workspace
entry (main.sx) through parse → resolveImports → lowerToIR, then attribute
each diagnostic back to its file via source_file and publish per file
(clearing files whose errors are gone).
Runs on didOpen/didSave (disk-based); sema stays the live per-keystroke
layer. Advertise textDocumentSync.save so the editor sends didSave.
collectProjectDiagnostics is split out (transport-free) and covered by a
hermetic temp-project test.
cmd-clicking a definition (or any use) now lists all references. Same-file matches are precise (by symbol index); cross-file matches a top-level name across loaded documents. Advertises referencesProvider. Verified: references to a free function resolve across files (rules.sx def + internal calls + main.sx caller).