I don’t think you are thinking about how capabilities work correctly. There isn’t a true inheritance, it’s more like copying into new post types. Changing the parent capabilities does not affect the child capabilities at all. They are completely unrelated once they are copied over to the new CPT.
Each post type has an array of capabilities assigned to it where the user must have those capabilities in various contexts to work with the post type. map_meta_cap()
is responsible for building this array. If you do not provide a capability_type argument, it defaults to ‘post’ so what ever a user can do with posts, they can do with your CPT as well. But you can assign a different type, say ‘mycpt’. Resulting in capabilities like ‘edit_mycpts’. Then you can fine tune which users can do things to your CPT completely independent of what they can do with posts. But you must assign these custom capabilities to users, they do not have them automatically just because the had ‘edit_posts’.
map_meta_cap()
builds the various capabilities based on the capability_type argument. It then assigns an array of those capabilities to the CPT. It may be a copy of the ones for ‘post’, or a custom set like ‘edit_mycpts’, ‘read_mycpts’ etc., depending on what you provided for capability_type.
The value of the map_meta_cap registration argument determines if only a few basic capabilities are generated, or the full primitive set.
Now if you filter ‘map_meta_cap’, your callback is passed this array destined for the CPT. You can add to it with completely new capabilities, you can remove a particular capability you do not want, or even trash the whole thing and generate your own custom set.
You probably don’t want to do $caps = 'edit_posts';
. For one thing, you need to return an associative array, but also this essentially removes all the other capabilities, so people will be able to edit your CPT, but they cannot read it or do anything requiring a different capability. Typically, you will either push new capabilities onto the array or unset specific elements. It’s unusual to assign a completely new array to the returned value, especially an array of one element like you are doing. Assigning a new array can also be done with the ‘capabilities’ argument when registering the CPT, the ‘map_meta_cap’ filter is not needed to do that.
I hope this all makes more sense to you now.