small and hard to understand
Adding a single "if" in some already working implementation is much easier, than introducing some completely separate field in your data structure, update it in all serialization methods, not forget about constructors and destructors (if any), and so on.
is that going to be a bug or what are people going to do?
Satoshi did the simplest thing he could. He just called some functions from the standard library or WinAPI, without thinking about "2106 year problem" or "2038 year problem". In the same way, people use "int" as their data type, without thinking if it is "int32", "int64", or maybe "uint32". In that case, Satoshi was aware enough to use unsigned integers, and to specify the size of those fields in most cases, but he was not aware enough, to do the same with time-based data types, like "time_t".
satoshi must have been a linux hacker
Definitely not. He used Windows, and there are some traces, leading to the conclusion, that he was running Windows on a real hardware, without any virtualization (because in that case, it would affect his mining performance, and some other things). Even if you assume, that he privately used some kind of Linux, then definitely he had at least one physical machine, with Japanese version of Windows XP, without any VirtualBox, and used that for development.
it requires all these possible fixes you mentioned
At that time, people didn't think about soft-forks and hard-forks, as we do it now. There were old times, when people thought, that you can upgrade the whole Script by using OP_VER (which is now disabled). In the same way, people thought, that transaction versions and block versions can be used to fully replace everything. But now, we know, that it is not the case.
what a disaster of an opcode
There are two different things, which should be clearly separated:
1. nLockTime at the end of transaction
2. OP_CHECKLOCKTIMEVERIFY and OP_CHECKSEQUENCEVERIFY inside Script
Also note, that even if we run out of those, and if all locktime values could be used (so nLockTime will become de-facto transaction nonce), then still, adding new opcodes is possible. Also: reusing existing ones is another option. Which means, that after block 500,000,000, and after year 2106, when every locktime value will be valid, we can implement completely different locktime rules from scratch, without any limits.