My understanding is that Racket hygiene being based on scope sets was chosen in part for historical reasons; e.g. the scope pruning scheme was added to be backwards compatible with existing idioms.
I've skimmed the docs and the original scope sets paper and I still find the details a bit confusing to work through. I'm wondering if backwards compatibility weren't a concern, if we could get away with a simpler scheme: when you make a syntax quote, identifiers in it can only resolve to things that were in scope when you constructed the quote OR bindings introduced within the same syntax quote, but not from any other syntax quote. If you wanted to actually refer to the same binding across multiple syntax quotes, you'd have to explicitly splice it into the binding and reference quotes:
That the #'x spliced in by #,ref would not be a reference to the x bound in the let. You would instead have to write:
(let ([ref #'x])
#`(let ([#,ref 1]) #,ref))
For the simple types of macros I've written in Racket before I don't think this would pose a problem, but I don't know if there is advanced macrology where this breaks?
Another way to think about this is that within a syntax quote, bindings are implicitly gensym'd and any references to them are patched appropriately, and when you just write a standalone #'identifier that's doing a gensym with no references, that you can then only produce more references to by splicing into other quotes.
It sounds like you're proposing to move the "freshness" boundary from the macro expansion step to the syntax template expression. If so, it sounds like Andre van Tonder's hygienic macro proposal, which eventually became SRFI-72.
I think it's a move in the wrong direction, on the general principle that impure abstractions are usually bad, or at least their costs need to be considered. To explain that, let me first point out an example of a pure abstraction: Racket's lambda form. Racket respects the βᵥ equation: ((lambda (x) e) v) = e[v/x]. That is, there is no observable difference (aside from debugging information) between an expression that contains a value directly and the application of a function that receives the value and refers to it in the right place (assuming no scoping changes). So Racket's lambda creates a pure abstraction, in a way that, for example, Javascript's function does not, since Javascript allows you to retrieve "the current function arguments", return is sensitive to function boundaries, variable hoisting, and possibly other reasons. Javascript function comes with extra baggage. Racket lambda doesn't, and so there are fewer things to worry about when using procedural abstraction in Racket.
Hygienic macros are not pure abstractions with respect to surface syntax. For example:
(let ([x 1]) (+ x 2))
≠
(define-syntax-rule (m e) (let ([x 1]) e))
(m (+ x 2))
In fact, that's kind of the point of hygiene. Hygiene is usually more useful than strict purity, but if you do sufficiently complicated things with macros, especially if you limit yourself to syntax-rules, you will likely find yourself occasionally saying "I wish hygiene didn't apply to this macro". But at least the granularity of impurity for Racket's hygienic macros is the macro expansion step. Changing the granularity to the syntax template instead means that you have additional worries when writing macros whose result is too complicated for a single template, or for refactoring a big syntax template into smaller pieces.