Honestly, especially in the context of diverse operating systems like Hurd, Mac OS/Darwin and Linux:
You'll have to trust the operating system to tell you what the operating system is. Your idea that XNU is the kernel, a sensibly separable part of Darwin, might be nice, and historically pleasant, but I don't see why Darwin (which is the operating system you're interacting with) would implement any function that tells you about that "personal" distinction.
And that's true for other OSes as well.
Good discussion point is Hurd there: You can't really speak of the "Hurd kernel", right, because that's not how microkernel servers responding to system requests would call themselves, but "Mach", hm does that cut it at describing it?
So, either you just say "hm, 'kernel' means different things for different operating systems", which I find fairly self-evident, considering the ranges of monolithic to nearly-micro-kernel OSes you list, and just stick with the reality of it, and use what uname
tells you.
Or, you start keeping your own table of mappings ("Darwin means a XNU kernel runs", "Linux means a Linux kernel is running, unless this other test tells us we're running in a Linux emulation on some *BSD", "Linux.*UML means that we're in a user mode Linux kernel, probably running on a Linux kernel?",…) and detectors.
Frankly, I'd go with the former. Since different kernels have nothing in common that you could use to abstract them without knowing the rest of the OS, "give me a string that describes the kernel" seems relatively useless to me: on a Debian kFreeBSD you'd get "FreeBSD" (I guess!), but then when you try to do anything that uses FreeBSD operating system interfaces you'd be meeting problems. Generally, on the weak copyleft kernels, chances are pretty high asking the kernel would return something like "airfrierKernel", which might be a slightly modified NetBSD, or a FreeBSD, or maybe it's a Minix fork? Or is it actually a bit of an overblown Zephyr? Or a system-licensed QNX procnto
? There's very little useful information in knowing the kernel name in itself; it's a very human, very non-actionable thing :)