Yeah, definitely looks like a bug to me:
julia> nt(::Wrapper{S,T}) where {S,T} = NamedTuple{S,T}
nt (generic function with 1 method)
julia> nt(X)
NamedTuple{(:a, :b, :c, :d), Tuple{Float64, Float64, Int64, SVector{3, Float64}}}
julia> nt(X) === typeof(X.x)
true
julia> isbits(X) # false
false
julia> isbits(X.x) # true
true
The wrapper seems to be matching the NamedTuple
exactly.