Thanks for the explanation and background details!
So far, I was using scriptrunner to play around with the Nitrokey HSM.
I’ve just tried scsh3gui. The first thing I noticed is that the UI is super tiny on my 2880x1800 laptop display. It does not scale well under Wayland. Other Java GUI applications (such as Android Studio or IntelliJ) scale properly and automatically.
You can use the explore/explore.js script
When I run this via File -> Run Script, it fails with:
>load("/home/thore/Downloads/sc-hsm-starterkit/sc-hsm-workspace/sc-hsm-sdk-scripts/explorer/explore.js");
Exception selecting EF_DIR. Assuming no EF_DIR...
Function (CARD_COMM_ERROR/27904) - "SELECT failed with SW1/SW2 = 6D00 "Checking error: Invalid instruction (0)"" in /home/thore/Downloads/scsh-3.18.61/tools/p15classes.js#1827
at /home/thore/Downloads/scsh-3.18.61/tools/p15classes.js#1827
at /home/thore/Downloads/scsh-3.18.61/tools/CardOutlineFactory2.0.js#106
at /home/thore/Downloads/sc-hsm-starterkit/sc-hsm-workspace/sc-hsm-sdk-scripts/explorer/explore.js#270
I get a similar error when accessing File -> Key Manager:
>load("keymanager/keymanager.js");
GPError: Card (CARD_INVALID_SW/27904) - "Unexpected SW1/SW2=6D00 (Checking error: Invalid instruction (0)) received" in /home/thore/Downloads/scsh-3.18.61/scsh/sc-hsm/SmartCardHSM.js#1642
at /home/thore/Downloads/scsh-3.18.61/scsh/sc-hsm/SmartCardHSM.js#1642
at /home/thore/Downloads/scsh-3.18.61/scsh/sc-hsm/SmartCardHSM.js#100
at /home/thore/Downloads/scsh-3.18.61/keymanager/keymanager.js#233
at /home/thore/Downloads/scsh-3.18.61/keymanager/keymanager.js#41
at /home/thore/Downloads/scsh-3.18.61/keymanager/keymanager.js#3347
When I eject and reinsert the Nitrokey HSM, the Automatically access card with Key Manager? dialog appears. When I confirm this with Yes, scsh3gui loads the tree structure view. 
In the tree view, I can see the keys that I generated with pkcs11-tool, and their CVC-REQs. I can also right click and Dump Certificate to the the pretty-print of the CVC-REQ ASN.1.
Getting the CVC-REQ programmatically
The fact that the CVC-REQ is stored in place of the cert was the info that I was missing. Previously, I was searching for ks.getCertificateRequest-like functions.
I managed to get the CVC-REQ from a script and serialise it for external storage:
var bin = ks.getCertificate(label);
var req = new CVC(bin);
print(req.isCertificateRequest());
print(JSON.stringify(req.toJSON()));
CVC-REQ not stored by default
If I run ./scriptrunner key-attestation.js and then inspect the HSM with the scsh3gui, the generated key does NOT have any CVC-REQ:

In this screenshot, attest-example was generated via ./scriptrunner key-attestation.js and aaaa-test was generated via pkcs11-tool.
It’s surprising to see that the CVC-REQ is not there, given that the script printed it. I would suggest that you add a call to
ks.storeEndEntityCertificate(label, req);
to the key-attestation.js sample, or otherwise mention this fact. To make it clear that the CVC-REQ needs to be explicitly stored. This seems important, since otherwise the CVC-REQ is forever lost, no?
Also, this apparently means that the OpenSC PKCS#11 provider stores the CVC-REQ automatically? Or how did that CVC-REQ get stored for the key generated by pkcs11-tool?