user100212: I'm reading the Bitcoin Core's descriptor documentation and I noticed that the raw() SCRIPT expression can only be used at descriptor top-level. Indeed when called with this descriptor getdescriptorinfo returns -5 error with the message Can only have raw() at top level:
tr(c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,raw(fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))
I assume that raw() is the only way you add an OP_RETURN type commitment in a taproot script path, or at least I couldn't figure out a way to do otherwise. I could think of using the pk() expression with a hash for example, but I guess it's bad to do that.
Why isn't it allowed to commit OP_RETURN type commitments, let alone other arbitrary script, inside a taproot address? Is it a descriptor restriction or a more fundamental limitation?
I read this but I don't think it really answer my point. If descriptors support arbitrary script only at top-level, why then?

user101498: The answer is twofold.
First, the Bitcoin Core descriptors are in the process of being extended with Miniscript. In the upcoming version (24.0), Miniscript will only be supported in Segwit version 0 outputs (P2WSH).
Once Miniscript support for Tapscript is added, you will be able to use a lot more Script functionalities in the script paths of a Taproot descriptor.
With regard to arbitrary Scripts, that is including those that are not representable (and therefore not solvable) using Miniscript. There is an ongoing discussion about supporting "partial descriptors", an otherwise solvable descriptor containing a spending path for which we have no solvability information.
A partial Taproot descriptor would allow you to have a rawnode(HEX) in the tree. This is what you need if you want to keep the solvability through the key path, because otherwise you could just use rawtr().

an OP_RETURN type commitment in a taproot script path, or at least I couldn't figure out a way to do otherwise. I could think of using the pk() expression with a hash for example, but I guess it's bad to do that.

Unrelated to your main question, but i don't think it's necessarily bad to use another form of commitment. If you were thinking this because of OP_RETURN outputs pruning from the UTxO set, note this is meaningless in this context.
You could use less expensive methods for committing the data. Such as tweaking a public key. And that would remove the need for partial descriptors.

user5406: It's not clear to me why one would want to commit to an OP_RETURN inside of a P2TR output construction, let alone inside of a descriptor. I feel like there might be a misunderstanding here.
Using the OP_RETURN op-code makes an output script unspendable (and in most cases non-standard). Putting OP_RETURN as the first instruction in a scriptPubKey indicates a NULL DATA output, which permits writing a small amount of data to the blockchain. Because NULL DATA outputs are unspendable, they do not get inserted in the UTXO set, but since they're written out as part of the transaction in the blockchain, they're still published.
A popular application of NULL DATA outputs is the publishing of a commitment, e.g. the hash of a document to prove that it existed at the time, the witness commitment in segwit blocks, or a Merkle root of a whole tree of commitments as with OpenTimeStamps.
Putting an OP_RETURN into a leafscript of a Taptree does not serve the purpose of publishing the data, since only the leafscript used for spending the UTXO in the input will ever written to the blockchain.
If the data should be published per the transaction, it should be a dedicated output.
If the creation of a commitment suffices, it would be enough to tweak the inner public key with the hash of the data. That way, the owner could at a later time publish the data, and attest to the hash by signing with the inner public key. The act of publishing would then be separate from the act of committing, but the commitment would still proof that the data existed at the time of the transaction output creation.

100212: <p>I'm reading the <a href="https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md" rel="nofollow noreferrer">Bitcoin Core's descriptor documentation</a> and I noticed that the <code>raw()</code> <code>SCRIPT</code> expression can only be used at descriptor top-level. Indeed when called with this descriptor <code>getdescriptorinfo</code> returns <code>-5</code> error with the message <code>Can only have raw() at top level</code>:</p>
<p><code>tr(c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,raw(fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))</code></p>
<p>I assume that <code>raw()</code> is the only way you add an <code>OP_RETURN</code> type commitment in a taproot script path, or at least I couldn't figure out a way to do otherwise. I could think of using the <code>pk()</code> expression with a hash for example, but I guess it's bad to do that.</p>
<p>Why isn't it allowed to commit <code>OP_RETURN</code> type commitments, let alone other arbitrary script, inside a taproot address? Is it a descriptor restriction or a more fundamental limitation?</p>
<p>I read <a href="https://bitcoin.stackexchange.com/questions/106586/output-descriptor-for-an-arbitrary-script">this</a> but I don't think it really answer my point. If descriptors support arbitrary script only at top-level, why then?</p>
 101498: <p>The answer is twofold.</p>
<p>First, the Bitcoin Core descriptors are in the process of being extended with <a href="https://bitcoin.sipa.be/miniscript/" rel="nofollow noreferrer">Miniscript</a>. In the upcoming version (24.0), Miniscript will only be supported in Segwit version 0 outputs (P2WSH).<br />
Once Miniscript support for Tapscript is added, you will be able to use a lot more Script functionalities in the script paths of a Taproot descriptor.</p>
<p>With regard to arbitrary Scripts, that is including those that are not representable (and therefore not solvable) using Miniscript. There is an ongoing discussion about supporting &quot;<a href="https://github.com/bitcoin/bitcoin/issues/24114" rel="nofollow noreferrer">partial descriptors</a>&quot;, an otherwise solvable descriptor containing a spending path for which we have no solvability information.<br />
A partial Taproot descriptor would allow you to have a <code>rawnode(HEX)</code> in the tree. This is what you need if you want to keep the solvability through the key path, because otherwise you could just use <a href="https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#reference" rel="nofollow noreferrer"><code>rawtr()</code></a>.</p>
<blockquote>
<p>an OP_RETURN type commitment in a taproot script path, or at least I couldn't figure out a way to do otherwise. I could think of using the pk() expression with a hash for example, but I guess it's bad to do that.</p>
</blockquote>
<p>Unrelated to your main question, but i don't think it's necessarily bad to use another form of commitment. If you were thinking this because of OP_RETURN outputs pruning from the UTxO set, note this is meaningless in this context.</p>
<p>You could use less expensive methods for committing the data. Such as <a href="https://bitcoinops.org/en/topics/pay-to-contract-outputs/" rel="nofollow noreferrer">tweaking a public key</a>. And that would remove the need for partial descriptors.</p>
 5406: <p>It's not clear to me why one would want to commit to an <code>OP_RETURN</code> inside of a P2TR output construction, let alone inside of a descriptor. I feel like there might be a misunderstanding here.</p>
<p>Using the <code>OP_RETURN</code> op-code makes an output script <em>unspendable</em> (and in most cases non-standard). Putting <code>OP_RETURN</code> as the first instruction in a scriptPubKey indicates a <em>NULL DATA</em> output, which permits writing a small amount of data to the blockchain. Because NULL DATA outputs are unspendable, they do not get inserted in the UTXO set, but since they're written out as part of the transaction in the blockchain, they're still published.</p>
<p>A popular application of NULL DATA outputs is the <em>publishing of a commitment</em>, e.g. the hash of a document to prove that it existed at the time, the witness commitment in segwit blocks, or a Merkle root of a whole tree of commitments as with OpenTimeStamps.</p>
<p>Putting an <code>OP_RETURN</code> into a leafscript of a Taptree does not serve the purpose of publishing the data, since only the leafscript used for spending the UTXO in the input will ever written to the blockchain.
If the data should be published per the transaction, it should be a dedicated output.</p>
<p>If the creation of a commitment suffices, it would be enough to tweak the inner public key with the hash of the data. That way, the owner could at a later time publish the data, and attest to the hash by signing with the inner public key. The act of publishing would then be separate from the act of committing, but the commitment would still proof that the data existed at the time of the transaction output creation.</p>
