This step, then that one, in that order. It is an instruction sheet, and a machine can follow it perfectly without ever knowing what it was for.
The why — the thing you actually had in mind when you wrote it — never makes the trip. It stays in your head, or in a comment, or in a design document that went stale two years ago. Every tool downstream is then guessing at intent it was never given.
You write what the program means. That gets stored as one canonical graph — content-addressed, so the same meaning always has the same name — with every effect it is permitted to have declared in a single list rather than scattered through the code.
The steps come out of that. Which is why the same program can come out the other side as native Rust, and why concurrency stops being something you hand-write: if the meaning says two things don't depend on each other, nothing has to be told twice.
Because nothing in that idea is about source code. A representation that holds what something means, separately from the steps that carry it out, is not a compiler feature. It is a question you can ask of anything that carries meaning at all.
Every one of those fields has already built its own semantic analysis, and none of them can talk to any of the others. Whether one substrate could carry all of it is entirely unsettled — that is the adventurously speculative half, and the half worth arguing about. It is worth reading not because it is right, but because it might be.