Generally, Bazel puts everything it needs in output_base. It makes it easy to remove all the artifacts related to a given workspace instance (e.g. bazel clean --expunge).
However, the Perforce type workflow you describe (which I used quite a bit when I had to use Perforce) is not limited to Perforce. I use git worktree for a similar workflow. When I've got a long running development cycle on a branch, I may want to work on another branch simultaneously. You could do this without git worktree, but git worktree allows you to use a single git repository to support multiple workspaces simultaneously.
Bazel isn't particularly currently optimized for this workflow, as each workspace has a dedicated outputBase. A large portion of these outputBases (e.g. action_cache, external) could reasonably be shared between outputBases. I think the content based nature of the artifacts could lend itself to sharing those artifacts.
The big hurdle would be managing those shared caches. That is, how do you safely determine when to clean up stale action cache entries? How would a bazel clean know what to clean? However, I think for growing subset of users, I think I can deal with the fallout of manually trimming the action cache across multiple workspaces. The space savings would be significant for my workflow.
I'm guessing it slightly more complicated than creating a single action cache, similar to how --disk_cache doesn't work with remote execution (
https://github.com/bazelbuild/bazel/pull/10233), but I for one would be able to leverage an action_cache shared across outputBases quite a bit.
-michael