This is related to #14150 and possibly others, but it's actually a separate issue.

For instance, when using the following query:
`bitcoin-cli scantxoutset start '[{"desc":"wpkh(xpubABCDEF/0/*)", "range":100}]'`
I can get a list of UTXOs, but no way to get back the index which derived that particular UTXO. So it's not much better than deriving on the user side and specifying addresses one by one, so that I already have a cache of addresses to match.

Not sure what the solution looks like. One way is to repeat the full descriptor in the utxo. That might get verbose though.
Unserialize(s);
    }
};
bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata);
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType);
bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType);
bool SignPSBTInput(const SigningProvider& provider, const CMutableTransaction& tx, PSBTInput& input, int index, int sighash = SIGHASH_ALL);
SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout);
void UpdateInput(CTxIn& input, const SignatureData& data);
/* Check whether we know how to sign for an output like this, assuming we
 * have all private keys. While this function does not need private keys, the passed
 * provider is used to look up public keys and redeemscripts by hash.
 * Solvability is unrelated to whether we consider this output to be ours. */
bool IsSolvable(const SigningProvider& provider, const CScript& script);
#endif