how much wiggle room is there?
https://en.bitcoin.it/wiki/NLockTime11-block median time past (the median timestamp of the 11 blocks preceding the block in which the transaction is mined)
that doesn't sound like a good thing.
1. The time always moves forward in the long term. It has to be strictly greater than MTP, which means, that you cannot start from the Genesis Block in 2009, and get a valid block in 2005.
2. For miners, it is profitable to move the time forward. Especially in testnet, where by moving it 20 minutes to the future, you can work with the minimal difficulty. But also in mainnet, if you have more time between blocks, then the difficulty is decreased.
3. Blocks are accepted up to two hours in the future. However, it can be changed locally in the node settings. And as always: you can work on future blocks, but if you work very far in the future (more than two hours), then there is a huge risk of getting your blocks reorged (because they are rejected by other nodes, until their clock will get there, and your blocks will be in this two hours window).
4. If you have some decentralized clock, then there is no one source of truth. Actually, we have three, which means, that having some "wiggle room" is a good thing. As Satoshi wrote in version 0.1.0:
// "Never go to sea with two chronometers; take one or three."
// Our three chronometers are:
// - System clock
// - Median of other server's clocks
// - NTP servers
//
// note: NTP isn't implemented yet, so until then we just use the median
// of other nodes clocks to correct ours.
Edit:
does that seem like an ideal solution or does that seem like shoehorning two totally separate ways of locking a transaction into the same field?
It is far from perfect, but it was better to have any format, than to have no format at all. And also, it shows that Satoshi tried to compress things, as much as he could. For that reason, we have VarInt. For the same reason, we have compressed 256-bit target into 32-bit value. If Satoshi would know about compressed public keys, then we could also have them from the start. But because he didn't know about it, he applied SHA-256 and RIPEMD-160, to get 160-bit addresses, because 256-bit and 512-bit ones were too big.
So, is it possible to have two separate locktimes, one for block numbers, and one for timestamps? Yes, of course. But: Satoshi wanted to make it small. And I guess it could be even smaller, like "skip the last four bytes, if there is no locktime", but we cannot have that now, because locktime is signed (even if you use SIGHASH_NONE | SIGHASH_ANYONECANPAY).
that way you get alot more use out nlocktime than 9500 years. and it works past the year 2106...
1. Do you need bigger timespan than 136 years, with accuracy up to one second?
2. It is possible to re-activate locktime in the future, by treating it like (time64 % 2^32). It is a soft-fork.
3. It is more likely, that the time in the block header will be also expressed as something like (time64 % 2^32) in the future. Because if you switch from 80-byte block headers into for example 84-byte block headers, then it will be ASIC-incompatible.
having those 4 bytes perform separate things with different meanings is just an example of poor design
1. You can separate them in your implementation, and add back-and-forth conversion, without touching any consensus rules. It would be a no-fork, not even a soft-fork, if you want to change it locally.
2. It is not a "poor design". It is just some kind of compression. And also tell me: if block numbers wouldn't be there, then would you really need to put locktime between 1970 and 1985, with accuracy to a single second?