That’s a surprise. AFAIK Xcode isn’t capable of correctly exporting a Developer ID-signed NE sysex
We generate our xcode project file using xcodegen, which lets us modify the entitlements (adding the system extension suffix) just before building using environment variables. Then, during the build, we also set the two different provisioning profiles using environment variables. Source available.
If it works, this bug isn’t as simple as we’re suspecting, and we should talk more.
Alas, I was not able to reproduce the issue exactly as described in a fresh VM. I'll copy-paste from the feedback assistant comment, where I attached three versions, and the sysdiagnose bundle.
There was no XPC connection invalidation when upgrading from the attached Version 2 to Version 3. Version 3 being just a few hours old. However, when upgrading from Version 2 to Version 3 on my personal macbook running macos 15.3.1, the issue occurred. In both cases, the VPN was stopped before the upgrade. Interestingly, when upgrading from Version 2 to Version 3 for a second time on the same macbook, the issue does not occur, also leading me to believe it has something to do with the ingesting of the notarization ticket.
I initially tested an upgrade from Version 1 to Version 2 on another fresh VM. What I didn't realise is that the VPN configuration applied by Version 1 had a different slug to that expected by Version 2. So, when upgrading, the VPN was not stopped by the .pkg preinstall scutil, and so Version 2 replaced the network extension whilst the VPN was running. Following this, the XPC connection was consistently invalidated between the Version 2 app, and the version 2 NE. Attached is a sysdiagnose (with NE debug logs enabled) captured right after the issue occurred.
But to sum up:
On an end-user device, an upgrade from Version 2 to 3 causes the issue. The network extension is not replaced whilst the VPN is running. This tracks with what our users are reporting. The issue only appears to occur when upgrading to Version 3 for the first time.
On a fresh VM, an upgrade from 2 to 3 does not cause the issue. I could not reproduce it in 5+ attempts.
On a fresh VM, an upgrade from 1 to 3 does cause the issue, as the network extension is replaced whilst the VPN is running. I could reproduce this consistently, but only on a fresh VM. Like on the end-user device, the issue only occurs in the VM when upgrading to Version 3 for the first time, and only if the VPN is running when the NE replacement happens.