[jan's answer](http://android.stackexchange.com/a/120417/44325) already addresses how to change the notification policy for such (disabled "show notifications") apps.

As for why and when (or essentially, in what condition it applies), your guess of system apps is on the right track.

To be exact, as [Sergey has explained in the comment](http://android.stackexchange.com/questions/120169/show-notifications-is-greyed-out-for-some-apps-whats-causing-it-and-how-do-i/120420?noredirect=1#comment148945_120420), only packages that are signed with the `platform` key (from vendor/manufacturer, e.g. [AOSP](https://github.com/android/platform_build/tree/master/target/product/security)) will have this privilege. These packages are [part of the core platform](https://source.android.com/devices/tech/ota/sign_builds.html#certificates-keys). Other preinstalled apps (including apps with some special privileges, which are signed with the `shared` or `media` key) and "system" apps (apps which are put on `/system/app` folder and granted access right) are not counted.

Summary: as of the latest version (Android 5.1.1 Lollipop), the checkbox is disabled if:

1. The app is signed with `platform` key (part of the core platform), or
2. The app is not installed on the current user (in multi-user case)

---

From [InstalledAppDetails.java](https://android.googlesource.com/platform/packages/apps/Settings/+/master/src/com/android/settings/applications/InstalledAppDetails.java) (this is what "App Info" displays),

    private CompoundButton mNotificationSwitch; // this is the "show notifications" checkbox

    ...

    private void initNotificationButton() {

        ...

        if (Utils.isSystemPackage(mPm, mPackageInfo)) {
            mNotificationSwitch.setEnabled(false);
        } else if ((mPackageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
            // App is not installed on the current user
            mNotificationSwitch.setEnabled(false);
        } else {
            mNotificationSwitch.setEnabled(true);
            mNotificationSwitch.setOnCheckedChangeListener(this);
        }
    }

**Note**: `Utils.isSystemPackage()` returns `true` only for packages signed with the `platform` key.