(1) the rules API is intended to make it safe to express complex build logic in a cacheable way. the way we have currently accomplished this is by codifying each disparate build step that can be independently cached with its own hashable type, e.g. a dataclass. the intent of the rules API however is that you should
not have to import a ton of small things, and instead you should be able to make use of higher-level wrappers. the rules API allows you to wrap complex actions into a series of cacheable `@rule`s, which you can then consume without much difficulty. we are 1000% working on building more of those higher-level wrappers (so your concern is a 100% correct observation), but i would also encourage you to consider whether a set of `@rule`s that would allow you to do e.g.
await Get(BuiltDockerImage, DockerInput(...))
might accomplish the goal you have with factory functions. anything that requires a process execution for sure we want to have in a ruleset so it can be cached, for example.
we would really love 100% to hear your thoughts on ergonomics though, and it sounds like you're barking up exactly the right tree. please feel free to elaborate in an issue, or slack (we mostly use the
#C0D7TNJHL channel for this)