Looking the the transaction structure and bitcoin protocol enforcement, one will just wonder how the bitcoin protocol enforce the no dublicate inputs at the consensus level
Can you elaborate more? Bitcoin node have UTXO set (sometimes called chainstate) to prevent same input spend more than once and check whether transaction actually use unspend input that actually exist.
why was the witness structure (segwit) was implemented as soft work rather than a hard fork
I recall the main reason is backward compatibility, which increase chance it would be supported/adopted.