Sure but logic doesn't exist in a vacuum so in most cases you are going to import / export your input data or your results to the filesystem or through the network.
At the time it was deemed to difficult to implement in Node.js after the fact, which makes sense of course.
But I'm disappointed that Deno didn't go for a more bolder, more secure approach. The current system seems pretty pointless.
It is actually more interesting about the definition of “per module”, because technically every single file is its very own module from the view of V8, and is reinforced in Deno since we are trying to be web compatible, so there is not even a package.json-like construct for you to identify the “root” of any library, more so as there is no more index.js magical resolution
I'm really sad that I lost my gist on this, but I was working on a system in Node.js for defining the capabilities of modules in an es module graph (as you suggest) where there might not be defined package boundaries. The implementation complexity (required changes to upstream V8) resulted in us going with node policies as they are today.
I don't remember the exact API, but basically an es module graph is a directed graph (e.g. edges have a direction), and because there is only one entrypoint in node, we can therefore create a hierarchy of modules. From this point on, you basically start at the root with X permissions, and from there each module can reduce the permissions of modules they import (or they can reduce their own permissions, but they can't raise them after that obviously).
I actually suggested a more granular, per-module approach to this during the Node Forward and IO.js debacle years ago: https://github.com/node-forward/discussions/issues/14
At the time it was deemed to difficult to implement in Node.js after the fact, which makes sense of course. But I'm disappointed that Deno didn't go for a more bolder, more secure approach. The current system seems pretty pointless.