Understanding the code path for admin.vm.device.pci.Attach

For all the VM types, libvirt config is handled the same: it’s generated and sent to libvirt daemon at VM start time, and remain there until VM is removed. But it’s updated only when VM is running, if VM is halted it may be not there at all, or be outdated.
You can get it with virsh -c xen dumpxml <vmname> (after VM was started)

As for the PCI devices, those assigned before VM start, are included in the libvirt template directly: https://github.com/QubesOS/qubes-core-admin/blob/master/templates/libvirt/xen.xml#L157

The device-pre-attach:pci handler (https://github.com/QubesOS/qubes-core-admin/blob/master/qubes/ext/pci.py) is relevant only for dynamic attach (when the VM is already running).