This was the right spirit, but given some further thought I am proposing to go ahead and reserve the isotopic word of ~end~ for this purpose (and in general, go ahead and probably reserve all isotopic words for system use)
If your argument is endable and not ^META, it will be something like this.
>> foo
Congratulations, you got an ~end~ isotope
>> foo ~end~
** Error: ~end~ is not a legitimate callsite argument
>> f: make frame! :foo
== make frame! [value: ~]
>> f.value: ~end~
>> do f
Congratulations, you got an ~end~ isotope
If your argument is ^META and not endable, you can get this
>> bar
** Error: bar.value is not endable
>> bar ~end~
Congratulations, you got an ~end~ quasiform
>> f: make frame! :bar
== make frame! [value: ~]
>> f.value: ~end~
>> do f
** Error: bar.value is not endable
>> f: make frame! :bar
== make frame! [value: ~]
>> f.value: '~end~
>> do f
Congratulations, you got an ~end~ quasiform
And if you have an endable ^META parameter, it meshes both possibilities together:
>> baz
Congratulations, you got an ~end~ isotope
>> baz ~end~
Congratulations, you got an ~end~ quasiform
>> f: make frame! :baz
== make frame! [value: ~]
>> f.value: ~end~
>> do f
Congratulations, you got an ~end~ isotope
>> f: make frame! :baz
== make frame! [value: ~]
>> f.value: '~end~
>> do f
Congratulations, you got an ~end~ quasiform
...under these rules there is no conflation...
Functions only receive ~end~ isotopes on <end>
-able parameters, but those isotopes can come from deliberate assignment in frames as well as an end encountered at the callsite.