With sandboxing of the bubblewrap or firejail flavor you have one externally applied ruleset to a tree of processes. This ruleset must be lax because it is the union of all the permissions the processes may need at any time and on any execution path. This is bad because it makes your sandbox more permissive than necessary and specific points in time for specific processes
pledge on the other hand allows a process to gradually drop privileges as it goes down different code paths. E.g. it could initially retain permissions to open files and enumerate directories because it has an option to do things recursively. But after checking arguments and no recursive option was requested it just opens a fixed list of files and then drops those caps. But it's a fancy tool (like ripgrep) that might spawn helper programs to parse the content and those may still have to open files on their own. So just because it locally dropped its own capability to open files (but retained the cap to spawn processes) doesn't mean its child processes should inherit that restriction, they can lock themselves down. It can still choose to impose separate restrictions on child processes externally, but that's orthogonal to the self-restrictions.
This makes things more composable and allows for tighter sandboxing after program init.
Even with self-sandboxing filters that won't be inherited can be made more tight than the inherited ones. Maybe you could fork a spawn helper at program startup before installing the filters to emulate this behavior, but that makes IPC more complicated.
pledge on the other hand allows a process to gradually drop privileges as it goes down different code paths. E.g. it could initially retain permissions to open files and enumerate directories because it has an option to do things recursively. But after checking arguments and no recursive option was requested it just opens a fixed list of files and then drops those caps. But it's a fancy tool (like ripgrep) that might spawn helper programs to parse the content and those may still have to open files on their own. So just because it locally dropped its own capability to open files (but retained the cap to spawn processes) doesn't mean its child processes should inherit that restriction, they can lock themselves down. It can still choose to impose separate restrictions on child processes externally, but that's orthogonal to the self-restrictions.
This makes things more composable and allows for tighter sandboxing after program init.