So I figured out how to make a double sided transparent surface shader, despite all sane knowledge on the topic informing me this should not be possible.
However, my process of dealing with unity’s meta-shader syntax, is to guess randomly until it does what I want. Because that is often easier than trying to develop any meaningful understanding from the 30% complete documentation.
Note there are no pass blocks, since "pass"es are not be compatible with surface shaders, but this does multiple passes despite not using “pass”.
I have no idea what including two cgprograms in the same subshader is even doing. My guess is its abusing unintended side-effects of unity’s pragmas.
Flaw - overlapping more than one closed surface, within the same queue, will cause z-artefacts
The only thing you’re doing wrong here is having two sets of tags. the second one will be ignored as only the first set of tags within a SubShader will be used. A shader can’t have more than one Queue, or one RenderType. Instead the order of the passes (including those generated by multiple Surface Shaders) determine the order they’re rendered in.*
If multiple objects use the same material, Unity may choose to render multiple objects using the first pass, then multiple objects with the second pass rather than running both for each object before rendering the next. There were also some bugs with this that can cause passes to render out of order in this situation, though they might be fixed now.
Having multiple Surface Shaders in a single SubShader does work though, and is a common way to do double sided transparent shaders. Each Surface Shader individually generates a set of passes, specifically ForwardBase, ForwardAdd, and Meta for anything with alpha in the #pragma surface line. Without alpha they’ll also generate a Deferred pass, and can optionally generate a ShadowCaster pass with addshadow. This is all fine.
However the “z-artifacts” you’re seeing are some parts of the transparent object disappear when you’re expecting to be able to see them. Unfortunately what you’re seeing is the expected result when using ZWrite On with any transparent surface. Having two passes just makes it more obvious, but it’ll happen with a single transparent pass on a complex enough mesh.
This is because correct, fast, and efficient sorting of real time transparent surfaces is an unsolved problem.