FWIW, this was an explicit design decision made when designing Codable: an Optional property indicates that a specific property need not be present in the encoded data — whether it is not present because the key was missing or the value was null doesn't factor into the default behavior.
You can override this behavior if need be by choosing decode(_:forKey:) over decodeIfPresent(_:forKey:) if you need to disambiguate, but the common case rarely cares and a more permissive default helps more code use a synthesized init(from:).
As you note in your examples, too, default values for variables are actually never taken into account when synthesizing init(from:), and this was purposeful too: a default value applied to a variable is not necessarily a reliable indicator of explicit permission to ignore encoded data. For example, many properties may have sensible defaults outside of decoding data, and may developers might prefer to assign default values to those properties (e.g. to benefit from getting synthesized initializers), but those values might be different from what's expected during decoding. null values may be significant, even if the default is not nil.
So code synthesis is conservative and considers the data you're decoding from to be the source of truth, and if you'd like to customize the behavior, it's absolutely possible to do. (Synthesis can't write any code that you couldn't have written yourself.)
In any case, changing behavior here is likely to be massively behavior-breaking. This is something that we'd need to be extremely cautious about, because this would be behavior-breaking in code that developers did not write themselves.