> * Even ***with*** `OP_CAT`, the following will enable non-recursive covenants without enabling recursive covenants:
> * `OP_CTV`, ...
> * With `OP_CAT`, the following would enable recursive covenants:
> * `OP_CHECKSIGFROMSTACK`, ...
Why does CTV+CAT not enable recursive covenants while CSFS+CAT does?
CTV+CAT lets you similarly assert against the outputs and verify that they match some dynamically constructed script.
Is it because CTV does not let you have a verified copy of the input's prevout scriptPubKey on the stack [0], while with OP_CSFS you can because the signature hash covers it?
But you don't actually need this for recursion. Instead of having the user supply the script in the witness stack and verifying it against the input to obtain the quine, the script can simply contain a copy of itself as an initial push (minus this push). You can then reconstruct the full script quine using OP_CAT, as a PUSH(<script>) followed by the literal <script>.
When I started experimenting with recursive covenants on liquid, I started with the approach of verifying user-supplied witness data against the input. It ended up being quite complex and verbose with taproot, because you have to compute the tagged taptree hash from the tapscript and TWEAKVERIFY it against the prevout's taproot output key (which also requires the internal key and parity flag, provided as two extra witness elements by the user).
I then realized that it is much simpler to have the tapscript hold a copy of itself, that it's as safe and that it reduces the witness size cost (because you don't need to do the entire taproot dance to verify the tapscript), and switched to this approach.
Here are two examples of recursive covenants using this approach that I played with (for liquid, rough sketches, very lightly tested and has some known issues. the $label thing is a scriptwiz notation and can be ignored):
shesek
[0] It does not cover it, and it cannot be done even by providing the full prev tx because the prevout txid is not covered either.