"Linux has an elegant and beautiful design when it comes to threads" - unifying threads and processes does simplify some things, but it makes it extremely hard to change a process-level property such as the effective user/group id of a process: https://ewontfix.com/17/.
I'm surprised no solution in the kernel has ever been done.
But that said, I suspect the big reason is that setting uid and gid with threads is going to be messy no way how you slice it. Making setuid and setgid work per-thread, and then having programs coordinate a privileged loss over all the threads is easier to do since the programmer knows where in their code is an appropriate place to do the privileged loss, rather then having one thread trigger it to happen regardless of what the other threads are currently doing. But of course, there's always the chance a thread doesn't drop it's privileges, and since libc has to emulate the POSIX API anyway it just makes things a lot messier since it has to force all the threads to call the setuid or setgid function without having them call it in code.
But of course, I think it's notable that if you can (And in most cases, you probably can) you should be dropping privileges well before you start threads and the body of your program, and if you do that then this doesn't even become an issue in the first place. I would suspect that this is part of why this hasn't been added to the kernel - the user-space solutions are sufficient simply because most programs don't actually ever call these functions after they've already setup threads.
Some language runtimes create threads before the application main() function is executed. Even if Linux has to retain bug-for-bug ABI compatibility there is valid reason to only provide fucked up the setid() syscalls.
The problem is even worse than it looks at first glance because setid() can fail per thread and there is no sane way to recover from this in userspace. Atomic syscalls are the only sane API for this and Linux is lacking those.
> I'm surprised no solution in the kernel has ever been done.
It has, just not the one the linked article is whining about. "Process level" capability management in modern security architectures is basically never based on uid/gid. The kernel is filled with tools (too many, IMHO) for doing this. Looping over your process to try to change the IDs is the Wrong Thing, basically.