Attributed variables, reachability, garbage collection, debugging

I’d like a way to assert that a goal has left no residual variables.
It seems that call_residue_vars/2 isn’t what I want in that it (intentionally) disregards reachability.

So here:

test_residue_vars(Vars) :-
    call_residue_vars(test_freeze(1, B), Vars).

test_freeze(A,B) :-
    freeze(X, (B = A)), !.

Even though X is not reachable in any way once we exit test_freeze, call_residue_vars will still report a nonempty list of residual variables.

Is there an (easy) way to implement:
no_residual_vars(Goal) that succeeds only if there are no residual vars when Goal succeeds?

Is it correct to say:
no_residual(G) :- G, deterministic(D), !, D.

(With the understanding that we literally claim ONLY that deterministic → no_residual, but have not attempted to identify any other Goals where no_residual(Goal) is true)

I don’t get it. Residual goals and determinism are pretty much orthogonal AFAIK. If you only want to consider reachable residuals, simply test that the answer does not contain any attributed variables using term_attvars/2.