and contains a scriptSig field (the unlocking script) which contains data necessary to spend the transaction
After August 2017 when we got SegWit, another field in each transaction was added called "witness" where we store stack items used in "unlocking" the output. In fact every tx spending a SegWit output has an empty signature script.
To verify the validity of a transaction, scriptSig data is appended to scriptPubKey data
Wrong.
Each script is evaluated/executed separately. Appending the data is a source for a bug which was fixed in early days.
It consists of a small set of 255 “asymetric cryptography specific” op codes
OP codes can be from 0 to 255 but there are actually a lot less OP codes defined than 255 (8-bit) since many values are not yet defined and a handful of old ones were disabled.
a bug in the OP_CHECKMULTISIG implementation
Although commonly referred to as a bug, I don't think this was actually a bug.
I believe that it was a "feature" meant for scalability. Imagine if you wanted to introduce a soft fork where you changed how OP_CHECKMULTISIG works and add additional steps to it. You could technically introduce the new rules for that extra item and the new nodes would pop it, evaluate it as a script and return true/false while old nodes simply ignore it (ie. a soft fork).
Keep in mind that prior to SegWit, BIP-147 (mandating the dummy item to be OP_0) was not enforced.
Since Segwit, OP_RETURN is also used to store the merkle root of the witness data in Segwit transactions.
Clarification: only used in coinbase transaction and is mandatory only if the block contained any SegWit transactions.
Because of the need for backward compatible changes in Bitcoin
It is not a "need" but a "preference".