So I had an epiphany earlier and finally understood the SCons dependency model. It turns out the system is actually very powerful being designed the way it is. Unlike most build systems, it doesn't work in terms of sources, but rather in terms of targets. This was counterintuitive to me at first (see recent comments in minisphere thread), but it actually makes a lot of sense: Your dependency is on the output of a build, not its input. So I decided that Cell will use a similar model. Instead of having functions to build stuff serially and then installing files like this:
install("src/*.js", "scripts");
buildSpriteset("something.rss", "something.sprite"); // or whatever
install("something.sprite", "spritesets");
It would instead be more like this:
install(files("src/*.js", { recurse: true }), "scripts/");
install(spriteset("something.sprite"), "spriteset/something.rss");
In other words, instead of directly installing files, you install assets. This is indeed much more robust as it allows the compiler to determine the proper build order of the various dependencies on its own without the build script having to worry about everything being in the right order.