I think FENCE! provides a generic answer regarding generalized shallow gathering (what we have called WRAP in the past), but better than WRAP as it can be captured literally by syntax:
Because FUNC(TION) takes its body by value and stores it for multiple evaluations, it is necessary to take a FENCE! literally, otherwise any locals created would be bound to a single object created at the time of FUNC creation. If FUNC is able to see the FENCE! then it can do the gather and fold it in with the frame, which seems the right answer.
The FENCE! seems to be a very solid solution--that matches your intuition--that gathering should not be deep by default, but it allows you to be granular and push deeper with more fences if you feel it is warranted.
Only the top-level fence has the problem of needing literal capture (as otherwise it would be wrapped once and then used for multiple function invocations with the same object). This liability solved via actually merging those top level fields into the locals of the frame becomes an asset for efficiency.