Bruce,
It's an honor to get help from the author himself!

I'm starting to understand why they have this:

do_configure_prepend() {
     cp "${S}/arch/${ARCH}/configs/${KBUILD_DEFCONFIG}" "${B}/.config" || bbfatal "CONFIG ${KBUILD_DEFCONFIG} NOT FOUND"
}

Since do_kernel_configme() creates the .config file in https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/meta/classes/kernel-yocto.bbclass?h=dunfell#n399
(I can't figure out why it fails to merge in our defconfig)

Then the ${WORKDIR}/defconfig is not used by kernel_do_configure() https://git.yoctoproject.org/cgit/cgit.cgi/poky/tree/meta/classes/kernel.bbclass#n595
So they do the copy of defconfig in do_configure_prepend(). 

Anyway,  do_kernel_configme() has already been run hence no CONFIG_LOCALVERSION is written to .config


I could just do this:
do_configure_prepend() {
     cp "${S}/arch/${ARCH}/configs/${KBUILD_DEFCONFIG}" "${B}/.config" || bbfatal "CONFIG ${KBUILD_DEFCONFIG} NOT FOUND"
     echo "CONFIG_LOCALVERSION=\"${LINUX_VERSION_EXTENSION}\"" >> "${B}/.config"
}

 

BUT
Your hint make me notice that they did: KCONFIG_MODE="--allnoconfig" which breaks the config merging.
After changing it to alldefconfig and removing do_configure_prepend it all works!

Thank you!