How do fragment shader invocations subgroups map onto triangles? Should I expect that every invocation/fragment within a subgroup, when using something like subgroupBroadcast(), will belong to the same triangle?
Fragment shader subgroups are not required to be restricted to a single primitive (and such a restriction would negatively impact performance). So subgroup broadcasting can cross primitive boundaries.
Note that the most recent version of the Vulkan standard states that invocations in the same quad scopes are required to be within the same primitive scope.