"The arguments represented by arg0,... are pointers to null-terminated character strings. These strings shall constitute the argument list available to the new process image. The list is terminated by a null pointer. The argument arg0 should point to a filename string that is associated with the process being started by one of the exec functions."
"The argument argv is an array of character pointers to null-terminated strings. The application shall ensure that the last member of this array is a null pointer. These strings shall constitute the argument list available to the new process image. The value in argv[0] should point to a filename string that is associated with the process being started by one of the exec functions."
[1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/e...
I don't agree with your reading that argv being non-NULL is a "should."
The POSIX Specification does not say "The value in argv[0] should exist" it says "The value in argv[0] should point to a filename string..."
The value existing is a foundational assumption in the specification. It is therefore required.
(This is consistent with the fact that it's explicitly required that argv[argc] == NULL, which necessarily means that argv != NULL. Consider this: https://pastebin.com/1gieMqEd If argv is NULL, then pointer arithmetic on it and dereferencing it is undefined behavior, and cannot possibly conform to the guarantee.)
Edit: delete commentary