That’s likely just constant folding in the specific case. If you add a Wrapper argument to f, the inference fails as expected:
julia> function f(b::Wrapper)
a = Wrapper(Int)
promote_type(a.value, b.value)
end
f (generic function with 2 methods)
julia> Base.promote_op(f, typeof(Wrapper(Float64)))
Type{S} where S